从EEPROM读取字符串时,ArduinoJson解析失败

时间:2018-07-10 16:19:40

标签: c++ json arduino eeprom

在有人将其标记为重复之前,我已经找到了这两个链接,尽管我至少实现了两个,但这两个链接都不适用。

Buffer gets overwritten

Arduino reading json from EEPROM / converting uint8_t to char

我的问题是这个。我正在尝试使用ArduinoJson库(https://github.com/bblanchon/ArduinoJson)向Arduinos EEPROM读取和写入JSON字符串。在下面的代码中,我从一个硬编码的JSON字符串生成一个JsonObject(这可行)。然后,我将其写入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");
  }
}

2 个答案:

答案 0 :(得分:1)

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 :(得分: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");
  }
}