Read and compare string form serial port

     cmdBuffer[0] = 0;

Before doing this, you want to copy this data to another array (strcmp() or memcmp()).

Then, this:

     if (strcmp("6047078288", cmdBuffer) == 0)

looks like where you want to compare cmdBuffer to the last command.

If you have two static arrays:

 static char cmdBuffer[CMDBUFFER_SIZE] = "";
 static char oldBuffer[CMDBUFFER_SIZE] = "";

Then, after populating cmdBuffer, you can compare that to oldBuffer:

     if (strcmp(oldBuffer, cmdBuffer) != 0)

and do what needs when they are different.

Finally, copy the current command as the old command, and reset the current command:

   strcpy(oldBuffer, cmdBuffer);
   cmdBuffer[0] = '\0';

Okay , I see exactly what you mean.
But suddenly I have to take into account that the first reading my oldbuffer will be empty , so to avoid that there is an action to first reading I must say that the buffer 2 takes the value of buffer 1 ?

But suddenly I have to take into account that the first reading my oldbuffer will be empty , so to avoid that there is an action to first reading I must say that the buffer 2 takes the value of buffer 1 ?

I don't see why. The first time data arrives, it is different from what was already known, right? Shouldn't you take action when the data is different?

Or, is the idea to do something only when you have two values and they are different?

When it will read the first sequence . cmdBuffer = sequence and oldbuffer = empty , so it will trigger an action. If I do not want it triggers the first time , I have to say that the cmdBuffer = OldBuffer first time

Or does not depend on the starting content of the buffer.

If I do not want it triggers the first time , I have to say that the cmdBuffer = OldBuffer first time

Or, skip the comparison if the old buffer is empty (strlen() returns 0).

PaulS:
Or, skip the comparison if the old buffer is empty (strlen() returns 0).

Happy Easter

Okay I'll try that .I put my function if the buffer is empty when I return 0 before reading the characters .

I come to you to thank you for the help you bring me , I could finally implement what I needed your help, I continued my project that is doing well . thank you

/* simple modification to remove all errors... 100% working*/

String inputString = "";
char c;

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

void loop()
{
while (Serial.available())
{
c = (char)Serial.read();
inputString += c;
}
if (inputString == "Ping")
{
Serial.println("Ok");
Serial.flush();
}
}

If you now would have had the decency to use code tags when you kicked a eight-or-so months old thread, we would maybe accept the fact that you use String (with capital S).

Yes, String is simple to use; and yes, String can leave holes in your memory and can cause all kinds of memory issues.

Can use this code to compare strings...

int ledPin = 13;
String readString;

void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
Serial.println("serial on/off test led pin 13");
}

void loop() {

while (Serial.available()) {
delay(3);
char c = Serial.read();
readString += c;
}
readString.trim();
if (readString.length() >0) {
if (readString == "on"){
Serial.println("switching on");
digitalWrite(ledPin, HIGH);
}
if (readString == "off")
{
Serial.println("switching off");
digitalWrite(ledPin, LOW);
}
if (readString == "A1")
{
Serial.println("eso es todo");
digitalWrite(ledPin, HIGH);
delay(1000);
digitalWrite(ledPin, LOW);

}

readString="";
}
}

ryucond:
Can use this code to compare strings...

It is not a good idea to use the String (capital S) class on an Arduino as it can cause memory corruption in the small memory on an Arduino. This can happen after the program has been running perfectly for some time. Just use cstrings - char arrays terminated with '\0' (NULL).

...R

Hello,

Have been reading a lot in these threads, but i can't get a clean start with my little project...
So maybe you can help.

I have a device that generates a string that holds timing info, every second.
i want to use this info to signal a light, buzzer or even display it on LCD or something.

With a serial port monitoring program i got this :
Data : 41 30 30 30 30 0d ==> Character info A0000.
Data : 41 30 30 30 31 0d ==> Character info A0001.
Data : 41 30 30 30 32 0d ==> Character info A0002.
Data : 41 34 34 35 39 0d ==> Character info A4459.

So you can read the for characters as time 00:00 to 44:49.

But so far, i've been unsuccesfull...

How can i get those 4 bytes as a value (separate) so i can process them ?

#define array_length 6

byte myArray[array_length];
int i;

void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available() > 0) {
  
  for (i = 0; i < array_length; i++) {
    myArray[i] =  Serial.read();
  }
 Serial.flush();
 
  for (i = 0; i < array_length; i++) {
    Serial.print("Value");
    Serial.print(i);
    Serial.print("=");
    Serial.print(myArray[i]);
    Serial.println();
   }
    Serial.println();
  }
 delay (50);
 // do something, calculate or display.
}

I hope you can push me in the right direction.
Thanks, Nick

Take a look at: Serial Input Basics - updated / Example 3
change startMarker and endMarker to your needs:

char startMarker = 0x41;
char endMarker = 0x0d;

and you will get 4459 (from your "test data" 4) in receivedChars.

If you like to get "minutes" and "seconds" as seperate there are several ways.
Something like this would do the job:

int myMinutes = 10 * (receivedChars[0] - '0') + (receivedChars[1] - '0');
int mySeconds = 10 * (receivedChars[2] - '0') + (receivedChars[3] - '0');
Serial.println(myMinutes);
Serial.println(mySeconds);

Hi there,

After some testing and reading (ahum), i found that one mistake were levels.
(TTL to RS232 convertor did the trick)

But my problem is stil not (completely) resolved.

If i use this i get the correct info :

char value;

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

}

void loop() {
  
while (Serial.available() > 0 ){

  value = Serial.read();
    Serial.println(value);
  }
  //Serial.println();
}

But if i use this :

// A1000 (time is 10:00)
// A0959 (time is  9:59)
// A0958 (time is  9:58)
//----------------------------

#define array_length 6

byte myArray[array_length];
int i;

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

void loop() {
  if (Serial.available() > 0) {
 
  for (i = 0; i < array_length; i++) {
    myArray[i] =  Serial.read();
  }
 
  for (i = 1; i < 5; i++) {
    Serial.print("Value");
    Serial.print(i);
    Serial.print("=");
    Serial.print(myArray[i]-48);
    Serial.println();
   }
    Serial.println();
  }
 delay (50);
 // do something, calculate or display.
}

Most of the time i get correct info, but there are glitches.
I can't be a timing issue, right ? I mean, it's only 9600 Baud.

Error values are constantly 207 or -35. (on different array positions)

Like :

Value1=1
Value2=0
Value3=0
Value4=0

Value1=0
Value2=9
Value3=5
Value4=9

Value1=0
Value2=9
Value3=5
Value4=8

Value1=207
Value2=207
Value3=207
Value4=207

Value1=0
Value2=9
Value3=5
Value4=6

Value1=-35
Value2=9
Value3=5
Value4=5

What could this be ?

Keep in mind that serial communication is pretty s___l___o___w. :slight_smile:
So it takes quite a long time until (all) characters of a serial message are received.

In your code you try to read 6 characters (array_length) whenever there is one (or more) characters received. This may not work properly in most cases, because there are less than 6 characters available (at this time).

Try to read and understand the code in Serial Input Basics - updated / Example 3 as mentioned in #32
The code there shows reliable ways of reading serial messages.
I use this kind of code in many of my own projects with success.

Thanks, did some reading and i tried another function, "Serial.readBytesUntil".
This seems to work much better. :slight_smile:

char buffer[6];

int myMinutes;
int mySeconds;

void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);
}

void loop() {

 while(!Serial.available());
 int size = Serial.readBytesUntil('\n', buffer, 6);
 
 for (int i = 0 ; i < size ; i++) {
// debug to screen, to see what was received
   Serial.print(buffer[i], HEX);
   Serial.print(",");
 } 
  Processing_Data();
}

void showNewData() {
        Serial.println();
        Serial.print(myMinutes);
        Serial.print(" - ");
        Serial.print(mySeconds);
        Serial.println();
}

void Processing_Data(){
    // convert ascii to separate variables
  
  int myMinutes = (10 * (buffer[1] - '0') + (buffer[2] - '0'));
  int mySeconds = (10 * (buffer[3] - '0') + (buffer[4] - '0'));
  
  showNewData();
  }

void Write_to_Display(){
  // write to external display and test for leading zero's.
    
  }

Only the output for the conversion is '0' and '0' (zero)
This remains an issue for me.

Also code doen't work :

digit_1={atoi(buffer[1])};  // digit #1 on large display (=ten minutes indicator)
digit_2={atoi(buffer[2])};  // digit #2 on large display (=one minute indicator)
digit_3={atoi(buffer[3])};  // digit #3 on large display (=ten second indicator)
digit_4={atoi(buffer[4])};  // digit #4 on large display (=one second indicator)

How to easy convert an ASCII character to int ?

BR,
Nick

nicknl:
Only the output for the conversion is '0' and '0' (zero)
This remains an issue for me.

How to easy convert an ASCII character to int ?

Change

void Processing_Data(){
    // convert ascii to separate variables
 
  int myMinutes = (10 * (buffer[1] - '0') + (buffer[2] - '0'));
  int mySeconds = (10 * (buffer[3] - '0') + (buffer[4] - '0'));
 
  showNewData();
  }

to

void Processing_Data(){
   // convert ascii to separate variables

  myMinutes = (10 * (buffer[1] - '0') + (buffer[2] - '0'));
  mySeconds = (10 * (buffer[3] - '0') + (buffer[4] - '0'));
 
  showNewData();
}

Otherwise you have 2 "versions" of variables "myMinutes" and "mySeconds". The global ones, declared at the top of the setch, and local variables in function "Processing_Data". Local variables are only visible to the function in which they are declared.

Further reading: Variable Scope

Thank you very much, @uxomm !

It works, i made a small modification so i have values for each digit.

digit_1 = (buffer[1] - '0');   // ten minute digit
digit_2 = (buffer[2] - '0');   // one minute digit
digit_3 = (buffer[3] - '0');   // ten second digit
digit_4 = (buffer[4] - '0');   // one second digit

With these values i can now adress each digit of the display.
(want to control a four digit electromechanical display)

That's the next challenge.... :wink:

BR,
Nick

Good to hear that it is working now.
Good luck with the next challenge!

If you see numbered variables, it's time to think about arrays. Something like below.

int digit[4];
byte buffer[6];

for (uint8_t cnt; cnt < sizeof(digit) / sizeof(digit[0]); cnt++)
{
  digit[cnt] = buffer[cnt + 1] - '0';
}