Introduction
In this tutorial we are going to learn how to serialize a parsed JSON object to a file on the ESP32 file system. We will be using the Arduino core.
In order to be able to interact with a file system on the ESP32, we first need to mount it. In our case, we are going to use the SPIFFS file system, one of the supported solutions on the ESP32.
To parse the JSON, we are going to use the nlohmann/json library. For an introductory article on how to install it as an Arduino library and get started with the basic functionality, please check here.
Note that we already covered how to deserialize a JSON object from a file on this previous tutorial.
The tests from this tutorial were performed on a ESP32-E FireBeetle board from DFRobot. The Arduino core version used was 2.0.0 and the Arduino IDE version was 1.8.15, working on Windows 8.1. The version of the Nlohmann/json library used was 3.10.2
Writing JSON to file
We will start the code by the library includes:
- SPIFFS.h: Allows to mount the SPIFFS file system.
- json.hpp: Exposes the JSON related functionality.
- fstream: Allows to read and write files from / to the file system using the ifstream and ofstream classes, respectively.
#include <SPIFFS.h>
#include <json.hpp>
#include <fstream>
Then we will take care of the Arduino setup function, which is where we will write the rest of our code. As usual, we start the code by opening a serial connection, to be able to write the results of our program.
Serial.begin(115200);
Then we will mount the SPIFFS file system. Naturally, we need to do this before we can read and write files. We mount the file system with a call to the begin method on the SPIFFS extern variable.
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
After that we will define a string containing a JSON object. For illustration purposes, our JSON will represent a possible person structure, which contains some properties. We will use a C++ raw string literal to avoid having to escape special characters in our string.
char str[] = R"(
{
"name": "John",
"age": 10,
"address": {
"street": "St. Street",
"code": "1234-12"
}
}
)";
Now that we have our JSON string, we will take care of parsing it to a json object. We do this with a call to the parse static method, passing as input our previously defined string. As output we get the parsed json object.
nlohmann::json obj = nlohmann::json::parse(str);
To write the file, we will start by creating an object of class ofstream. As input of the constructor we will pass the name of the file, which should include the whole path. Since we are using the SPIFFS file system and we did not override the default root path, it should start with “/spiffs“. We are going to call the file “person.json“, meaning the whole path will be “/spiffs/person.json”.
std::ofstream fileToWrite("/spiffs/person.json");
Now that we have our parsed json object and our ofstream object, we can leverage the << operator to perform the serialization.
fileToWrite << obj;
To finalize the writing process, we need to call the close method on our ofstream object.
fileToWrite.close();
To confirm the file was correctly written, we will now read it. For that, we will use the ifstream class. Like before, we create an object of this class, passing as input the name of the file.
std::ifstream fileToRead("/spiffs/person.json");
Then we will print each character of the file in a loop.
char c;
while(fileToRead.get(c)){
Serial.print(c);
}
The whole code is shown below.
#include <SPIFFS.h>
#include <json.hpp>
#include <fstream>
void setup() {
Serial.begin(115200);
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
char str[] = R"(
{
"name": "John",
"age": 10,
"address": {
"street": "St. Street",
"code": "1234-12"
}
}
)";
nlohmann::json obj = nlohmann::json::parse(str);
std::ofstream fileToWrite("/spiffs/person.json");
fileToWrite << obj;
fileToWrite.close();
std::ifstream fileToRead("/spiffs/person.json");
char c;
while(fileToRead.get(c)){
Serial.print(c);
}
}
void loop() {}
To test the code, compile it and upload it to your device, using the Arduino IDE. Once the procedure is finished, open the IDE serial monitor. You should obtain a result similar to figure 1, which shows the serialized JSON that was written to the file.
Other types of streams
In the previous tutorial where we learned how to parse JSON files from the file system, we concluded that we could apply the process to other types of streams. The same is true for writing, since the << operator actually expects a ostream, being ofstream just an example of a class that extends ostream.
As such, for this section, we will write a JSON to a stringstream object, which also extends the ostream class.
We start by the library includes. This time, we will just need the json.hpp, for the JSON related functionalities, and the sstream, which exposes the stringstream class.
#include <json.hpp>
#include <sstream>
Like before, on the setup, we will define a JSON string and parse it to a json object.
char str[] = R"(
{
"name": "John",
"age": 10,
"address": {
"street": "St. Street",
"code": "1234-12"
}
}
)";
nlohmann::json obj = nlohmann::json::parse(str);
Then we will create a stringstream object and use the << operator to serialize the parsed json object to it.
std::stringstream stream;
stream << obj;
Finally, we will print all the characters of the stringstream to the serial port, to confirm the whole process was executed as expected.
char c;
while(stream.get(c)){
Serial.print(c);
}
The complete code can be seen below.
#include <json.hpp>
#include <sstream>
void setup() {
Serial.begin(115200);
char str[] = R"(
{
"name": "John",
"age": 10,
"address": {
"street": "St. Street",
"code": "1234-12"
}
}
)";
nlohmann::json obj = nlohmann::json::parse(str);
std::stringstream stream;
stream << obj;
char c;
while(stream.get(c)){
Serial.print(c);
}
}
void loop() {}
To test the code, once again simply compile it and upload it to your ESP32. When the procedure finishes, you should get a result similar to figure 1 on the Arduino IDE serial monitor.
Suggested ESP32 Readings
- Deserializing JSON objects from the file system
- Getting started with the Nlohmann/json json library
- Preserve order of keys on json properties insertion
- Using the ifstream and ofstream functions
- Reading a file from SPIFFS
- Writing a file to SPIFFS
- FAT file system