EEPROM Sketch

Hey Guys, I'm new to programming but I have been messing about with my arduino uno for a day or two now and i made a sketch as a practice project.

I was using the EEPROM.h Library because I need to store data on my arduino for a car project, but the data has to remain even if the ignition is cycled.

Anyway its pretty neat, i called it a tool but it just basically lets you run the EEPROM. functions from the serial port and prints the stuff on your screen. IDK if anyone could use this to their benefit, also i welcome the criticism. If there is room for improvement (as I'm sure there is) please highlight it.

Sorry about not commenting it. I've made it a habit to comment stuff I'm gonna come back to latter but i threw this together just to get my head around the EEPROM library.

Oh also you it displays the values in dec but the table axis are hex cause its the most logical way to organize it.

#include <EEPROM.h>

const int ledPin = 13;
int address = 0;
byte value = 0;
int ref = 0;
int h = 0;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  h = EEPROM.length()/16;
}

void loop() {
  
  Serial.println("------------------MAIN MENU-----------------");
  Serial.println("| please enter one of following selections |");
  Serial.println("| 1 -- Dump EEPROM                         |");
  Serial.println("| 2 -- Clear EEPROM                        |");
  Serial.println("| 3 -- EEPROM Size                         |");
  Serial.println("| 4 -- Write EEPROM                        |");
  Serial.println("| 5 -- Read EEPROM                         |");
  Serial.println("| 6 -- Write All                           |");
  Serial.println("| 7 -- Address Refrence                    |");
  Serial.println("| 8 -- No Action                           |");
  Serial.println("| 9 -- No Action                           |");    
  Serial.println("--------------------------------------------");
  Serial.println();

  
  while(Serial.available()==0) {
  }
  while(Serial.available() > 0) {
    int input = Serial.parseInt();

    switch (input) {

     /* 
      case 1:
      address = 0;
      while(address < EEPROM.length()){
        value = EEPROM.read(address);
        Serial.print(address);
        Serial.print("\t");
        Serial.print(value, DEC);
        Serial.println();
        address++;
      }
      address = 0;      
      break;
      */

      case 1:
      address = 0;
      while(address < EEPROM.length()){
        for(int c=0; c<16; c++){
          Serial.print("\t");
          Serial.print(c, HEX);
        }
        Serial.println();
        Serial.println();
        for(int a=0; a<h; a++) {
          Serial.print(a, HEX);
          for(int b=0; b<16; b++) {
            value = EEPROM.read(address);
            Serial.print("\t");
            Serial.print(value, DEC);
            address++;
          }
          Serial.println();
        }
      }
      address = 0;
      break;
      
      case 2:
      Serial.println("Clearing");
      digitalWrite(ledPin, 1);
      for(int i=0; i<EEPROM.length(); i++){
        EEPROM.write(i, 0);
      }
      Serial.println("Complete");
      digitalWrite(ledPin, 0);
      break;

      
      case 3:
      Serial.println(EEPROM.length());
      break;

      
      case 4:
      Serial.println("Which Address?");
      while(Serial.available()==0) { 
      }
      address = Serial.parseInt();
      if(address < 0 || address > 1023){
        Serial.println("invalid entry");
        address = 0;
        return;
      }
      Serial.println("What value?");
      while(Serial.available()==0) { 
      }
      input=Serial.parseInt();
      if(input < 0 || input > 255) {
        Serial.println("invalid entry 0-255");
        return;
      }
      value = byte(input);
      EEPROM.write(address, value);
      address = 0;
      break;

      
      case 5:
      Serial.println("Which Address?");
      while(Serial.available()==0){
      }
      address = Serial.parseInt();
      if(address < 0 || address > 1023){
        Serial.println("invalid entry");
        address = 0;
        return;
      }
      value = EEPROM.read(address);
      Serial.print(address);
      Serial.print("\t");
      Serial.print(value, DEC);
      Serial.println();
      value = 0;
      address = 0;
      break;

      case 6:
      Serial.println("What value?");
      while(Serial.available()==0) { 
      }
      input=Serial.parseInt();
      if(input < 0 || input > 255) {
        Serial.println("invalid entry 0-255");
        return;
      }
      value = byte(input);
      Serial.println("Writing");
      digitalWrite(ledPin, 1);
      for(int i=0; i<EEPROM.length(); i++){
        EEPROM.write(i, value);
      }
      value = 0;
      Serial.println("Complete");
      digitalWrite(ledPin, 0);
      break;

      case 7:
        while(ref < EEPROM.length()){
        for(int c=0; c<16; c++){
          Serial.print("\t");
          Serial.print(c, HEX);
        }
        Serial.println();
        Serial.println();
        for(int a=0; a<h; a++) {
          Serial.print(a, HEX);
          for(int b=0; b<16; b++) {
            Serial.print("\t");
            Serial.print(ref, DEC);
            ref++;
          }
          Serial.println();
        }
       }
       ref = 0;
       break;

      
      default:
      Serial.println("invalid Selection");
      Serial.println();
      break;
    }  
  }
}

Thanks for sharing!

Some constructive comments

const int ledPin = 13;

Good to use const and the word pin, a better type would be byte. Also specifically for the LED (on pin 13 usually) there is a default name for it LED_BUILTIN. Cf this explanation

Serial.begin(9600);

Both your arduino and computer are way faster than this, you can use 115200 baud there (or more)

Serial.println("------------------MAIN MENU-----------------");

And all the others similar lines. You are using tons of your very limited SRAM (2k on a UNO) for each character within the quotes. Read about PROGMEM and the description of the various types of memory available on an Arduino. Then You might want to use this form:

Serial.println([color=red]F([/color]"------------------MAIN MENU-----------------"[color=red])[/color]);
while(Serial.available()==0) {}

This is a personal preference but there is no need to do {}. If there is no expression to execute a semicolon is enough

while(Serial.available()==0) [color=red];[/color] // wait for input

Your input parsing is approximative, while working with short selection and quick entry through the console because parseInt() implements a timeout. A better parsing scheme in general would be needed where you wait until the carriage return for example to build the command (CF Robin's post on Serial Input Basics)

EEPROM.write(...)

Given your EEPROM has a limited lifetime (100,000 writes), instead of calling write() you might want to prefer the update() method. It's a bit slower as it reads first the value and won't write if the same value needs to be stored, but you'll get an expanded lifetime especially if you often write the same values.

Hope this helps

Awesome Thank you very much. Ill Make these changes, I had been playing with the baud rate. No Errors at 250000. I was also wondering about the EEPROM only being writable a few times, this information was very useful to me. Ill make the changes now.

J-M-L:
Thanks for sharing!

Some constructive comments

const int ledPin = 13;

Good to use const and the word pin, a better type would be byte. Also specifically for the LED (on pin 13 usually) there is a default name for it LED_BUILTIN. Cf this explanation

Serial.begin(9600);

Both your arduino and computer are way faster than this, you can use 115200 baud there (or more)

Serial.println("------------------MAIN MENU-----------------");

And all the others similar lines. You are using tons of your very limited SRAM (2k on a UNO) for each character within the quotes. Read about PROGMEM and the description of the various types of memory available on an Arduino. Then You might want to use this form:

Serial.println([color=red]F([/color]"------------------MAIN MENU-----------------"[color=red])[/color]);
while(Serial.available()==0) {}

This is a personal preference but there is no need to do {}. If there is no expression to execute a semicolon is enough

while(Serial.available()==0) [color=red];[/color] // wait for input

Your input parsing is approximative, while working with short selection and quick entry through the console because parseInt() implements a timeout. A better parsing scheme in general would be needed where you wait until the carriage return for example to build the command (CF Robin's post on Serial Input Basics)

EEPROM.write(...)

Given your EEPROM has a limited lifetime (100,000 writes), instead of calling write() you might want to prefer the update() method. It's a bit slower as it reads first the value and won't write if the same value needs to be stored, but you'll get an expanded lifetime especially if you often write the same values.

Hope this helps

Ok the changes have been made.
Except for the Serial.parseInt() I am still reading the post from CF Robin.

#include <EEPROM.h>

const byte ledPin = LED_BUILTIN;
int address = 0;
byte value = 0;
int ref = 0;
int h = 0;

void setup() {
  Serial.begin(250000);
  pinMode(ledPin, OUTPUT);
  h = EEPROM.length()/16;
}

void loop() {
  
  Serial.println(F("------------------MAIN MENU-----------------"));
  Serial.println(F("| please enter one of following selections |"));
  Serial.println(F("| 1 -- Dump EEPROM                         |"));
  Serial.println(F("| 2 -- Clear EEPROM                        |"));
  Serial.println(F("| 3 -- EEPROM Size                         |"));
  Serial.println(F("| 4 -- Write EEPROM                        |"));
  Serial.println(F("| 5 -- Read EEPROM                         |"));
  Serial.println(F("| 6 -- Write All                           |"));
  Serial.println(F("| 7 -- Address Refrence                    |"));
  Serial.println(F("| 8 -- No Action                           |"));
  Serial.println(F("| 9 -- No Action                           |"));    
  Serial.println(F("--------------------------------------------"));
  Serial.println();

  
  while(Serial.available()==0);
  while(Serial.available() > 0) {
    int input = Serial.parseInt();

    switch (input) {

     /* 
      case 1:
      address = 0;
      while(address < EEPROM.length()){
        value = EEPROM.read(address);
        Serial.print(address);
        Serial.print("\t"));
        Serial.print(value, DEC);
        Serial.println();
        address++;
      }
      address = 0;      
      break;
      */

      case 1:
      address = 0;
      while(address < EEPROM.length()){
        for(int c=0; c<16; c++){
          Serial.print("\t");
          Serial.print(c, HEX);
        }
        Serial.println();
        Serial.println();
        for(int a=0; a<h; a++) {
          Serial.print(a, HEX);
          for(int b=0; b<16; b++) {
            value = EEPROM.read(address);
            Serial.print("\t");
            Serial.print(value, DEC);
            address++;
          }
          Serial.println();
        }
      }
      address = 0;
      break;
      
      case 2:
      Serial.println(F("Clearing"));
      digitalWrite(ledPin, 1);
      for(int i=0; i<EEPROM.length(); i++){
        EEPROM.update(i, 0);
      }
      Serial.println(F("Complete"));
      digitalWrite(ledPin, 0);
      break;

      
      case 3:
      Serial.println(EEPROM.length());
      break;

      
      case 4:
      Serial.println(F("Which Address?"));
      while(Serial.available()==0);
      address = Serial.parseInt();
      if(address < 0 || address > 1023){
        Serial.println(F("invalid entry"));
        address = 0;
        return;
      }
      Serial.println(F("What value?"));
      while(Serial.available()==0) { 
      }
      input=Serial.parseInt();
      if(input < 0 || input > 255) {
        Serial.println(F("invalid entry 0-255"));
        return;
      }
      value = byte(input);
      EEPROM.update(address, value);
      address = 0;
      break;

      
      case 5:
      Serial.println(F("Which Address?"));
      while(Serial.available()==0);
      address = Serial.parseInt();
      if(address < 0 || address > 1023){
        Serial.println(F("invalid entry"));
        address = 0;
        return;
      }
      value = EEPROM.read(address);
      Serial.print(address);
      Serial.print("\t");
      Serial.print(value, DEC);
      Serial.println();
      value = 0;
      address = 0;
      break;

      case 6:
      Serial.println(F("What value?"));
      while(Serial.available()==0);
      input=Serial.parseInt();
      if(input < 0 || input > 255) {
        Serial.println(F("invalid entry 0-255"));
        return;
      }
      value = byte(input);
      Serial.println(F("Writing"));
      digitalWrite(ledPin, 1);
      for(int i=0; i<EEPROM.length(); i++){
        EEPROM.update(i, value);
      }
      value = 0;
      Serial.println(F("Complete"));
      digitalWrite(ledPin, 0);
      break;

      case 7:
        while(ref < EEPROM.length()){
        for(int c=0; c<16; c++){
          Serial.print("\t");
          Serial.print(c, HEX);
        }
        Serial.println();
        Serial.println();
        for(int a=0; a<h; a++) {
          Serial.print(a, HEX);
          for(int b=0; b<16; b++) {
            Serial.print("\t");
            Serial.print(ref, DEC);
            ref++;
          }
          Serial.println();
        }
       }
       ref = 0;
       break;

      
      default:
      Serial.println(F("invalid Selection"));
      Serial.println();
      break;
    }  
  }
}

Great - karma for following up and digging into this and increasing knowledge :slight_smile:

Hi,

case 4:
Serial.println(F("Which Address?"));
while(Serial.available()==0);
address = Serial.parseInt();

It does not wait for the user input and use the address 0.

?

JPD

It does not wait for the user input and use the address 0.

?

Are you responding to the original post, now over 2 years old, or is this a problem that you are having ?

Hi,

This a problem that I am having with the original post, now over 2 years old ?

I copied-paste the last version of the sketch.

In case 4:

It does not wait for the user input and uses the address 0 but it waits for the value input and overwrite the address 0 ............ !?

?

Please post your complete program copied from the IDE so that we know exactly what code you are using

/*
   mega 2506 size  4096

*/
#include <EEPROM.h>

const byte ledPin = LED_BUILTIN;
int address = 0;
byte value = 0;
int ref = 0;
int h = 0;

void setup() {
  Serial.begin(115200);
  pinMode(ledPin, OUTPUT);
  h = EEPROM.length() / 16;
}

void loop() {

  Serial.println(F("------------------MAIN MENU-----------------"));
  Serial.println(F("| please send one of following selections |"));
  Serial.println(F("| 1 -- Dump EEPROM                         |"));
  Serial.println(F("| 2 -- Clear EEPROM                        |"));
  Serial.println(F("| 3 -- EEPROM Size                         |"));
  Serial.println(F("| 4 -- Write EEPROM                        |"));
  Serial.println(F("| 5 -- Read EEPROM                         |"));
  Serial.println(F("| 6 -- Write All                           |"));
  Serial.println(F("| 7 -- Address Refrence                    |"));
  Serial.println(F("| 8 -- Print used address                          |"));
  Serial.println(F("| 9 -- No Action                           |"));
  Serial.println(F("--------------------------------------------"));
  Serial.println();


  while (Serial.available() == 0);
  while (Serial.available() > 0) {
    int input = Serial.parseInt();

    switch (input) {

      /*
        case 1:
        address = 0;
        while(address < EEPROM.length()){
         value = EEPROM.read(address);
         Serial.print(address);
         Serial.print("\t"));
         Serial.print(value, DEC);
         Serial.println();
         address++;
        }
        address = 0;
        break;
      */

      case 1:
        address = 0;
        while (address < EEPROM.length()) {
          for (int c = 0; c < 16; c++) {
            Serial.print("\t");
            Serial.print(c, HEX);
          }
          Serial.println();
          Serial.println();
          for (int a = 0; a < h; a++) {
            Serial.print(a, HEX);
            for (int b = 0; b < 16; b++) {
              value = EEPROM.read(address);
              Serial.print("\t");
              Serial.print(value, DEC);
              address++;
            }
            Serial.println();
          }
        }
        address = 0;
        break;

      case 2:
        Serial.println(F("Clearing"));
        digitalWrite(ledPin, 1);
        for (int i = 0; i < EEPROM.length(); i++) {
          EEPROM.update(i, 0);
        }
        Serial.println(F("Complete"));
        digitalWrite(ledPin, 0);
        break;


      case 3:
        Serial.println(EEPROM.length());
        break;


      case 4:
        Serial.println(F("Which Address?"));
        while (Serial.available() == 0) {
        }
        address = Serial.parseInt();
        Serial.print(F("your entry = "));
        //value = EEPROM.read(address);
        if (address < 0 || address > 1023) {
          Serial.println(F("invalid entry"));
          address = 0;
          return;
        }
        Serial.println(address);
        Serial.println(F(" What value?"));
        while (Serial.available() == 0) {
        }
        input = Serial.parseInt();
        if (input < 0 || input > 255) {
          Serial.println(F("invalid entry 0-255"));
          return;
        }
        value = byte(input);
        //value = EEPROM.read(address);
        EEPROM.put(address, value);
        Serial.print(F("address = "));
        Serial.print(address);
        Serial.print(F("  value = "));
        Serial.println(value);
        address = 0;
        break;


      case 5:
        Serial.println(F("Which Address?"));
        while (Serial.available() == 0);
        address = Serial.parseInt();
        if (address < 0 || address > 1023) {
          Serial.println(F("invalid entry"));
          address = 0;
          return;
        }
        value = EEPROM.read(address);
        Serial.print(F("Address is: "));
        Serial.print(address);
        Serial.print("\t");
        Serial.print(F("value is: "));
        Serial.print(value);
        Serial.print("\t");
        Serial.print(F("value DEC is: "));
        Serial.println(value, DEC);
        Serial.println();
        value = 0;
        address = 0;
        break;

      case 6:
        Serial.println(F("What value?"));
        while (Serial.available() == 0);
        input = Serial.parseInt();
        if (input < 0 || input > 255) {
          Serial.println(F("invalid entry 0-255"));
          return;
        }
        value = byte(input);
        Serial.println(F("Writing"));
        digitalWrite(ledPin, 1);
        for (int i = 0; i < EEPROM.length(); i++) {
          EEPROM.update(i, value);
        }
        value = 0;
        Serial.println(F("Complete"));
        digitalWrite(ledPin, 0);
        break;

      case 7:
        while (ref < EEPROM.length()) {
          for (int c = 0; c < 16; c++) {
            Serial.print("\t");
            Serial.print(c, HEX);
          }
          Serial.println();
          Serial.println();
          for (int a = 0; a < h; a++) {
            Serial.print(a, HEX);
            for (int b = 0; b < 16; b++) {
              Serial.print("\t");
              Serial.print(ref, DEC);
              ref++;
            }
            Serial.println();
          }
        }
        ref = 0;
        break;

      case 8:
        address = 0;
        int flag = 0;
        while (address < EEPROM.length()) {
          if (flag == 0) {
            for (int c = 0; c < 16; c++) {
              Serial.print("\t");
              Serial.print(c, HEX);
            }
            flag = 1;
          }
          Serial.println();
          Serial.println();
          for (int a = 0; a < h; a++) {
            //Serial.print(a, HEX);
            for (int b = 0; b < 16; b++) {
              value = EEPROM.read(address);
              Serial.print("\t");
              if (value != '\0') {
                Serial.print(value, DEC);
              }
            }
            address++;
          }
          Serial.println();
        }

        address = 0;
        break;


      default:
        Serial.println(F("invalid Selection"));
        Serial.println();
        break;
    }
  }
}

What have you got the Line Ending set to in the Serial monitor ?

In case 4:

It does not wait for the user input and uses the address 0 but it waits for the value input and overwrite the address 0 ............ !?

that's because it's a poor way to handle Serial input... it's all documented above... have you read the thread?

There is a time out associated to Serial.parseInt(); which is 1 second by default.
So unless you type in very quickly the address (or on the same line "4<space>address<CR><LF>") you'll miss that data

I would suggest to study Serial Input Basics to handle this

Hi, yes I have read the thread. Although I did not memorized everything.

Thank you for your answer. I will read.

Hummmmmmmmmmm, should I put a delay() in there ?

Jean24816:
Hummmmmmmmmmm, should I put a delay() in there ?

what do you want us to say? a delay where and to do what? usually when dealing with asynchronous protocols, it's not a great idea to try to second guess when data will be ready by adding fixed delays.... just read stuff when they come in and structure your code accordingly (usually a state machine could help)

Thank you.

JPD

while(Serial.available()==0) ; // wait for input

There are (in the above quote) two statements; however, how do I defend if a new learner says that there is only one statement looking at the comma ( ; ) which is usually a statement terminating character? Therefore, should not the quoted expression be written as follows from literate programming point of view?

while(Serial.available()==0) 
   ;

A semicolon alone is a legit empty expression statement. As is {}
Wether you place it on the same line or on a line by itself or multiple lines is personal indenting preference