Wierd Serial Read result!! I don't know why this doesn't work!! (EEPROM)

Hi All,

I try to use following code to control the "read" and "write" of EEPROM.

Basically, I want to be able to type "write 3 10" in the serial monitor and save number 10 into the location 3 of EEPROM and when I type "read 3" it should print out 10 (the number that store in location 3).

My code compiled well but it runs funny...

I am able to store the "read" "location" and "number" into different variables and convert them into string, int, int, respectively.

However, the part with read & writing into EEPROM doesn't go well!!

Somehow the program cannot store the number into correct location and that after I type in "write 10 12" (for example), the next time I type "read 10", the Serial print gives me "reade 10" instead of "read 10". Also, it cannot get the correct number back.

I just cannot see what has gone wrong with my code. I imaging its some problem with the start/end of the serial read or some problem with the leftover serial input.

Thanks in advance for any suggestions! :slight_smile: :slight_smile: :slight_smile:

#include <EEPROM.h>

char commend[20];
char rw[20];
char location[20];
char number[20];
int l;
int n;
String RW;
int value;

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

void loop() {

if (Serial.available() > 0)
{
Serial.readBytesUntil(' ',rw, 20);
Serial.readBytesUntil(' ',location, 20);
Serial.readBytesUntil(' ',number, 20);
Serial.println(rw);
Serial.println(location);
Serial.println(number);
int l = atoi(location);
int n = atoi(number);
RW = String(rw);
Serial.println(l);
Serial.println(n);

}

if (RW == "read"){
value = EEPROM.read(l);
Serial.println(value);
}

if (RW == "write"){
EEPROM.write(l,n);

}

Serial.println(rw);
Serial.println(location);
Serial.println(number);

Anonymous printing sucks. Print some identifiers before and after these "strings" and you will see that they are NOT strings. A string is a NULL terminated array of chars. These arrays are NOT NULL terminated.

Hi Paul,

Thanks for your fast reply!

Do you know how I can fix this?

Do you know how I can fix this?

Yes. Look at the documentation for the readBytesUntil() function. It returns the number of bytes actually placed in the array. Add a NULL to the array, after that number of bytes.

  byte byteCount = Serial.readBytesUntil(' ',rw, 20);
  nw[byteCount] = '\0';

Thanks Paul!

I'll try it out tonight and see how it goes!

Does other parts of my code looks okay?

Do you think this is the only issue with my code?

Does other parts of my code looks okay?

Except for the use of the String class, yes.

Do you think this is the only issue with my code?

If you go to the doctor with a hangnail on you middle finger, after nearly cutting you are off in a chainsaw accident, do you think the doctor is going to treat the hangnail?

Fix the obvious, major, issues first.

Got it! Thanks again, Paul!

Hi Paul,

I have changed my code to the following and still doesn't work~

#include <EEPROM.h>

char commend[20];
char rw[20];
char location[20];
char number[20];
int l;
int n;
String RW;
int value;
int byteCount1;
int byteCount2;
int byteCount3;

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

void loop() {

while(!Serial.available()) ;
if (Serial.available() > 0)
{
Serial.readBytesUntil(' ',rw, 20);
byteCount1 = Serial.readBytesUntil(' ',rw, 20);
rw[byteCount1] = '\0';
Serial.readBytesUntil(' ',location, 20);
byteCount2 = Serial.readBytesUntil(' ',location, 20);
location[byteCount2] = '\0';
Serial.readBytesUntil(' ',number, 20);
byteCount3 = Serial.readBytesUntil(' ',number, 20);
number[byteCount3] = '\0';
int l = atoi(location);
int n = atoi(number);
RW = String(rw);
Serial.println(RW);
Serial.println(l);
Serial.println(n);
}

if (RW == "read"){
value = EEPROM.read(l);
Serial.println(value);
}

if (RW == "write"){
EEPROM.write(l,n);
}

}

I have changed my code to the following and still doesn't work

The code does something. It gets some data and prints some data to the serial port. I do not think it is unrealistic for us to expect you to explain what it does and show what it prints.

PaulS:
The code does something. It gets some data and prints some data to the serial port. I do not think it is unrealistic for us to expect you to explain what it does and show what it prints.

Hi Paul,

I tried the following code, but now when I type "write 12 10", instead of giving me:

Write
12
10

It gives me:
12
0
0

And when I type "read 12"

It still gives me:

12
0
0

Please let me know what I did wrong. Thanks!

#include <EEPROM.h>

char commend[20];
char rw[20];
char location[20];
char number[20];
int l;
int n;
String RW;
int value;
byte byteCount1;
byte byteCount2;
byte byteCount3;

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

void loop() {

while(!Serial.available()) ;
if (Serial.available() > 0)
{
Serial.readBytesUntil(' ',rw, 20);
byte byteCount1 = Serial.readBytesUntil(' ',rw, 20);
rw[byteCount1] = '\0';
Serial.readBytesUntil(' ',location, 20);
byte byteCount2 = Serial.readBytesUntil(' ',location, 20);
location[byteCount2] = '\0';
Serial.readBytesUntil(' ',number, 20);
byte byteCount3 = Serial.readBytesUntil(' ',number, 20);
number[byteCount3] = '\0';
int l = atoi(location);
int n = atoi(number);
RW = String(rw);
Serial.println(RW);
Serial.println(l);
Serial.println(n);
}

if (RW == "read"){
value = EEPROM.read(l);
Serial.println(value);
}

if (RW == "write"){
EEPROM.write(l,n);
}

}

Serial.readBytesUntil(' ',rw, 20);
  byte byteCount1 = Serial.readBytesUntil(' ',rw, 20);
  rw[byteCount1] = '\0';
Serial.readBytesUntil(' ',location, 20);
  byte byteCount2 = Serial.readBytesUntil(' ',location, 20);
  location[byteCount2] = '\0';
Serial.readBytesUntil(' ',number, 20);
  byte byteCount3 = Serial.readBytesUntil(' ',number, 20);
  number[byteCount3] = '\0';

Read everything until a space appears. Put that in rw, so rw contains "write".

Then, read everything until another space appears, and put that in rw, so rw contains "10", but this time count the bytes so you can NULL terminate the string.

Can you see that that way lies madness?

Got it. You mean I shouldn't do the serial.readbyteUntil() twice?

Hi Paul,

Thanks many for your advice!

I have changed my code to the following. Now, when I type "write 12 10"

it prints:

write
12
10

But when I type "read 12"

It gives me:

read
12
0
0

It seems that it still cannot save the number 10 into position 12.

Do you know why?

Thanks!!!

#include <EEPROM.h>

char commend[20];
char rw[20];
char location[20];
char number[20];
int l;
int n;
String RW;
int value;
byte byteCount1;
byte byteCount2;
byte byteCount3;

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

void loop() {

while(!Serial.available()) ;
if (Serial.available() > 0)
{
byte byteCount1 = Serial.readBytesUntil(' ',rw, 20);
rw[byteCount1] = '\0';
byte byteCount2 = Serial.readBytesUntil(' ',location, 20);
location[byteCount2] = '\0';
byte byteCount3 = Serial.readBytesUntil('\n',number, 20);
number[byteCount3] = '\0';
int l = atoi(location);
int n = atoi(number);
RW = String(rw);
Serial.println(RW);
Serial.println(l);
Serial.println(n);
}

if (RW == "read"){
value = EEPROM.read(l);
Serial.println(value);
}

if (RW == "write"){
EEPROM.write(l,n);
}

}

#include <EEPROM.h>

char commend[20];
char rw[20];
char location[20];
char number[20];
int l;
int n;
String RW;
int value;
byte byteCount1;
byte byteCount2;
byte byteCount3;

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


void loop() {

while(!Serial.available()) ;
if (Serial.available() > 0)
  {
  byte byteCount1 = Serial.readBytesUntil(' ',rw, 20);
  rw[byteCount1] = '\0';
  byte byteCount2 = Serial.readBytesUntil(' ',location, 20);
  location[byteCount2] = '\0';
  byte byteCount3 = Serial.readBytesUntil('\n',number, 20);
  number[byteCount3] = '\0';  
int l = atoi(location);
int n = atoi(number);
RW = String(rw);
Serial.println(RW);
Serial.println(l);
Serial.println(n);
}


if (RW == "read"){
value = EEPROM.read(l);
Serial.println(value);
}

if (RW == "write"){
EEPROM.write(l,n);
}

}

It really is not hard to post using code tags. The redeclaration of l and n within the serial input block has them at 0 value in the read/write blocks.

//int l = atoi(location);
//int n = atoi(number);

 l = atoi(location);
 n = atoi(number);

Hi Paul,

Sorry for not posting with the code tag~ I am completely new to Arduino & this forum so didn't notice that. Will do in future.

So what you said is that I should put the converting code out of the Serial block to solve the problem?

I will try it and let you know how it goes!

Thank you!

So what you said is that I should put the converting code out of the Serial block to solve the problem?

No. Just don't redeclare l and n. They are already globals.

Hi Paul,

Now it works! thanks a million!!

Hi Cattledog,

It seems that when I move the converting out from the block. The code works perfectly. I will try without redeclaring l and n to see how it goes later.