jsonesp32spiffsarduinojson

Json parsing not working with JsonObject using ArduinoJson library


I am using the following code to store Config.json file to ESP32 flash memory using SPIFFS

#include <ArduinoJson.h>
#include <FS.h>
#include<SPIFFS.h>

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);
Serial.println(buf.get());


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


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

const char* ssid = json["ssid"];
const char* password = json["password"];

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


Serial.print("Loaded ssid: ");
Serial.println(ssid);
Serial.print("Loaded password: ");
Serial.println(password);
return true;
}


void setup() {
Serial.begin(115200);
Serial.println("");
delay(1000);
Serial.println("Mounting FS...");
if (!SPIFFS.begin()) {
Serial.println("Failed to mount file system");
return;
}




if (!loadConfig()) {
  
Serial.println("Failed to load config");

} 

else {
Serial.println("Config loaded");
}

}

void loop() {
yield();

}

However the parsing fails, and I get the following message on the serial monitor: Mounting FS... ⸮xV⸮⸮⸮⸮⸮ Failed to parse config file Failed to load config

    {
        "ssid": "ESP32",
        "password": "Softronics"    
      }

Thank you in advance


Solution

  • There's no need to pre-allocate a buffer to store the file for ArduinoJSON. ArduinoJSON is quite capable of reading the file itself and avoiding the need to manage a buffer for the file.

    This code is unnecessary. You should not allocate a buffer.

    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);
    Serial.println(buf.get());
    
    
    StaticJsonBuffer<1024> jsonBuffer;
    JsonObject& json = jsonBuffer.parseObject(buf.get());
    
    if (!json.success()) {
    Serial.println("Failed to parse config file");
    return false;
    }
    

    Here's a complete program which works correctly for me:

    #include <ArduinoJson.h>
    #include <FS.h>
    #include<SPIFFS.h>
    
    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;
      }
    
      StaticJsonDocument<1024> doc;
      DeserializationError error = deserializeJson(doc, configFile);
    
      if(error) {
        Serial.println("Failed to parse config file");
        return false;
      }
    
      const char* ssid = doc["ssid"];
      const char* password = doc["password"];
    
      // Real world application would store these values in some variables for
      // later use.
    
    
      Serial.print("Loaded ssid: ");
      Serial.println(ssid);
      Serial.print("Loaded password: ");
      Serial.println(password);
      return true;
    }
    
    
    void setup() {
      Serial.begin(115200);
      Serial.println("");
      delay(1000);
      Serial.println("Mounting FS...");
      if (!SPIFFS.begin()) {
        Serial.println("Failed to mount file system");
        return;
      }
    
      if (!loadConfig()) {
        Serial.println("Failed to load config");
      } 
      else {
        Serial.println("Config loaded");
      }
    }
    
    void loop() {
      yield();
    
    }
    

    The code you posted was for ArduinoJSON version 5, which is obsolete. This uses ArduinoJSON version 6. You should upgrade your library to use it.

    The ArduinoJSON documentation and examples are quite helpful when writing code that uses the library.

    Also, please try indenting your code, at least as a courtesy to others if not to do yourself a favor. Proper indentation makes code much more readable.