Curious Serial.print behaviour with a string

I am at a loss, the strings() are new to me, and I am getting some confusing results, my aim is to receive a message from a serial port, then generate a checksum to compare with that of the incoming message.

The code below only receives a message and generates a checksum, the checksum function works and is tested.

The bit that is odd is the Serial.print(msg), it prints out the hex for the received chars rather then their representation e.g. 'A' prints as 65... why?

String msg;
void setup() {Serial.begin(57600); Serial.print("send a message...");}
void loop() 
{
  msg="";
  if (Serial.available())
   {
      while (Serial.available() > 0) {msg += Serial.read();Serial.println(msg);}
      Serial.print("msg= ");
      Serial.print(msg);// ***<---- this line is the problem!***
      Serial.print("checksum=");
      Serial.print(generate_checksum(msg), HEX);
      Serial.println();
   }
}

byte generate_checksum(String this_string)
{
  int num = this_string.length()-1;
  byte XOR = 0;
  for(int i=0; i<(num); i++){XOR = XOR ^ (this_string.charAt(i)*i);}
  return XOR;
}

sample output in response to 123
49
4950
495051
49505110
msg= 49505110checksum=C4

Thanks in advance

Ian

The issue lies here, changed Serial.read to Serial.readString, and the issue goes away.

result :slight_smile:

No, it's printing the decimal representation for the ASCII character. I.E., key "1" = decimal 49. If you want the numeric representation, subtract 40 ("0").

1 Like

There are some problems with your arithmetic. 49 - 40 = 9 but not 1.
We should subtract 0x30 (hexadecimal) or 48 (decimal).

1 Like

Hi Gents, thanks for you replies, they are correct and would work if the incoming data was only numeric, however it is mixed... an example would be: @T1625003730; i.e a command setting the internal clock

So the above solution works just fine, in reality the messages never get printed out/displayed, they are fed to an interpreter which acts upon correctly formatted and checksum blessed messages

Thanks for your comments

Ian

Fat fingers

Simple. If the character is >57 or < 40, do nothing. Else subtract 48.

The underlying problem is that Serial.read() returns an int NOT a char
So when you go to print it OR add it to a String it is treated as a int and printed and added as such.
this works

int i = Serial.read();
msg += (char) i;  
Serial.println( char) i);

My Arduino Software Solutions tutorial as various sketches for reading from Serial, with their pros and cons.

3 Likes

Looks like I have some learning and reading to do... thanks for the link and sharing your knowledge

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.