До того, как кто-то пометит это как дубликат, я нашел эти две ссылки, и ни одна из них не применима полностью, хотя я реализовал хотя бы несколько из них.
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");
}
}
Размер, выделенный для charBuf
должно быть jsonStr.length() + 1
потому что вам нужно место для конца строки. Поэтому вы также должны добавить что-то вроде charBuf[jsonStr.length()] = '\0';
чтобы предоставить этот строковый терминатор:
int const jsonStringLengh = jsonStr.length();
char charBuf[jsonStringLengh + 1];
jsonStr.toCharArray(charBuf, jsonStringLengh);
charBuf[jsonStringLengh] = '\0';
Итак, это решило это. Все, что мне нужно было сделать, это создать новый 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");
}
}