1

I'm using RF24 library to send messages between 2 MCU's : 1) ESP8266 (no Wifi, same code can be compiled to any Arduino board) 2) pro-Micro.

Message is sent in JSON format, while using ArduinoJSON library to serialize and deserialize messages.

Altough entire code works as expected, I get an error in "RFread" function, which _readmsg array loses its content after using deserializeJson.

Attached below relevant part of "RFread" function. Explanations in code below. Please notice "Mark [X]" in code and Serial output:

char _readmsg[32];                                <---- Storing input in this array
    char t2[32];                                  <---- variable to clone value
    radio.read(&_readmsg, sizeof(_readmsg));      <---- getting RF input and store it in `_readmsg`
    strcpy(t2, _readmsg);                         <---- cloning, part of error seeking

    Serial.print("first: ");                      <---- printing initial value stored. OK. marked [A] in Serial output
    Serial.println(_readmsg);
    Serial.print("duplicate: ");                  <---- printing clone. OK. marked [B] in Serial output
    Serial.println(t2);
    
    if (key != nullptr)                           <--- check if "msg" key was sent in message
    {
      StaticJsonDocument<80> DOC;
      deserializeJson(DOC, _readmsg);             <---- **error beyond this point**
      Serial.print("second: ");
      Serial.println(_readmsg);                   <---- printing wrong value. marked [C] in Serial output

      if (DOC.containsKey(key))
      {
        const char *outmsg = DOC[key];
        if (out != nullptr)
        {
          strcpy(out, outmsg);
          return true;
        }
      }
      else
      {
        Serial.print("third: ");               
        Serial.println(_readmsg);              <---- still error. marked [D] in Serial output
        Serial.print("duplicate2: ");
        Serial.println(t2);                    <---- clone variable is OK. marked [E] in Serial output
        strcpy(out, t2); // if key not present, return entire message
        return 0;
      }

and in Serial port:

message sent OK   <---- irrelevant for debug 

15:18:14.934 -> first: {"id":"Port","msg":"fff"}       <----[A] 

15:18:14.934 -> duplicate: {"id":"Port","msg":"fff"}   <----[B]

15:18:14.934 -> second: id                             <----[C]

15:18:14.934 -> third: id                              <----[D]

15:18:14.934 -> duplicate2: {"id":"Port","msg":"fff"}  <----[E]

15:18:14.934 -> Error. no such key. got reply: {"id":"Port","msg":"fff"}

Is there a reason for that ? is it a bug ?

3
4

When you pass a char* input to deserializeJson(), it alters the input to avoid making useless copies.
This is the "zero-copy" mode of ArduinoJson.

In this mode, the JSON parser modifies the input in-place. The following modifications are performed:

  1. '\0' are inserted at the end of each string
  2. Escaped special characters (like \n) are unescaped

Example:

char[] json = "{\"hello\":\"world\"}";
deserializeJson(doc, json);

After executing the line above, the input variable probably contains something like: "hello\0world\0".

You can find more details in the documentation

1
  • Thank you for your reply - I don't understand why _readmsg changes ( as a concept ). Whould you recommend to clone that variable as I did using t2 ? – Guy . D Dec 2 '20 at 14:20
0

To sum up Benoit Blanchon answer:

in original code:

deserializeJson(DOC, _readmsg);

changes to:

deserializeJson(DOC, (const char *)_readmsg); 

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.