0

I would like to convert a byte *payload to a String, because I want to compare the content of payload to another String.

void mqttCallbackHandler(char *topic, byte *payload, unsigned int length) {
  String payloadstr = ???
  ...
}
4

Depending on what is setting the message on the topic, payload may, or may not be, a NULL-terminated string. This is why they provide the length parameter.

You could consider comparing the data with memcmp() which is like strcmp() but doesn't look for a NULL termination - instead it takes a length parameter. This is good if you may have NULL bytes in your payload.

An alternative is strncmp() which both looks for a NULL termination and also limits the length using a length parameter. Better for payloads you know are strings, but you aren't sure if they have NULL termination or not.

Here is a callback (for PubSubClient on ESP8266) I have in one of my projects which uses strncmp():

void callback(char *topic, byte *payload, unsigned int length) {
    if (!strcmp(topic, SUBTOPIC)) {
        if (!strncmp((char *)payload, "on", length)) {
            digitalWrite(POWERPIN, HIGH);
            powerState = true;
            client.publish(PUBTOPIC, "on", true);
        } else if (!strncmp((char *)payload, "off", length)) {
            digitalWrite(POWERPIN, LOW);
            powerState = false;
            client.publish(PUBTOPIC, "off", true);
        }
    }
}

Simply casting your payload to (char *) is enough for the functions to take it as a string, and the length parameter will prevent looking past the end of the payload if there is no NULL termination.

It's not perfect - a single byte payload of o will falsely match the first on, but if that is a critical problem I am sure you can find a way to work around it by checking what length equals.

2

Consider simply using the returned pointer.

Payload is a pointer of type byte. You can compare each byte in a string to the byte the pointer is pointing at. Then increment the pointer to the next byte and repeat the process. You don't need to allocate more memory for new string.

If a type string is necessary. For example, if you were using a complex library method which requires a string to be passed to it, you could copy what the returned pointer is pointing at byte by byte into a locally defined string.

2

For comparing a byte array to a String object, you could convert the byte array to another String object, but this involves dynamically allocating memory for a whole copy of the string. This is memory unfriendly, and preferably avoided on small microcontrollers.

The cheapest way to achieve what you want is to compare them as character arrays :

if (strcmp((char *) payload, theReferenceString.c_str()) == 0) {
    // the strings are equal
}

strcmp() is a standard C function that does the byte by byte comparison, exactly as suggested by st2000.

  • what if the payload string is not terminated with zero? – Juraj Aug 5 '18 at 8:45
  • @Juraj: then memcmp(). – Edgar Bonet Aug 5 '18 at 8:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.