I’m using SparkJson and ran into an issue where the buffer size required may be too large for the Photon (when I set it somewhere above 3284 the Photon starts to flash red). I’m not sure where to go from here other than abandon the JSON data structure for a simpler, less human readable structure.
Can someone help me determine the maximum buffer size I can set on the Photon, or think a modification to the SparkJson library that could reduce the required buffer size, or have answer to a question I don’t know how to ask?
Here’s the JSON in question. String length is 366.
{
"history": {
"brush twice":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0],
"dont murder":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
"no sweets":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0],
"workout":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
"sleep by 12am":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0],
"on time":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
}
}
Calculating Buffer Size.
I used the ArduinoJson assistant site to determine the max required buffer size, which according to them comes out to 3920 in the JSON above and 3284 for the smaller JSON example below.
Do note, the BUFFER_SIZE
number calculated by the Photon and the site is inconsistent.
// Calculating Buffer Size on Photon
const int CHAR_LENGTH = 284;
const int BUFFER_SIZE = 5*JSON_ARRAY_SIZE(22) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(5) + CHAR_LENGTH;
// 3172 w/ CHAR_LENGTH, 2888 w/o. Both worked in my trials below.
Yet the site recommends:
- AVR 8-bit ** 1252**
- ESP8266 ** 1756**
- Visual Studio x86 3200
- Visual Studio x64 3284
The correct BUFFER_SIZE is probably the one calculated on the Photon (it seems to work, anyways).
My Particle.subscribe()
handler:
void handleHistory(const char *event, const char *data) {
int length = strlen(data) + 1;
// copy char[] out of const since SparkJson needs to write.
char json[length];
strcpy(json, data);
const int CHAR_LENGTH = 366;
const int BUFFER_SIZE = JSON_ARRAY_SIZE(22) * 6 + JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(1) + CHAR_LENGTH; // 3822
StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(json);
if (!root.success()) {
Particle.publish("parseObject() failed", String(System.freeMemory()));
} else {
Particle.publish("parseObject() success!", String(System.freeMemory()));
}
}
// This code fails for me, causing the Photon to flash red.
The library definitely works.
I’ve determined that a smaller test JSON (length 284) parses perfectly when the buffer is set to 3172 or 2888 (both work).
char small_json[] = "{\"history\":{\"brush twice\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0],\"dont murder\":[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],\"no sweets\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0],\"workout\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0],\"sleep by 12am\":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0]}}";
System.freeMemory()
reports 60908 before the buffer is created, and 60960 upon success.
In the particle console I see the webhook response containing the entire json string, and on the Photon I’m publishing the length of that string to confirm it is what I expect.
So far I’m sure that:
- The parser works for smaller JSONs of similar structure.
- The entire JSON char[] is making it to the handler’s
const char* data
- Reducing the buffer size significantly below to the size calculated by on the Photon will cause the parse to fail.
- The Photon’s max buffer size for me is somewhere between 3284 and 3920