Laywah
Laywah

Reputation: 94

how to fix arduino variable getting extra data in callback function?

When using the mqtt callback function. I am getting extra characters and persisting characters on each run.

void callback(char* topic, byte* payload, unsigned int length) {
  unsigned long currentMillis = millis();
  const char* STATE_OPEN = "OPEN";
  const char* STATE_CLOSE = "CLOSE";
  const char* STATE_STOP = "STOP";
  char* msg = (char*)payload;

  if(strcmp(topic, "office/shutter") == 0) {
    Serial.println(msg);
    Serial.print("Message:");

    if(strcmp(msg, STATE_OPEN) == 0) {
      digitalWrite(relay2, LOW);
      digitalWrite(relay1, HIGH);
      shutterRunTime = currentMillis;
    }
    if(strcmp(msg, STATE_CLOSE) == 0) {
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, HIGH);
      shutterRunTime = currentMillis;
    }
    if(strcmp(msg, STATE_STOP) == 0) {
      digitalWrite(relay2, LOW);
      digitalWrite(relay1, LOW);
      shutterRunTime = currentMillis;
    }
  }

  Serial.println();
  Serial.println("-----------------------");
  if((currentMillis - shutterRunTime) >= shutterMaxRun) {
    digitalWrite(relay2, LOW);
    digitalWrite(relay1, LOW);
  }
  /* Clear the strings */
  memset(msg, 0, sizeof(msg));
}

if I post on mqtt CLOSE it works. if I post on mqtt OPEN, I get OPENr if it is done before CLOSE or otherwise if its after I get OPENE

I have tried to null out the variable msg and even memset doesn't work. How do I get it to just give me the value of the payload. when I do a Serial.print(length) it gives me the correct of either 4 or 5 so I am confused on whats actually happening.

Upvotes: 0

Views: 328

Answers (1)

hardillb
hardillb

Reputation: 59751

You can't just cast the byte array payload to a char array and then treat it as a string (a null terminated char array)

When you call Serial.println(msg) println has no idea how long string is so will continue to read until it hits the first null it finds in memory. So far it sounds like you have got lucky and it's only been 1 or 2 bytes after the actual length of the incoming payload byte array.

If you want a string that just contains the payload, you should malloc a new char array that is length + 1 and make sure the last char in the new array is set to 0 (null).

You should probably include the null terminator in your const strings as well that way strcmp will work properly as well.

Upvotes: 3

Related Questions