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 ?
-
2Please see: Why is the input modified?Benoit Blanchon– Benoit Blanchon2020年12月02日 13:53:17 +00:00Commented Dec 2, 2020 at 13:53
-
1Also, please check the error code returned by deserializeJson()Benoit Blanchon– Benoit Blanchon2020年12月02日 13:54:14 +00:00Commented Dec 2, 2020 at 13:54
-
@BenoitBlanchon Error gets "OK"guyd– guyd2020年12月02日 14:17:12 +00:00Commented Dec 2, 2020 at 14:17
2 Answers 2
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:
'0円'
are inserted at the end of each string- 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: "hello0円world0円"
.
You can find more details in the documentation
-
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 usingt2
?guyd– guyd2020年12月02日 14:20:37 +00:00Commented Dec 2, 2020 at 14:20
To sum up Benoit Blanchon answer:
in original code:
deserializeJson(DOC, _readmsg);
changes to:
deserializeJson(DOC, (const char *)_readmsg);