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
  • 2
    Please see: Why is the input modified? Commented Dec 2, 2020 at 13:53
  • 1
    Also, please check the error code returned by deserializeJson() Commented Dec 2, 2020 at 13:54
  • @BenoitBlanchon Error gets "OK" Commented Dec 2, 2020 at 14:17

2 Answers 2

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 ? Commented Dec 2, 2020 at 14:20
0

To sum up Benoit Blanchon answer:

in original code:

deserializeJson(DOC, _readmsg);

changes to:

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.