Go Down

Topic: EEPROM reading and saving via Serial Monitor (Read 5233 times) previous topic - next topic

mahmoud-saad

hello

may i present you with the project that i have been working on for 14 days and can't finish  :D

it is quite exhausting i worked out a great code, but still don't work i want to consult you (experienced people). on why the code isn't working :D

I'm working on a code that can simply
write an order:"read ' address of EEPROM'" in the Serial Monitor and it reads out the data in this EEPROM address and print on Serial monitor
and another order
and
write another order:"write 'address of EEPROM' 'number i want to save in'" and it saves that number into the specified EEPROM memory


and here's my code i wish you can help me with why it is not working


void setup()
{
Serial.begin(9600);
Serial.println("This code allows you to read and write from the EEPROM memory");
  /* add setup code here */

}

#include <EEPROM.h>
String command;

void loop()
{
   if (Serial.available())
   {
      char c=Serial.read();
      if (c=='\n')
      {
         parseCommand(command);
         command="";
      }
      else
      command+= c;
   }
}

void parseCommand (String com)
{
   String part1;
   String part2;
   String part3;
   part1 = com.substring(0, com.indexOf(" "));
   part2 = com.substring(com.indexOf(" ")+1);
   if(part1.equalsIgnoreCase("read"))
   {
      int addressRead = part2.toInt();
      int valueRead = EEPROM.read(addressRead);
      Serial.print("\n");
      Serial.print("ADDRESS:");
      Serial.print(addressRead, DEC);
      Serial.print("\t");
      Serial.print("VALUE:");
      Serial.print(valueRead, DEC);
   }
   else if(part1.equalsIgnoreCase("write"))
   {
      part2 = com.substring(com.indexOf(" ")+1);
      part3 = part2.substring(part2.indexOf(" "));
      String address=part2.substring(0,part2.indexOf(" "));
      int addressWrite = address.toInt();
      int valueWrite = part3.toInt();
      
      EEPROM.write(addressWrite, valueWrite);
      Serial.print("saved");
      Serial.print(valueWrite, DEC);
      Serial.print("to");
      Serial.print(addressWrite, DEC);
   }
   else
   {
      Serial.println("COMMAND NOT RECOGNIZED");
   }
}

chucktodd

#1
Dec 30, 2015, 11:05 pm Last Edit: Dec 31, 2015, 12:00 am by chucktodd Reason: better code
hello

may i present you with the project that i have been working on for 14 days and can't finish  :D

it is quite exhausting i worked out a great code, but still don't work i want to consult you (experienced people). on why the code isn't working :D

I'm working on a code that can simply
write an order:"read ' address of EEPROM'" in the Serial Monitor and it reads out the data in this EEPROM address and print on Serial monitor
and another order
and
write another order:"write 'address of EEPROM' 'number i want to save in'" and it saves that number into the specified EEPROM memory


and here's my code i wish you can help me with why it is not working
Code: [Select]

void setup()
{
Serial.begin(9600);
Serial.println("This code allows you to read and write from the EEPROM memory");
  /* add setup code here */

}

#include <EEPROM.h>
String command;

void loop()
{
 if (Serial.available())
 {
 char c=Serial.read();
 if (c=='\n')
 {
 parseCommand(command);
 command="";
 }
 else
 command+= c;
 }
}

void parseCommand (String com)
{
 String part1;
 String part2;
 String part3;
 part1 = com.substring(0, com.indexOf(" "));
 part2 = com.substring(com.indexOf(" ")+1);
 if(part1.equalsIgnoreCase("read"))
 {
 int addressRead = part2.toInt();
 int valueRead = EEPROM.read(addressRead);
 Serial.print("\n");
 Serial.print("ADDRESS:");
 Serial.print(addressRead, DEC);
 Serial.print("\t");
 Serial.print("VALUE:");
 Serial.print(valueRead, DEC);
 }
 else if(part1.equalsIgnoreCase("write"))
 {
 part2 = com.substring(com.indexOf(" ")+1);
 part3 = part2.substring(part2.indexOf(" "));
 String address=part2.substring(0,part2.indexOf(" "));
 int addressWrite = address.toInt();
 int valueWrite = part3.toInt();
 
 EEPROM.write(addressWrite, valueWrite);
 Serial.print("saved");
 Serial.print(valueWrite, DEC);
 Serial.print("to");
 Serial.print(addressWrite, DEC);
 }
 else
 {
 Serial.println("COMMAND NOT RECOGNIZED");
 }
}

Mahmoud,
your program works, It saves and reads bytes.  I think your problem is that you are expecting to store a integer using EEPROM.write().  EEPROM.write() stores and retrieves individual bytes.  Check out EEPROM.get(), EEPROM.put().  These two function read and write multi-byte types.

I made a little expansion of your code that shows how.  It is attached.

Chuck.
Currently built mega http server, Now converting it to ESP32.

mahmoud-saad

#2
Jan 01, 2016, 02:32 pm Last Edit: Jan 01, 2016, 02:50 pm by mahmoud-saad
thanks chuck for your help :D

actually i want to discuss something with you, i already placed EEPROM.get and EEPROM.put functions, thanks for the enriching information.

i also want to tell you that i think the problem is with the code in the void loop because i never get the message "COMMAND NOT RECOGNIZED" for any order i put with the Serial monitor. i tried to expose this error, and have put a println order to print the command string -i'm saving to- after the if new line.

and guess what, it didn't print anything as i thought :D

happy that i have been able to expose a bug, not so happy because i can't fix it :D
and here i will try attaching my 'modified' code.

would like to hear what you think.

i also downloaded the string.ino file and didn't understand it :D , i see similar stuff when using atmel studio and wrongly press debugg. i'm a bit of beginner you see. and failed to make my code appear as you did. this line is my reply edit.

void setup()
{
Serial.begin(9600);
Serial.println("This code allows you to read and write from the EEPROM memory");
  /* add setup code here */

}
#include <EEPROM.h>
String command;
void loop()
{
   if (Serial.available())
   {
      char c=Serial.read();
      if (c=='\n')
      {
         Serial.print(command);
         parseCommand(command);
         command="";
      }
      else
      command+= c;
   }
}

void parseCommand (String com)
{
   String part1;
   String part2;
   String part3;
   part1 = com.substring(0, com.indexOf(" "));
   part2 = com.substring(com.indexOf(" ")+1);
   if(part1.equalsIgnoreCase("read"))
   {
      int addressRead = part2.toInt();
      int valueRead;
      EEPROM.get(addressRead,valueRead);
      Serial.print("\n");
      Serial.print("ADDRESS:");
      Serial.print(addressRead, DEC);
      Serial.print("\t");
      Serial.print("VALUE:");
      Serial.print(valueRead, DEC);
   }
   else if(part1.equalsIgnoreCase("write"))
   {
      part2 = com.substring(com.indexOf(" ")+1);
      part3 = part2.substring(part2.indexOf(" ")+1);
      String address=part2.substring(0,part2.indexOf(" "));
      int addressWrite = address.toInt();
      int valueWrite = part3.toInt();
      
      EEPROM.put(addressWrite, valueWrite);
      Serial.print("saved");
      Serial.print(valueWrite, DEC);
      Serial.print("to");
      Serial.print(addressWrite, DEC);
   }
   else
   {
      Serial.println("COMMAND NOT RECOGNIZED");
   }
}

chucktodd

thanks chuck for your help :D

actually i want to discuss something with you, i already placed EEPROM.get and EEPROM.put functions, thanks for the enriching information.

i also want to tell you that i think the problem is with the code in the void loop because i never get the message "COMMAND NOT RECOGNIZED" for any order i put with the Serial monitor. i tried to expose this error, and have put a println order to print the command string -i'm saving to- after the if new line.

and guess what, it didn't print anything as i thought :D

happy that i have been able to expose a bug, not so happy because i can't fix it :D
and here i will try attaching my 'modified' code.

would like to hear what you think.

i also downloaded the string.ino file and didn't understand it :D , i see similar stuff when using atmel studio and wrongly press debugg. i'm a bit of beginner you see. and failed to make my code appear as you did. this line is my reply edit.
The correct way to post code for these forums is to place markup codes around your sketch.

The markup sequence is to place [ code ] (without any spaces) before your sketch,
and [ / code ] (without any spaces) after your sketch.

Your code is designed to use the Arduino Serial Monitor with Newline line termination, and 9600 baud communication rate.  Verify your 'line ending' is Newline and your baud is 9600.


Code: [Select]

void setup()
{
Serial.begin(9600);
Serial.println("This code allows you to read and write from the EEPROM memory");
  /* add setup code here */

}
#include <EEPROM.h>
String command;
void loop(){
if (Serial.available()){
  char c=Serial.read();
  if (c=='\n'){
    Serial.print(command);
    parseCommand(command);
    command="";
    }
  else command+= c;
  }
}

void parseCommand (String com) {
  String part1;
  String part2;
  String part3;
  part1 = com.substring(0, com.indexOf(" "));
  part2 = com.substring(com.indexOf(" ")+1);
  if(part1.equalsIgnoreCase("read")){
    int addressRead = part2.toInt();
    int valueRead;
    EEPROM.get(addressRead,valueRead);
    Serial.print("\n");
    Serial.print("ADDRESS:");
    Serial.print(addressRead, DEC);
    Serial.print("\t");
    Serial.print("VALUE:");
    Serial.print(valueRead, DEC);
    }
  else if(part1.equalsIgnoreCase("write")) {
    part2 = com.substring(com.indexOf(" ")+1);
    part3 = part2.substring(part2.indexOf(" ")+1);
    String address=part2.substring(0,part2.indexOf(" "));
    int addressWrite = address.toInt();
    int valueWrite = part3.toInt();
 
    EEPROM.put(addressWrite, valueWrite);
    Serial.print("saved");
    Serial.print(valueWrite, DEC);
    Serial.print("to");
    Serial.print(addressWrite, DEC);
    }
else{
  Serial.println("COMMAND NOT RECOGNIZED");
  }
}

I just compiled your code and uploaded it to a UNO,  here is the output.
What are you expecting that it is not doing?

Code: [Select]

This code allows you to read and write from the EEPROM memory
read 0
ADDRESS:0 VALUE:256read 1
ADDRESS:1 VALUE:257read 2
ADDRESS:2 VALUE:257read 3
ADDRESS:3 VALUE:257read 16
ADDRESS:16 VALUE:258helpCOMMAND NOT RECOGNIZED
write 0 25saved25to0read 0
ADDRESS:0 VALUE:25


Your code is a little ruff, but it allows you to read and write individual int values, what else do you want it to do?

I was bored yesterday.  I kind of went overboard.  Attached is my latest EEPROM access code.

Chuck.
Currently built mega http server, Now converting it to ESP32.

mahmoud-saad

I'm submitting this as an assignment. so i was testing it on the autodesk 123dcircuits online simulator, because it will be tested by the my peers to grade me there on this simulator.

maybe because the code is rough and the simulator is not like the real board it didn't work.

it used to never give me anything whatever i do the serial monitor is always blank

you can't know how i appreciate the help you did :D
thank you alot chuck.

until later when you help me again :D

Code: [Select]


thank you



just testing :D

btw what is the EEPROM access code?

chucktodd

I'm submitting this as an assignment. so i was testing it on the autodesk 123dcircuits online simulator, because it will be tested by the my peers to grade me there on this simulator.

btw what is the EEPROM access code?
I just wrote a sketch to read and write the internal EEPROM of an Arduino in multiple formats.

Chuck.
Currently built mega http server, Now converting it to ESP32.

mahmoud-saad

your code is way advanced for me to understand :D

and it don't compile too, does it know i'm a beginner  :o  ! :D


if you could help me with un-ruffing my code. first i wanna understand what ruff means and if there's a simple advice that could help me.

cattledog

#7
Jan 04, 2016, 08:13 pm Last Edit: Jan 04, 2016, 08:13 pm by cattledog
@ mahmoud-saad

I loaded the sketch you posted, and like Chuck I find that it runs to read and write integers, and outputs COMMAND NOT RECOGNIZED if you don't enter read or write with spaces between the numbers.

One problem I saw was that if you entered "write 17" it placed the value of 17 in register 17. I don't use use Strings, so I don't know what is wrong with this but i think it is repeating part2 in part3 if there is no part3.
Code: [Select]
else if(part1.equalsIgnoreCase("write")) {
    part2 = com.substring(com.indexOf(" ")+1);
    part3 = part2.substring(part2.indexOf(" ")+1);
    String address=part2.substring(0,part2.indexOf(" "));
    int addressWrite = address.toInt();
    int valueWrite = part3.toInt();


I think when Chuck calls the sketch "rough" he is referring to the formatting of the output, and what appears on one line and what appears on a new line. Go through your sketch carefully and consider where you want a new line for clarity. Currently, new commands are stacked up on the same line as previous responses.

chucktodd

your code is way advanced for me to understand :D

and it don't compile too, does it know i'm a beginner  :o  ! :D


if you could help me with un-ruffing my code. first i wanna understand what ruff means and if there's a simple advice that could help me.
Mahmoud,
 download both of the attached files.  Save them into a directory named string.  When you open string.ino, the Arduino program will load both files.  It should compile just fine.

My comment about being 'ruff' is that you can 'polish' to make it handle errors better, and validate input before storing the values.

If you format is :

command address value

You are correctly parsing the first word, but you assume the second and possibly the third word are always valid numbers.

If I pass the following command to your program it will not generate an error:

Write Write Write

What would you expect it to do?

What it actually does is preform a write of 0 to address 0. The String.toInt() attempts to convert from a text string to binary integer value.  It stops converting as soon as it encounters a non-numeric symbol. Since the first character of the second word is not - (negative) or between 0..9. The conversion aborts and returns 0.  

You only have input checking on the first 'word' of your command line.

It would be better to check each 'word' of command string.

Write a function to validate an integer.  something Like this:
Code: [Select]

bool isInt(String instr){ // an integer validation function that returns true or false
// a valid int is from -32768 to 32767  

long L; // storage for the actual value, a long can be from -2147483648..2147483647
const char * ch; // a pointer to an array of characters that cannot be changed

ch =instr.c_str(); // set ch to point to the internal instr character buffer
// ch points to an array of char. It's length is marked by a null or '\0' as the termination character.

byte b=0; // an index variable to move through the array
bool negative= false;

// the first character of the text array can be a '-' negative symbol or a digit '0..9'
if (ch[b]=='-') {
  negative == true; // found the negative marker!
  b++; // increment my index variable
}

if(ch[b]=='\0'){ // the string contained only a '-' or was empty! Not a Number
  return false;
}

while((ch[b]!='\0')&&(ch[b]>='0')&&(ch[b]<='9')){ // not at end, and is a digit
  L=L*10 + (ch[b]-48); // each time we append another digit we have multiply the prior result by 10
      // the (ch[b]-48)  converts from the symbol zero '0' to the value 0,  the ASCII code for '0' is 48.

  b++; // increment to the next index position
}

if(ch[b]!='\0') { // the string conversion was terminated by a non numeric symbol, Error!
  return false;
}


if(negative){ \\ make the value negative!
  L = L * -1
  }

// we have now converted the value to number, now we must verify it is an int (-32768..32767)

if((L<-32768L)||(L>32767L)) return false; // doesn't fit in and int
else return true; // is an int

}



Chuck.
Currently built mega http server, Now converting it to ESP32.

mahmoud-saad

Chuck, you totally rock :smiley-cool:

13 days from now i will be done with my finals. and i will go through every piece of advice and study your code carefully.

thanks for your time and effort my friend :smiley-lol:

Cattledog, thank you too for pointing things out for me.

Go Up