Bluetooth Display - Part 2

Welcome to the second part of the Bluetooth Display series.

Whoever displays the display of the first part already finished, it will have been noted that you can enter any text on our display very conveniently, but unfortunately only one text can be entered and also this must be re-entered again and again if the display is disconnected from the current. This is a bit tedious in the long run. Therefore, in today's part, we will provide for the possibility to store fixed texts in the internal EEPROM and retrieve them if necessary. 

For this purpose, we expand our serial menu with the following menu items:

  • • S - Read ALL EEPROM Banks
  • • E - Erase ALL EEPROM Banks
  • • W - Write sel. EEPROM Bank
  • • R - Read sel. EEPROM Bank
  • • P - Print EEPROM Bank on Display


For this extension, upload the following code to our Arduino UNO:

 

#include <Spi.H>
#include <Wire.H>
#include <SoftwareSerial.H>
#include <Eeprom.H>
#include <LiquidCrystal.H>
#include <Avr/Sleep.H>


#define MaxInputBufferSize 20 maximum 255 characters to adapt to vlcdr
#define EEpromSize 990

#define rLcdChr 20
#define LcdRows 4
#define interval 1000

EEprom Memory CellAddresses for Configuration
#define EEFadeSeconds  993
#define EEPINA 996
#define EEPINC 997
#define EEPINDD 998

SoftwareSerial mySerial(7, 6); RX, TX

LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal Lcd(8, 13, 12, 11, 10, 9);

variables
Byte DisplayBankContent = 0;

Serial Input Handling
Char TBuffer;
Char Cbuffer[MaxInputBufferSize + 1];     USB Code Input Buffer
String Sbuffer = "";                      USB String Input Buffer
Int Value;                                USB Nummeric Input Buffer
Byte Ccount = 0;                          Number received Chars
Byte Inptype = 0;
Boolean StrInput = False;
Boolean NumberInput = False;
Boolean DataInput = False;
Boolean EnterInput = False;
Byte MenueSelection = 0;

Byte SelectedMsg = 0;

Give Debug Information over serial Interface
Boolean DebugMode = False;
Boolean EchoMode = True;

Eeprom
Int eeaddress;                 EEPROM Address Pointer
Byte EEPromBanks = 0;          Used for Calculating the EEPROM Banks
SerMnueControl
Byte MnuState = 0;            Maximum menu depth 255 icl Sub
Byte Selectedbank = 0;

Real Time Clock
Long previousMillis = 0;       will store last time was measured
Long previousMillisB = 0;       will store last time was measured

Display Management
Boolean DisplayLock = False;
Boolean Directprint = False;
Byte DirectprintROW = 0;
Byte DirectprintLine = 0;
Boolean RefreshDisplay = False;
Byte FRMCheck = 0; Used fpr Writing Operations to eeprom so save hosts cycles

Void Setup()
{   EEPromBanks = EEpromSize / ((rLcdChr) * LcdRows);   Lcd.Begin(rLcdChr, LcdRows);   Lcd.Clear();   Lcd.setCursor(0, 0);   Lcd.Print(" Bluetooth ");   Lcd.setCursor(0, 1);   Lcd.Print(" Display ");   mySerial.Begin(9600);   Lcd.setCursor(0, 0);   mySerial.Flush();
}



// ###################################################################################################### //

Void Loop()

{   SerialcommandProcessor();   Display processor();

}

// ###################################################################################################### //


Void TextHeader(Byte rowm)
{   mySerial.println("Text for Bank" + String( Selectedbank) + " ROW " + String (rowm) + ":");
}

Void SerialcommandProcessor()
{   Int A;   Inptype = 0;   Inptype = SerInputHandler();   0 no return   1 number   2 String   3 Data   If ((Inptype > 0) & (!Directprint))   {     MenueSelection = 0;     If ((MnuState < 2) && (Inptype == 2)) {       Sbuffer.Touppercase();  For Easy Entering Commands     }     If ((Sbuffer == "S") && (MnuState == 0) && (Inptype == 2))       {       MenueSelection = 3;     }     Erasing ALL EEprom Content     If ((Sbuffer == "E") && (MnuState == 0) && (Inptype == 2))       {       MenueSelection = 4;     }     If ((Sbuffer == "YES") && (MnuState == 1) && (Inptype == 2))      {       MenueSelection = 5;     }     If ((Sbuffer != "YES") && (MnuState == 1) && (Inptype == 2))     {       MenueSelection = 6;     }     //Edit  Selected Content     if ((Sbuffer == "W") && (MnuState == 0) && (Inptype == 2))       {       MenueSelection = 7;     }     if ((MnuState == 2) && (value  < EEPromBanks) && (Inptype == 1)) {       MenueSelection = 8;     }     if (MnuState == 3)                                               {       MenueSelection = 9;     }     if (MnuState == 4)                                               {       MenueSelection = 10;     }     //Display  Selected Content     if ((Sbuffer == "P") && (MnuState == 0) && (Inptype == 2))       {       MenueSelection = 11;     }     if ((MnuState == 5) && (Inptype == 1))                           {       MenueSelection = 12;     }     if ((MnuState == 6) && (Inptype == 1))                           {       MenueSelection = 14;     }     if ((Sbuffer == "D") && (MnuState == 0) && (Inptype == 2))       {       MenueSelection = 15;     }     if ((Sbuffer == "Z") && (MnuState == 0) && (Inptype == 2))       {       MenueSelection = 16;     }     if (MnuState == 9)                                               {       MenueSelection = 20;     }     if (MnuState == 10)                                              {       MenueSelection = 21;     }     switch (MenueSelection)     {       case 1:         {           break;         }       case 2:         {           break;         }       case 3:         {           mySerial.println("Read EEEPROM Content:" );           mySerial.flush();           for (int a = 0; a < EEPromBanks; a++)           {             mySerial.println("EEPROM Memory Bank: " + String(a) );             mySerial.flush();             for (int b = 1; b <= LcdRows; b++)             {               mySerial.print("Row " + String(b) + ": ");               mySerial.flush();               for (int c = 0; c < rLcdChr; c++)               {                 eeaddress = 0;                 eeaddress = (a * (rLcdChr) * LcdRows) + ((rLcdChr) * b) + c;                 value = EEPROM.read(eeaddress);                 mySerial.print(char(value));                 mySerial.flush();               }               mySerial.println(" ");               mySerial.flush();             }           }           Sbuffer = "";           mySerial.println("No more EEPROM Banks available.");           mySerial.flush();           break;         }       case 4:         {           value = 0;           mySerial.print("Erasing EEPROM ");           mySerial.println("YES/NO:");           mySerial.flush();           MnuState = 1;           Sbuffer = "";           break;         }       case 5:         {           value = 0;           mySerial.print("Erasing EEPROM ");           mySerial.println("Stand by.");           mySerial.flush();           for (int a = 0; a < EEPromBanks; a++)           {             //Memory Bank a             mySerial.println("Clear Bank: " + String(a));             for (int b = 1; b <= LcdRows; b++)             {               for (int c = 0; c < rLcdChr; c++)               {                 eeaddress = 0;                 eeaddress = (a * (rLcdChr) * LcdRows) + ((rLcdChr ) * b) + c;                 FRMCheck = EEPROM.read(eeaddress);                 if (FRMCheck > 0)                 {                   EEPROM.write(eeaddress, 00); // Formatierung                   mySerial.print(".");                   value++;                   delay(30);                   mySerial.flush();                 }               }             }             mySerial.println("");             mySerial.flush();           }           mySerial.println("");           mySerial.println("Finished. " + String(value) + " Bytes cleared");           mySerial.println("");           mySerial.flush();           Sbuffer = "";           MnuState = 0;           break;         }       case 6:         {           value = 0;           Sbuffer = "";           MnuState = 0;           mySerial.println("OP abort.");           mySerial.flush();           break;         }       case 7:         {           mySerial.println("EEPPROM Bank Number (0-" + String(EEPromBanks - 1) + "):");           mySerial.flush();           MnuState = 2;           value = 0;           Sbuffer = "";           break;         }       case 8:         {           Selectedbank = value;           TextHeader(1);           MnuState = 3;           Sbuffer = "";           value = 0;           break;         }       case 9:         {           WriteEEPROM(Selectedbank, 1);           TextHeader(2);           value = 0;           MnuState = 4;           Sbuffer = "";           break;         }       case 10:         {           WriteEEPROM(Selectedbank, 2);           value = 0;           MnuState = 0;           Sbuffer = "";           TextHeader(3);           mySerial.flush();           value = 0;           MnuState = 9;           Sbuffer = "";           break;         }       case 11:         {           value = 0;           mySerial.println("EEPPROM Bank Number (0-" + String(EEPromBanks - 1) + "):");           MnuState = 5;           Sbuffer = "";           mySerial.flush();           break;         }       case 12:         {           SelectedMsg = value;           DisplayBank(value);           break;         }       case 13:         {           value = 0;           mySerial.println("EEPPROM Bank Number (0-" + String(EEPromBanks - 1) + "):");           MnuState = 6;           Sbuffer = "";           mySerial.flush();           break;         }       case 14:         {           a = value;           if ( a < EEPromBanks)           {             mySerial.println("Memory Bank: " + String(a) );             mySerial.flush();             for (int b = 1; b <= LcdRows; b++)             {               mySerial.print("Row " + String(b) + ": ");               mySerial.flush();               for (int c = 0; c < rLcdChr; c++)               {                 eeaddress = 0;                 eeaddress = (a * (rLcdChr) * LcdRows) + ((rLcdChr) * b) + c;                 value = EEPROM.read(eeaddress);                 mySerial.print(char(value));                 mySerial.flush();               }               mySerial.println(" ");               mySerial.flush();             }           } else           {             mySerial.println("Value out of Range.");           }           value = 0;           Sbuffer = "";           MnuState = 0;           break;         }       case 15:         {           // Direct pPrint to Display           Directprint = true;           mySerial.println ("Directprint ON.");           if (Directprint)           {             DirectprintROW = 0;             DirectprintLine = 0;             lcd.clear();             lcd.cursor();             lcd.blink();           }           value = 0;           Sbuffer = "";           MnuState = 0;           break;         }       case 16:         {           value = 0;           Sbuffer = "";           MnuState = 0;           break;         }       case 20:         {           WriteEEPROM(Selectedbank, 3);           value = 0;           MnuState = 0;           Sbuffer = "";           TextHeader(4);           mySerial.flush();           value = 0;           MnuState = 10;           Sbuffer = "";           break;         }       case 21:         {           WriteEEPROM(Selectedbank, 4);           value = 0;           MnuState = 0;           Sbuffer = "";           break;         }       default:         {           mySerial.println("-------Smart Bluetooth Display 1.0------");           mySerial.println("S - Read ALL EEPROM Banks");           mySerial.println("E - Erase ALL EEPROM Banks");           mySerial.println("W - Write sel. EEPROM Bank");           mySerial.println("R - Read sel. EEPROM Bank");           mySerial.println("P - Print EEPROM Bank on Display");           mySerial.println("----------------------------------------");           mySerial.println("D - Direct Print");           mySerial.println("----------------------------------------");           mySerial.println("Type Cmd and press Enter");           mySerial.flush();           MnuState = 0;           value = 0;           Sbuffer = "";         }     }   } // Eingabe erkannt
}

void WriteEEPROM(byte FBank, byte FRow)
{   byte Writecounter;   Writecounter = 0;   mySerial.print("Saving ");   for (int c = 0; c < rLcdChr; c++)   {     eeaddress = 0;     eeaddress = (FBank * (rLcdChr) * LcdRows) + ((rLcdChr) * FRow) + c;     value = EEPROM.read(eeaddress);     if (Sbuffer[c] != value)     {       EEPROM.write(eeaddress, Sbuffer[c]);       mySerial.print(".");       Writecounter++;     }   }   mySerial.println(" " + String (Writecounter) + " Bytes written.");

}


void ClearCBuffer ()

{   for (byte a = 0; MaxInputBufferSize - 1; a++)     Cbuffer[a] = 0;
}


byte SerInputHandler()

{   byte result = 0;   int c;   int d;   int a;   int b;   result = 0;   if (CheckforserialEvent())   {     if ((NumberInput) and not (DataInput) and not (StrInput))    //Numbers only     {       Sbuffer = "";       value = 0;       StrInput = false;       NumberInput = false;       DataInput = false;       EnterInput = false;       a = 0;       b = 0;       c = 0;       d = 0;       Sbuffer = Cbuffer; // Zahl wird AUCH ! in SBUFFER übernommen, falls benötigt.       if (Ccount == 1) {         value  = Cbuffer[0] - 48 ;       }       if (Ccount == 2) {         a = Cbuffer[0] - 48 ;         a = a * 10;         b = Cbuffer[1] - 48 ;         value = a + b;       }       if (Ccount == 3) {         a = Cbuffer[0] - 48 ;         a = a * 100;         b = Cbuffer[1] - 48 ;         b = b * 10;         c = Cbuffer[2] - 48 ;         value = a + b + c;       }       if (Ccount == 4) {         a = Cbuffer[0] - 48 ;         a = a * 1000;         b = Cbuffer[1] - 48 ;         b = b * 100;         c = Cbuffer[2] - 48 ;         c = c * 10;         d = Cbuffer[3] - 48 ;         value = a + b + c + d;       }       if (Ccount >= 5)       {         Sbuffer = "";         value = 0;         Sbuffer = Cbuffer;         ClearCBuffer;         result = 2;       } else       {         ClearCBuffer;         Ccount = 0;         result = 1;                                                //Number Returncode         NumberInput = false;         StrInput = false;         DataInput = false;         EnterInput = false;         Ccount = 0;         return result;       }     }     if ((StrInput) and not (DataInput))                          //String Input only     {       Sbuffer = "";       Sbuffer = Cbuffer;       value = 0;       StrInput = false;       NumberInput = false;       DataInput = false;       EnterInput = false;       Ccount = 0;       ClearCBuffer;       result = 2;                                                 //Number Returncode     }     if (DataInput) {       Sbuffer = "";       Sbuffer = Cbuffer;       value = 0;       StrInput = false;       NumberInput = false;       DataInput = false;       EnterInput = false;       Ccount = 0;       ClearCBuffer;       result = 3;                                               //Number Returncode     }     if ((EnterInput) and not (StrInput) and not (NumberInput) and not (DataInput))     {       Sbuffer = "";       value = 0;       Ccount = 0;       ClearCBuffer;       result = 4;                                               //Number Returncode     }     NumberInput = false;     StrInput = false;     DataInput = false;     EnterInput = false;     Ccount = 0;     return result;   }   return result;   //End CheckforSerialEvent
}



// Eingabebuffer


boolean CheckforserialEvent()
{   while (mySerial.available()) {     // get the new byte:     TBuffer = mySerial.read();     if (TBuffer > 9 && TBuffer < 14)     {       Cbuffer[Ccount] = 0;       TBuffer = 0;       if (EchoMode)       {         mySerial.print(char(13));         mySerial.flush();       }       if (Directprint)       {         mySerial.println("");         DirectprintLine = 0;         DirectprintROW = DirectprintROW + 1;         if ( DirectprintROW > 3)         {           Directprint = false;           lcd.noCursor();           lcd.noBlink();           Sbuffer = "";           value = 0;         } else         {           lcd.cursor();           lcd.blink();           lcd.setCursor(0, DirectprintROW);         }       }       EnterInput = true;       return true;     } else if (TBuffer > 47 && TBuffer < 58 )     {       If ( Ccount < MaxInputBufferSize)       {         Cbuffer[Ccount] = TBuffer;         Ccount++;         If ((Directprint))         {           Lcd.Print(Char(TBuffer));           DirectprintLine = DirectprintLine + 1;           If ( Ccount > MaxInputBufferSize - 1)           {             Lcd.noCursor();             Lcd.noBlink();           } else {             Lcd.Cursor();             Lcd.Blink();           }         }         If (EchoMode) {           mySerial.Print(Char(TBuffer));           mySerial.Flush();         }       } else {         mySerial.Print("#");       }       Number Input detected       NumberInput = True;     }     else If (TBuffer > 64 && TBuffer < 123 )     {       If ( Ccount < MaxInputBufferSize)       {         Cbuffer[Ccount] = TBuffer;         Ccount++;         If ((Directprint))         {           Lcd.Print(Char(TBuffer));           DirectprintLine = DirectprintLine + 1;           If ( Ccount > MaxInputBufferSize - 1)           {             Lcd.noCursor();             Lcd.noBlink();           } else {             Lcd.Cursor();             Lcd.Blink();           }         }         If (EchoMode) {           mySerial.Print(Char(TBuffer));           mySerial.Flush();         }       } else {         mySerial.Print("#");       }       Character Char Input detected       StrInput = True;     }     else If ( (TBuffer == 127 )  |  (TBuffer == 8 ) )     {       If ( DirectprintLine > 0 )       {         DirectprintLine = DirectprintLine - 1;         Lcd.setCursor(DirectprintLine, DirectprintROW);         Lcd.Print(" ");         Lcd.setCursor(DirectprintLine, DirectprintROW);       }       If (( DirectprintLine == 0 ) & ( DirectprintROW > 0 ))       {         DirectprintROW = DirectprintROW - 1;         DirectprintLine = rLcdChr - 1;         Lcd.setCursor(DirectprintLine, DirectprintROW);       }       If ( Ccount > 0)       {         Ccount--;         Cbuffer[Ccount] = 0;         If ((Directprint))         {           If ( Ccount > MaxInputBufferSize - 1)           {             Lcd.noCursor();             Lcd.noBlink();           } else {             Lcd.Cursor();             Lcd.Blink();           }         }         If (EchoMode) {           mySerial.Print("-");           mySerial.Flush();         }       }     }     else     {       If ( Ccount < MaxInputBufferSize)       {         Cbuffer[Ccount] = TBuffer;         Ccount++;         If ((Directprint))         {           DirectprintLine = DirectprintLine + 1;           If (TBuffer < 128) {             Lcd.Print(Char(TBuffer));           } else  {             Lcd.Print(String(TBuffer));           }           If ( Ccount > MaxInputBufferSize - 1)           {             Lcd.noCursor();             Lcd.noBlink();           } else {             Lcd.Cursor();             Lcd.Blink();           }         }         If (EchoMode) {           mySerial.Print(Char(TBuffer));           mySerial.Flush();         }       } else {         mySerial.Print("#");       }       Data Input detected       DataInput = True;     }     Return False;   }   Return False;
}

Void Display processor()  With blue display, scroll ingesisising is omitted, as this only "lubricates"
{   If (RefreshDisplay)   {     Lcd.Clear();     RefreshDisplay = False;     for (Int B = 1; B <= LcdRows; B++)     {       Lcd.setCursor(0, B - 1);       mySerial.Print("Row" + String(B) + ": ");       for (Int C = 0; C < rLcdChr; C++)       {         eeaddress = 0;         eeaddress = (DisplayBankContent * (rLcdChr) * LcdRows) + ((rLcdChr) * B) + C;         Value = 0;         Value = Eeprom.Read(eeaddress);         If (Value > 31) Don't show special characters         {           Delay(100);           Lcd.Print(Char(Value));         } else         {           Lcd.Print(Char(32));         }       }     }   }
}


Void DisplayBank ( Byte cobank)
{   If (cobank  < EEPromBanks )   {     RefreshDisplay = True;   Initalize Display Output     DisplayBankContent = cobank;     mySerial.println("Bank" + String(cobank) + " is displayed on LCD");     MnuState = 0;     Sbuffer = "";     Value = 0;     mySerial.Flush();   } else   {     mySerial.println("Bank not available.");     Value = 0;     MnuState = 0;     Sbuffer = "";     mySerial.Flush();   }
}

 

The new commands created by the menu extension are explained below.

  • S - Read ALL EEPROM Banks

Entering "S" and Enter displays all available memory spaces and their contents. With a 4x20 character display and the Default are 11 memory slots. In the following screenshot Bank 1 is documented:

 

EEPROM Content

  • E - Erase ALL EEPROM Banks

The menu item "E" allows us to "format" the internal EEPROM when using the display for the first time as well as to delete ALL memory banks later in use. A "formatting process" looks like this on the menu interface:

Delete all content using "E"

 

  • W - Write sel. EEPROM Bank

W - Writing

 

  • R - Read sel. EEPROM Bank

If a specific text of a specific memory bank is to be DISPLAYED but not displayed on the display, it can be displayed via the menu item "R" in.

R - Read

 

  • P - Print EEPROM Bank on Display

P - Print

I wish you a lot of fun rebuilding and, as always, until the next time.

DisplaysProjects for beginners

Leave a comment

All comments are moderated before being published

Recommended blog posts

  1. Install ESP32 now from the board manager
  2. Lüftersteuerung Raspberry Pi
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1
  4. ESP32 - das Multitalent
  5. OTA - Over the Air - ESP programming via WLAN