Сбой разбора ArduinoJson при чтении строки из EEPROM

До того, как кто-то пометит это как дубликат, я нашел эти две ссылки, и ни одна из них не применима полностью, хотя я реализовал хотя бы несколько из них.

Буфер перезаписывается

Arduino читает json из EEPROM / конвертирует uint8_t в char

Моя проблема в этом. Я пытаюсь прочитать и записать строку JSON в EEPROM Arduinos с помощью библиотеки ArduinoJson (https://github.com/bblanchon/ArduinoJson). В приведенном ниже коде я генерирую JsonObject из жестко закодированной строки JSON (это работает). Затем я пишу это в EEPROM (это работает). Затем он возвращается из EEPROM (это работает), но когда я пытаюсь разобрать вторую строку с помощью ArduinoJSON, я получаю ошибку разбора.

Для целей тестирования я также очищаю EEPROM каждый раз на всякий случай, хотя в конечном итоге он будет удален.

Код компилируется без ошибок. Я надеюсь, что кто-то более знающий в C ++, чем я, заметит что-то действительно очевидное. Я собираю это на NodeMCU (esp8266).

#include <ArduinoJson.h>
#include <EEPROM.h>

StaticJsonBuffer<400> jsonBuffer;
JsonObject *jsonObject;
JsonObject *config;

String dummyJson = "{\"name\":\"RGB LED 1\",\"io\":[\"pwm1\",\"pwm2\",\"pwm3\"],\"io_type\":\"output\",\"device\":\"pwm_output\",\"uuid\":\"5a81f424aaf8d1e951ae78d270668337\",\"ip\":\"255.255.255.255\"}";

void setup()
{
Serial.begin(9600);
while (!Serial)
{
continue;
}
EEPROM.begin(512);

Serial.println("\n\n");
clearEEPROM();
createDummyJsonObject();
writeJsonToEEPROM();
readJsonFromEEPROM();
}

void createDummyJsonObject()
{
jsonObject = &jsonBuffer.parseObject(dummyJson);
if (!jsonObject->success())
{
Serial.println("jsonBuffer.parseObject() failed");
return;
}
else
{
Serial.println("JSON object generated from dummy string");
jsonObject->prettyPrintTo(Serial);
Serial.println("\n\n");
}
}

void loop()
{
// not used
}

void clearEEPROM()
{
for (int i = 0; i < 512 + 1; i++)
{
EEPROM.write(i, 0);
}
EEPROM.commit();
}

void writeJsonToEEPROM()
{
String jsonStr;
jsonObject->printTo(jsonStr);

for (int i = 0; i < jsonStr.length(); ++i)
{
EEPROM.write(i, jsonStr[i]);
}

EEPROM.write(jsonStr.length(), byte(0));
EEPROM.commit();
}

void readJsonFromEEPROM()
{
String jsonStr;

for (int i = 0; i < 512; ++i)
{
char c = char(EEPROM.read(i));
if (c != 0)
{
jsonStr += c;
delay(1);
}
else
{
break;
}
}
Serial.println(jsonStr);

char charBuf[jsonStr.length()];
jsonStr.toCharArray(charBuf, jsonStr.length());
config = &jsonBuffer.parseObject(charBuf);

if (!config->success())
{
Serial.println("jsonObject.parseObject() failed ");
return;
}
else
{
// Never reaches this point!
Serial.println("\nJSON object generated from EEPROM data");
config->prettyPrintTo(Serial);
Serial.println("\n\n");
}
}

0

Решение

Размер, выделенный для charBuf должно быть jsonStr.length() + 1 потому что вам нужно место для конца строки. Поэтому вы также должны добавить что-то вроде charBuf[jsonStr.length()] = '\0'; чтобы предоставить этот строковый терминатор:

int const jsonStringLengh = jsonStr.length();
char charBuf[jsonStringLengh + 1];
jsonStr.toCharArray(charBuf, jsonStringLengh);
charBuf[jsonStringLengh] = '\0';
1

Другие решения

Итак, это решило это. Все, что мне нужно было сделать, это создать новый StaticJsonBuffer для второго анализа строки. Для тех, у кого есть подобная проблема, вот рабочий код.

    #include <ArduinoJson.h>
#include <EEPROM.h>

StaticJsonBuffer<512> jsonBuffer;
JsonObject *jsonObject;
JsonObject *config;

String dummyJson = "{\"name\":\"RGB LED 1\",\"io\":[\"pwm1\",\"pwm2\",\"pwm3\"],\"io_type\":\"output\",\"device\":\"pwm_output\",\"uuid\":\"5a81f424aaf8d1e951ae78d270668337\",\"ip\":\"255.255.255.255\"}";

void setup()
{
Serial.begin(9600);
while (!Serial)
{
continue;
}
EEPROM.begin(512);

clearEEPROM();
createDummyJsonObject();
writeJsonToEEPROM();
readJsonFromEEPROM();
}

void createDummyJsonObject()
{
jsonObject = &jsonBuffer.parseObject(dummyJson);
if (!jsonObject->success())
{
Serial.println("jsonBuffer.parseObject() failed");
return;
}
else
{
Serial.println("JSON object generated from dummy string");
}
}

void loop()
{
// not used
}

void clearEEPROM()
{
for (int i = 0; i < 512 + 1; i++)
{
EEPROM.write(i, 0);
}
EEPROM.commit();
}

void writeJsonToEEPROM()
{
String jsonStr;
jsonObject->printTo(jsonStr);
for (int i = 0; i < jsonStr.length(); ++i)
{
EEPROM.write(i, jsonStr[i]);
}
EEPROM.write(jsonStr.length(), byte(0));
EEPROM.commit();
}

void readJsonFromEEPROM()
{
String jsonStr;
for (int i = 0; i < 512; ++i)
{
char c = char(EEPROM.read(i));
if (c != 0)
{
jsonStr += c;
delay(1);
}
else
{
break;
}
}

StaticJsonBuffer<512> jsonBuffer2;
config = &jsonBuffer2.parseObject(jsonStr);
if (!config->success())
{
Serial.println("jsonObject.parseObject() failed ");
return;
}
else
{
Serial.println("\nJSON object generated from EEPROM data");
config->prettyPrintTo(Serial);
Serial.println("\n\n");
}
}
0

По вопросам рекламы [email protected]