I am having a problem with the serial monitor on Arduino Uno.
Basically I want to write some commands on the Serial Monitor, read the string and according to the string do something.
The problem is the following: supposing I type the command 'read 4' in the Serial Monitor, sometimes the string is read correctly, sometimes it is read like: 'ead 4', missing the first character. I even put a delay between two readings from the Serial Monitor. Does anyone have an explanation?
For completeness I post my code (basically it reads/writes from/to the EEPROM: for example 'read 5' will read the 5 block of EEPROM, 'write 4 5' will write the value 5 to the 4th block of memory).
#define MAX_STRING_LENGTH 14
#include <ctype.h>
#include <EEPROM.h>
//The function initializes the string to spaces
void initString(char* mystr, char strLength);
//The function returns true if it is a read operation, false otherwise
boolean isReadEEPROM(char *myStr, char strLength);
//The function returns true if it is a write operation, false otherwise
boolean isWriteEEPROM(char *myStr, char strLength);
//The function returns the EEPROM address from the string
unsigned int findAddress(char *myStr, char strLength);
char findValue(char *myStr, char strLength);
//Check the address range
boolean isAddressOk(unsigned int address);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
}
void loop() {
char pos = 0;
bool newDataFound = false;
char serialStr[MAX_STRING_LENGTH];
unsigned int address = 0;
char val = 0;
while(Serial.available()){
val = Serial.read();
}
val = 0;
initString(&serialStr[0], (char) MAX_STRING_LENGTH);
while(Serial.available() && pos < MAX_STRING_LENGTH){
serialStr[pos] = Serial.read();
pos ++;
newDataFound = true;
delay(200);
}
if (newDataFound){
Serial.print("New Command found: ");
Serial.println(serialStr);
address = 0;
address = findAddress(&serialStr[0], MAX_STRING_LENGTH);
if (isReadEEPROM(&serialStr[0], MAX_STRING_LENGTH) && isAddressOk(address)){
Serial.println("Reading from EEPROM");
Serial.print("Address is ");
Serial.println(address);
val = EEPROM.read(address);
Serial.print("Value is: ");
Serial.println( (uint8_t) val );
Serial.println(" ");
}
else if (isWriteEEPROM(&serialStr[0], MAX_STRING_LENGTH) && isAddressOk(address)){
Serial.println("Writing to EEPROM");
Serial.print("Address is ");
Serial.println(address);
Serial.println(" ");
val = findValue(&serialStr[0], MAX_STRING_LENGTH);
EEPROM.write(address, val);
}
else{
if (!isAddressOk(address)){
Serial.write(address);
Serial.println("Address out of range");
Serial.println("");
}
Serial.println("Not recognized operation\n");
}
delay(2000);
}
}
void initString(char* mystr, char strLength){
for(char ii=0; ii<strLength; ii++){
(*mystr) = ' ';
mystr++;
}
}
//The function returns true if it is a read operation, false otherwise
boolean isReadEEPROM(char *myStr, char strLength){
//The string should contain first the 'read' operation
char expected[] = "read";
int ii =0;
while (ii<4){
if ( *(myStr + ii) != expected[ii]){
return false;
Serial.println("Not a Read Operation\n");
}
ii++;
}
return true;
Serial.println("Read Operation");
}
//The function returns true if it is a write operation, false otherwise
boolean isWriteEEPROM(char *myStr, char strLength){
//The string should contain first the 'read' operation
char expected[] = "write";
int ii =0;
while (ii<5){
if ( *(myStr + ii) != expected[ii]){
return false;
}
ii++;
}
return true;
}
//The function returns the EEPROM address from the string
unsigned int findAddress(char *myStr, char strLength){
unsigned int address;
char tmpStr[strLength];
char strAddress[] = " ";
int ii = 0;
while(ii< strLength){
tmpStr[ii] = *(myStr+ii);
ii++;
}
Serial.print("The address found is: ");
Serial.println(strAddress);
ii= 0;
if (isReadEEPROM(myStr, strLength)){
while (ii<=4){
if (isdigit(*(myStr + 5 + ii))){
strAddress[ii] = *(myStr + 5 + ii);
}
else{
break;
}
ii++;
}
address = atoi(strAddress);
}
else if(isWriteEEPROM(myStr, strLength)){
while (ii<=4){
if (isdigit(*(myStr + 6 + ii))){
strAddress[ii] = *(myStr + 6 + ii);
}
else{
break;
}
ii++;
}
address = atoi(strAddress);
}
else{
address = 0;
//Serial.println("Address not available in function 'findAddress'");
}
return address;
}
//The function returns the value to be written to the EEPROM from the string
char findValue(char *myStr, char strLength){
char val;
char tmpStr[strLength];
char strVal[] = " ";
int ii, idx = 0;
while(ii< strLength){
tmpStr[ii] = *(myStr+ii);
ii++;
}
ii= 0;
// first found the first digits corresponding to the address
while (ii<=4){
if (isdigit(*(myStr + 6 + ii))){
;//strAddress[ii] = *(myStr + 6 + ii);
}
else{
ii++;
break;
}
ii++;
}
// now find the value
while (ii<=4+3){
Serial.println(*(myStr + 6 + ii));
if (isdigit(*(myStr + 6 + ii))){
strVal[idx] = *(myStr + 6 + ii);
}
else{
break;
}
ii++;
idx++;
}
Serial.print("original string: ");
Serial.println(tmpStr);
Serial.print("Value found: ");
Serial.println(strVal);
val = (char)atoi(strVal);
return val;
}
boolean isAddressOk(unsigned int address){
if (address < 1024 && address >= 0){
return true;
}
else{
return false;
}
}