3

我正在使用 Arduino ESP8266 在 SPIFSS 上存储和加载配置设置。我使用这个 ConfigFile.ino 作为参考示例。

https://github.com/esp8266/Arduino/blob/master/libraries/esp8266/examples/ConfigFile/ConfigFile.ino

此函数将配置设置加载到变量serverNameaccessToken.

bool loadConfig() {
  File configFile = SPIFFS.open("/config.json", "r");
  if (!configFile) {
    Serial.println("Failed to open config file");
    return false;
  }

  size_t size = configFile.size();
  if (size > 1024) {
    Serial.println("Config file size is too large");
    return false;
  }

  // Allocate a buffer to store contents of the file.
  std::unique_ptr<char[]> buf(new char[size]);

  // We don't use String here because ArduinoJson library requires the input
  // buffer to be mutable. If you don't use ArduinoJson, you may as well
  // use configFile.readString instead.
  configFile.readBytes(buf.get(), size);

  StaticJsonBuffer<200> jsonBuffer;
  JsonObject& json = jsonBuffer.parseObject(buf.get());

  if (!json.success()) {
    Serial.println("Failed to parse config file");
    return false;
  }

  const char* serverName = json["serverName"];
  const char* accessToken = json["accessToken"];

  // Real world application would store these values in some variables for
  // later use.

  Serial.print("Loaded serverName: ");
  Serial.println(serverName);
  Serial.print("Loaded accessToken: ");
  Serial.println(accessToken);
  return true;
}

我对此函数进行了一些修改,以将配置设置加载到结构中。

struct ConfigSettingsStruct
{
    String ssid;
    String password;
};

ConfigSettingsStruct ConfigSettings;

bool loadConfig() {
    File configFile = SPIFFS.open("/config.json", "r");
    if (!configFile) {
        Serial.println("Failed to open config file");
        return false;
    }

    size_t size = configFile.size();
    if (size > 1024) {
        Serial.println("Config file size is too large");
        return false;
    }

    // Allocate a buffer to store contents of the file.
    std::unique_ptr<char[]> buf(new char[size]);

    // We don't use String here because ArduinoJson library requires the input
    // buffer to be mutable. If you don't use ArduinoJson, you may as well
    // use configFile.readString instead.
    configFile.readBytes(buf.get(), size);

    StaticJsonBuffer<200> jsonBuffer;
    JsonObject& json = jsonBuffer.parseObject(buf.get());

    if (!json.success()) {
        Serial.println("Failed to parse config file");
        return false;
    }

    //const char* serverName = json["serverName"];
    //const char* accessToken = json["accessToken"];

    char ssid_[30];
    strcpy(ssid_, json["ssid"]);
    ConfigSettings.ssid = String(ssid_);

    char password_[30];
    strcpy(password_, json["password"]);
    ConfigSettings.password = String(password_);

    // Real world application would store these values in some variables for
    // later use.

    Serial.print("Loaded ssid: ");
    Serial.println(ConfigSettings.ssid);
    Serial.print("Loaded password: ");
    Serial.println(ConfigSettings.password);

    return true;
}

下载代码并运行 ESP8266 后,WiFi 芯片重置并出现一些堆栈错误。我的代码有什么问题?如何正确加载配置设置ConfigSettings

4

2 回答 2

2

您的代码在问题中没有任何问题。它应该工作。我强烈怀疑堆栈错误的原因在于其他地方。请再次仔细检查您的代码。

这不算作答案,但有助于提醒您寻找其他地方。你可能看错地方了。

于 2016-09-21T02:22:10.773 回答
2

请注意;之后你可能有内存泄漏

std::unique_ptr<char[]> buf(new char[size]);

我建议您使用通过 malloc 分配一些内存(这不是时尚但经典)并毕竟释放它。您还需要在返回之前关闭文件。

此外,您的 ssid 和密码短语缓冲区长度还不够。最大 ssid 长度必须为 32。假设您有基于 psk 的加密,您需要将传递缓冲区长度增加到 64。

小但是;也许您可以考虑在结构定义之前添加一个 typedef,尽管 C++ 线程可以在命名空间中定义它们。

于 2016-09-22T04:09:19.567 回答