EEPROM

Hi Guys,

I am sending message thru Bluetooth, getting it on LCD.
I got this part working, all good.

Now I want to store that message on EEPROM.

And when device powered up , it should show that message.

Everything working but message is not showing. for some reason its showing 152.

Could you please help me to find mistake?

Here is my code

#include <Wire.h>
#include <hd44780.h>            // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h>  // i2c expander i/o class header
#include <EEPROM.h>

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip

int addr = 0;
byte value;


char terminalRead;

// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;

void setup() {
  Serial.begin(9600);  

int status;
status = lcd.begin(LCD_COLS, LCD_ROWS);
  if(status) // non zero status means it was unsuccesful
  {
    status = -status; // convert negative status value to positive number

    // begin() failed so blink error code using the onboard LED if possible
 //   hd44780::fatalError(status); // does not return
  }

  // turn on automatic line wrapping
  // which automatically wraps lines to the next lower line and wraps back
  // to the top when at the bottom line
  // NOTE: 
  // noLineWrap() can be used to disable automatic line wrapping.
  // _write() can be called instead of write() to send data bytes
  // to the display bypassing any special character or line wrap processing.
  lcd.lineWrap();
value = EEPROM.read(addr);
lcd.setCursor(0, 0);
lcd.print("EEPROM");
lcd.setCursor(0, 1);
lcd.print(value);



  //char terminalRead;
  

}
void loop() {
  terminalRead=Serial.read();
 int i=0;
  char commandbuffer[100];

  if(Serial.available()){
     delay(1000);
     while( Serial.available() && i< 99) {
        commandbuffer[i++] = Serial.read();
     }
     commandbuffer[i++]='\0';

 


  if(i>0)

     Serial.println((char*)commandbuffer);
     lcd.clear();
     lcd.cursor();


     
char c = ((char*)commandbuffer);

for(int i=2*LCD_COLS*LCD_ROWS; i; i--)


lcd.print(c);
     
     lcd.setCursor(0, 0);
lcd.print((char*)commandbuffer);
//     if(c > 0x7e) // wrap back to beginning of printable ASCII chars
//     c = '!'; 
     
     
     EEPROM.write(addr, (char*)commandbuffer);
     delay(1000);
//    lcd.clear();
  }

}

What you are writing to EEPROM is not correct. You are reading in a series of chars into your commandbuffer array but then you are writing the address of that variable to EEPROM. The write() function only writes one byte, not an entire string like lcd.print() does.

If you want to write just one byte, you would use EEPROM.write(addr, commandbuffer[0]);

If you want to interpret what is in the commandbuffer as a number (e.g. "123"), then you need to use atoi() to convert it and then write that value.

Try the following put() and get() methods instead of read() and write() methods:

EEPROM.put(addr, (char*)commandbuffer); 
EEPROM.get(addr, myData);

you are reading only one byte from your eeprom. if you want a character representation instead of the byte value then you need to cast it to string or char array before you print.

Hi,

yeah, I am starting to understand now. It was only one byte.
Learning about strings and arrays now.
something like that

char *myStrings[] = {"This is string 1", "This is string 2", "This is string 3",
                     "This is string 4", "This is string 5", "This is string 6"
                    };

void setup() {
  Serial.begin(9600);
}

void loop() {
  for (int i = 0; i < 6; i++) {
    Serial.println(myStrings[i]);
    delay(500);
  }
}

Hi guys,

I tried arrays.
I used
value = EEPROM.get(0, myArray);

and I used EEPROM.put

I arranged my array from serial reading -
if(Serial.available()>0){
myArray=Serial.available();

And somehow I still get exactly the same result. LCD showing “152” after I turn it on.
Could you please point me where I should look for mistake
Also I was thinking - EEPROM has some kind of read/wright limit. So I don’t want to write in it every second. What kind of solution could save EEPROM in my project?
Here is my current code

#include <Wire.h>
#include <hd44780.h>            // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h>  // i2c expander i/o class header
#include <EEPROM.h>

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip

int addr = 0;
byte value;

int myArray[100];
int X = 0;

char terminalRead;

// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;

void setup() {
  Serial.begin(9600);  

int status;
status = lcd.begin(LCD_COLS, LCD_ROWS);
  if(status) // non zero status means it was unsuccesful
  {
    status = -status; // convert negative status value to positive number

    // begin() failed so blink error code using the onboard LED if possible
 //   hd44780::fatalError(status); // does not return
  }

  // turn on automatic line wrapping
  // which automatically wraps lines to the next lower line and wraps back
  // to the top when at the bottom line
  // NOTE: 
  // noLineWrap() can be used to disable automatic line wrapping.
  // _write() can be called instead of write() to send data bytes
  // to the display bypassing any special character or line wrap processing.
  lcd.lineWrap();



  
value = EEPROM.get(0, myArray[X]);


lcd.setCursor(0, 0);
lcd.print("EEPROM");
lcd.setCursor(0, 1);
lcd.print(value);



  //char terminalRead;
  

}
void loop() {
  terminalRead=Serial.read();
 int i=0;
  char commandbuffer[100];

  if(Serial.available()){
     delay(1000);
     while( Serial.available() && i< 99) {
        commandbuffer[i++] = Serial.read();
     }
     commandbuffer[i++]='\0';

 


  if(i>0)

     Serial.println((char*)commandbuffer);
     lcd.clear();
     lcd.cursor();


     
char c = ((char*)commandbuffer);

for(int i=2*LCD_COLS*LCD_ROWS; i; i--)


lcd.print(c);
     
     lcd.setCursor(0, 0);
lcd.print((char*)commandbuffer);
//     if(c > 0x7e) // wrap back to beginning of printable ASCII chars
//     c = '!'; 
if(Serial.available()>0){
  myArray[X]=Serial.available();
  X = X + 1;
}
}
     
//     EEPROM.write(addr, (char*)commandbuffer);
//
EEPROM.put(0, myArray[X]);
//EEPROM.put(addr, (char*)commandbuffer); 
     delay(1000);
//    lcd.clear();
  }

Try this code. Basically, you need to loop over your array of char (not int) and read/write each char to/from EEPROM

#include <Wire.h>
#include <hd44780.h>            // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h>  // i2c expander i/o class header
#include <EEPROM.h>

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip

int addr = 0;
byte value;

const int maxMessageLength = 100;
char myMsg[maxMessageLength];


// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;

void setup() {
  Serial.begin(9600);

  int status;
  status = lcd.begin(LCD_COLS, LCD_ROWS);
  if (status) // non zero status means it was unsuccesful
  {
    status = -status; // convert negative status value to positive number

    // begin() failed so blink error code using the onboard LED if possible
    //   hd44780::fatalError(status); // does not return
  }

  // turn on automatic line wrapping
  // which automatically wraps lines to the next lower line and wraps back
  // to the top when at the bottom line
  // NOTE:
  // noLineWrap() can be used to disable automatic line wrapping.
  // _write() can be called instead of write() to send data bytes
  // to the display bypassing any special character or line wrap processing.
  lcd.lineWrap();

  // copy existing message from EEPROM
  // copy until we get a nul (0) or any char above 127 or max message length
  for ( int i = 0; i < maxMessageLength; ++i ) {
    char c = EEPROM[i];
    if ( c > 127 or c == 0 ) {
      myMsg[i] = '\0';
      break;
    }
    myMsg[i] = c;
  }

  lcd.setCursor(0, 0);
  lcd.print("EEPROM");
  lcd.setCursor(0, 1);
  lcd.print(myMsg);

}

void loop() {
  char terminalRead = Serial.read();
  int idx = 0;
  char commandbuffer[maxMessageLength];

  if (Serial.available()) {
    delay(1000);
    while ( Serial.available() && i < maxMessageLength - 1) {
      commandbuffer[idx++] = Serial.read();
    }
    commandbuffer[idx] = '\0';

    if (idx > 0) {
      Serial.println(commandbuffer);
    }
    lcd.clear();
    lcd.cursor();
    lcd.setCursor(0, 0);
    lcd.print(commandbuffer);

    for ( int i = 0; i < idx; ++i ) {
      EEPROM[i] = commandbuffer[i];
    }
    delay(1000);
    //    lcd.clear();
  }
}

Thank you blh64,

I just tried it.

Its asking me to declare “i” for this line while ( Serial.available() && i < maxMessageLength - 1)

I am not sure what “i” should be. I think its 0

i tried

int i = 0;

but got that on LCD (see attached image plz)

It does show message on LCD but only for a moment!
And then it gets covered by blocks

I tried adding delays to see what happens.

I cant find it somehow

what happens now:
everything working.
message is showing on LCD from EEPROM. However only for a split second.

here is current code:

#include <Wire.h>
#include <hd44780.h>            // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h>  // i2c expander i/o class header
#include <EEPROM.h>

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip

int addr = 0;
byte value;

const int maxMessageLength = 100;
char myMsg[maxMessageLength];


// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;

int i = 0;

void setup() {
  Serial.begin(9600);

  int status;
  status = lcd.begin(LCD_COLS, LCD_ROWS);
  if (status) // non zero status means it was unsuccesful
  {
    status = -status; // convert negative status value to positive number

    // begin() failed so blink error code using the onboard LED if possible
    //   hd44780::fatalError(status); // does not return
  }

  // turn on automatic line wrapping
  // which automatically wraps lines to the next lower line and wraps back
  // to the top when at the bottom line
  // NOTE:
  // noLineWrap() can be used to disable automatic line wrapping.
  // _write() can be called instead of write() to send data bytes
  // to the display bypassing any special character or line wrap processing.
  lcd.lineWrap();

  // copy existing message from EEPROM
  // copy until we get a nul (0) or any char above 127 or max message length
  for ( int i = 0; i < maxMessageLength; ++i ) {
    char c = EEPROM[i];
    if ( c > 127 or c == 0 ) {
      myMsg[i] = '\0';
      break;
    }
    myMsg[i] = c;
  }

  lcd.setCursor(0, 0);
  lcd.print("EEPROM");
  lcd.setCursor(0, 1);
  lcd.print(myMsg);
 

}

void loop() {
  
  char terminalRead = Serial.read();
  int idx = 0;
  char commandbuffer[maxMessageLength];

  if (Serial.available()) {
    delay(1000);
    while ( Serial.available() && i < maxMessageLength - 1) {
      commandbuffer[idx++] = Serial.read();
    }
    commandbuffer[idx] = '\0';

    if (idx > 0) {
      Serial.println(commandbuffer);
    }
    lcd.clear();
    lcd.cursor();
    lcd.setCursor(0, 0);
    lcd.print(commandbuffer);

    for ( int i = 0; i < idx; ++i ) {
      EEPROM[i] = commandbuffer[i];
    }
    delay(1000);
    //    lcd.clear();
  }
}

I had changed your 'i' variable to 'idx'

Based on your questions and attempts at code, I would really suggest you look at some of the examples that come with the IDE and really learn how they work and why.

As a way of debugging your code, you can do everything you did in your setup() function but then leave your loop() function empty so your code will only read from EEPROM and print to the LCD and do nothing else. If there still is a problem, then it may be with reading in the message. You can also print your message out to Serial with some sort of marker before it and after it to see if it is what you expect.

Thank you so much blh64 :slight_smile:
I am learning a lot from you! You right, I need to go back to basics. Working on it now.
I just really need that project coz its a part of other project. Its digital label.

I changed to idx.
Its working, however after powering it up, I get just some of the text

here is two pictures: first pic is showing when text message sent thru Bluetooth terminal (sometimes it looses first symbols);
and second picture is showing LCD after powering Arduino up.

I tried to connect Bluetooth module to SUART but it didn’t work.
I used this diagram (see pic attached)

I don’t really know what else

hc5-1.png

I tried arrays.
I used
value = EEPROM.get(0, myArray);

If you used
EEPROM.get(0, myArray);
It would read the value at EEPROM 0 into the array all at once. There is no need to iterate through addresses and array levels

Hi guys,

Could you please help with debagging
I tried to make loop function empty but I was getting too many error messages. I don’t think I did it right.
What other ways to find where the program is failing?

#include <Wire.h>
#include <hd44780.h>            // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h>  // i2c expander i/o class header
#include <EEPROM.h>

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip

//int addr = 0;
//byte value;

const int maxMessageLength = 100;
char myMsg[maxMessageLength];


// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;



void setup() {
  Serial.begin(9600);

  int status;
  status = lcd.begin(LCD_COLS, LCD_ROWS);
  if (status) // non zero status means it was unsuccesful
  {
    status = -status; // convert negative status value to positive number

    // begin() failed so blink error code using the onboard LED if possible
    //   hd44780::fatalError(status); // does not return
  }

  // turn on automatic line wrapping
  // which automatically wraps lines to the next lower line and wraps back
  // to the top when at the bottom line
  // NOTE:
  // noLineWrap() can be used to disable automatic line wrapping.
  // _write() can be called instead of write() to send data bytes
  // to the display bypassing any special character or line wrap processing.
  lcd.lineWrap();

  // copy existing message from EEPROM
  // copy until we get a nul (0) or any char above 127 or max message length
  for ( int idx = 0; idx < maxMessageLength; ++idx ) {
    char c = EEPROM[idx];
    if ( c > 127 or c == 0 ) {
      myMsg[idx] = '\0';
      break;
    }
    myMsg[idx] = c;
  }

 // lcd.setCursor(0, 0);
 // lcd.print("EEPROM");
  lcd.setCursor(0, 0);lcd.clear();
  lcd.print(myMsg);
 

}

void loop() {
  
  char terminalRead = Serial.read();
  int idx = 0;
  char commandbuffer[maxMessageLength];

  if (Serial.available()) {
    delay(1000);
    while ( Serial.available() && idx < maxMessageLength - 1) {
      commandbuffer[idx++] = Serial.read();
    }
    commandbuffer[idx] = '\0';

    if (idx > 0) {
      Serial.println(commandbuffer);
    }
    lcd.clear();
    lcd.cursor();
    lcd.setCursor(0, 0);
    lcd.print(commandbuffer);

    for ( int i = 0; i < idx; ++i ) {
      EEPROM[i] = commandbuffer[i];
    }
    delay(1000);
    //    lcd.clear();
  }
}

The code you posted does not have an empty loop() function.
You did not provide any error messages you encountered.

How exactly is anybody supposed to help?

EEPROM[i] = commandbuffer[i];
char c = EEPROM[idx];

This syntax is wrong. Your need to read or write or get or put.

Have you looked at the basic library examples?

cattledog:

EEPROM[i] = commandbuffer[i];

char c = EEPROM[idx];




This syntax is wrong. Your need to read or write or get or put.

Have you looked at the basic library examples?

No, it is not. You can access single bytes of EEPROM by subscript like it is an array.

It is part of the documentation here

No, it is not. You can access single bytes of EEPROM by subscript like it is an array.
It is part of the documentation here

Thanks. Learned something. It looks like that syntax came in with EEPROM v2.0 with IDE 1.6.2.

My apologies to @PASHGEN.

Good Morning blh64,

I moved loop function to the end, so the whole program run one time only.
But cant compile code. Getting error message - expected unqualified-id before ‘if’
highlighted line:

if (Serial.available()) {

I tried to move brackets.
I did more reading. I found that it happens when statement is outside the function. But I still don’t understand how to change it, and what.
Could you please tell me where to look. I really want to get good at Arduino

#include <Wire.h>
#include <hd44780.h>            // main hd44780 header
#include <hd44780ioClass/hd44780_I2Cexp.h>  // i2c expander i/o class header
#include <EEPROM.h>

hd44780_I2Cexp lcd; // declare lcd object: auto locate & config exapander chip

//int addr = 0;
//byte value;

const int maxMessageLength = 100;
char myMsg[maxMessageLength];


// LCD geometry
// while 16x2 will work on most displays even if the geometry is different,
// for actual wrap testing of a particular LCD it is best to use the correct
// geometry.
const int LCD_COLS = 20;
const int LCD_ROWS = 4;



void setup() {
  Serial.begin(9600);

  int status;
  status = lcd.begin(LCD_COLS, LCD_ROWS);
  if (status) // non zero status means it was unsuccesful
  {
    status = -status; // convert negative status value to positive number

    // begin() failed so blink error code using the onboard LED if possible
    //   hd44780::fatalError(status); // does not return
  }

  // turn on automatic line wrapping
  // which automatically wraps lines to the next lower line and wraps back
  // to the top when at the bottom line
  // NOTE:
  // noLineWrap() can be used to disable automatic line wrapping.
  // _write() can be called instead of write() to send data bytes
  // to the display bypassing any special character or line wrap processing.
  lcd.lineWrap();

  // copy existing message from EEPROM
  // copy until we get a nul (0) or any char above 127 or max message length
  for ( int idx = 0; idx < maxMessageLength; ++idx ) {
    char c = EEPROM[idx];
    if ( c > 127 or c == 0 ) {
      myMsg[idx] = '\0';
      break;
    }
    myMsg[idx] = c;
  }

 // lcd.setCursor(0, 0);
 // lcd.print("EEPROM");
  lcd.setCursor(0, 0);lcd.clear();
  lcd.print(myMsg);
 

}


  
  char terminalRead = Serial.read();
  int idx = 0;
  char commandbuffer[maxMessageLength];

  if (Serial.available()) {
    delay(1000);
    while ( Serial.available() && idx < maxMessageLength - 1) {
      commandbuffer[idx++] = Serial.read();
    }
    commandbuffer[idx] = '\0';

    if (idx > 0) {
      Serial.println(commandbuffer);
    }
    lcd.clear();
    lcd.cursor();
    lcd.setCursor(0, 0);
    lcd.print(commandbuffer);

    for ( int i = 0; i < idx; ++i ) {
      EEPROM[i] = commandbuffer[i];
    }
    delay(1000);
    //    lcd.clear();
  }
  void loop() {
}