String variable removes last character in ESP32

I wrote an application for receiving and sending MQTT messages to control inputs and outputs and have a strange issue. I have this working on a ESP8266 but am trying to port to a ESP32 board. In the following code, the String str_msg = String(message); truncates the last letter from the payload. It displays the payload correctly but when I try to store the payload for comparison in a series of "If" statements, the last letter is missing. If I remove the last letter in the "If" statements the code works. I am trying to get this working properly with both environments so I want this to be the same if possible. This is in an mqttCallback function. The serial output that shows this occurring is as follows; code after that. Any thoughts?

Message arrived on Topic:
mylayout/to/0001/13
CLOSED
CLOSE

Message arrived on Topic:
mylayout/to/0001/14
CLOSED
CLOSE

The codes is as follows:

//Prints Message to Display and performs actions based on message and payload
  char message[5]={0x00};
  for (int i=0; i<length; i++) {
  message[i]=(char)payload[i];
  message[length]=0x00;
  }
  Serial.println (message);
  display.setTextSize(2);
  display.setCursor(0,40);
  display.println(message);
  display.display();
  String str_msg = String(message); //This appears to be the problem line
  Serial.println(str_msg);

  if (strcmp(topic, RECTOP01) == 0) {
    if(str_msg.equals ("THROWN")) {
    digitalWrite(RELAY01, HIGH);
 }else if (str_msg.equals("CLOSED")) {
   digitalWrite(RELAY01, LOW);
 }
 }

How does this even compile since length is not defined.
Anyways if length is someplace else in your code make it one larger for the null character.

Change it like this:

char message[length+1]={0x00};
1 Like

Hi @hykv4ster ,
Welcome to the forum..
message is to small..

that's 5 chars, you need at least 7 the extra is for the ending null..

good luck.. ~q

Or simplify it like this:

//Prints Message to Display and performs actions based on message and payload
  String str_msg;
  for (int i=0; i<length; i++) {
    str_message += (char)payload[i];
  }
  display.setTextSize(2);
  display.setCursor(0,40);
  display.println(str_msg);
  display.display();
  Serial.println(str_msg);

  if (strcmp(topic, RECTOP01) == 0) {
    if(str_msg == "THROWN") {
      digitalWrite(RELAY01, HIGH);
    }
    else if (str_msg == "CLOSED") {
      digitalWrite(RELAY01, LOW);
    }
  }

Thank you! First one solved it but I am going to try this slimmed down version. Interesting that it worked on the ESP8266 with me putting the wrong size in for the array; go figure...

Just luck.

More likely to be lucky with ESP8266 (80KB of dynamic memory) versus Uno/Nano (2KB).

1 Like

To me, this is the interesting part. It's like the String() function is saying "hang on, message is only 5 chars long, so I will stop reading after 5 even if I have not found the null-terminator yet".

Another way:

//Prints Message to Display and performs actions based on message and payload
  char message[length+1]={0x00};
  for (int i=0; i<length; i++) {
    message[i]=(char)payload[i];
  }
  message[length]=0x00;
  
  Serial.println (message);
  display.setTextSize(2);
  display.setCursor(0,40);
  display.println(message);
  display.display();

  if (strcmp(topic, RECTOP01) == 0) {
    if(strcmp(message, "THROWN") == 0) {
      digitalWrite(RELAY01, HIGH);
    } else if (strcmp(message, "CLOSED") == 0) {
      digitalWrite(RELAY01, LOW);
    }
  }

And it was displaying the entire payload even though I had the array limited to 5.

No, you had only allocated 5 chars. There is no "limited to". When using strings, C/C++ will simply continue to write or read more memory until it finds the null-terminator. Writing into that unallocated memory can cause all kinds of bizarre side effects, and C/C++ does nothing to protect you from that kind of error.

EDIT: I didn't mean to sound brutal with you. C/C++ is brutal like that.

Welcome to the forum

As your post does not relate directly to the Nano ESP32 board it has been moved to a more generic forum category

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