ESP32 Relay Web Server

Pages
Contributors: Elias The Sparkiest
Favorited Favorite 11

Sate Machine - De/serializing Data

As mentioned above we'll be using ArduinoJSON to store not only the state of the relays "On" or "Off", but also Wifi credentials.

Deserialization

The tutorial on the Arduino JSON website is pretty darn fantastic and so this won't be a regurgitation of the information they have there, but I will go over the relevant components to this project.

In brief, deserialization is how we'll read the JSON document on the ESP32 (home.json) to get the necessary information for loading our wifi settings. Let's again take a look at the JSON file we have within the data folder that is uploaded to the ESP32 using the ESP32 file upload tool.

{
  "SSID" : "Wifi name",
  "Password": "password",
  "relay_states" : [0,0,0,0] 
}

Ignoring the "relay states" for now, we see that it's a rather simple document. To get this information, we're doing two main things within the manage_config_file.ino sketch. The first is opening the the JSON file to get to the wifi credentials and checking for errors.

 File configFile = SPIFFS.open(configPath, "r");
  if(!configFile)
    Serial.println("Could not open file.");

Opening the config file.

This is simple enough, we need the absolute path to the file: configPath, which is /home.json. This is defined in the main home.ino sketch. The next main thing is to take the wifi credentials within the JSON file and save them so that they can be used to connect to the WiFi. This process is not as straight forward as it may seem but it's well worth the effort.

  const size_t capacity = JSON_ARRAY_SIZE(4) + JSON_OBJECT_SIZE(3) + 100;
  DynamicJsonDocument doc(capacity); 

  DeserializationError err = deserializeJson(doc, configFile);

  if(err) {
    Serial.print("Deserialization error:");
    Serial.println(err.c_str());
  }

  doc["SSID"].as<String>().toCharArray(ssid, 30);
  doc["Password"].as<String>().toCharArray(password, 30);

  configFile.close();

}

Deserializing the JSON file.

First and foremost you have to determine the size of the information that you're deserializing. On the ArduinoJSON website they include how to calculate the size manually but even better they provide a tool that calculates the size automatically. Take note that you want the size needed for deserializing and not serializing. I believe the size already in place should be sufficient for 90 percent of people's WiFi network names and passwords, but in case you get a "NoMemory" error, this is the place to modify.

Next a "doc" object is created with the given size (this will hold our information from the JSON file), and is passed to deserializeJson along with the configFile. If there is an error, it will be printed out to the Serial terminal, but if not we'll take that information and save it to ssid and password. Now this looks a bit funky. Let's break the two deserialization lines down for clarification.

  doc["SSID"].as<String>().toCharArray(ssid, 30);
  doc["Password"].as<String>().toCharArray(password, 30);

I could (and I tried) to do this:

const char* ssid = doc["SSID"];

This is correct because doc returns a const char pointer. However since we're reading from a file, that will later be closed, this pointer will not point to anything. So we don't want to save a pointer to our information, we would rather save the information itself. So we use some built in C++ magic to take the wifi credentials being pointed at and save them as an array of characters. If that's over your head, don't worry, just leave it as is and everything works.

Serializing

Coming SOON!