As JsonConfigExample.ino shows, it’s important to use custom structures to store the state of your application.
Many users are puzzled by this advice. Why should I create my own structure when
Reason 1: monotonic allocator
Why a monotonic allocator? Because it’s the simplest, fastest, and smallest kind of allocator; it’s the perfect solution for microcontrollers. More importantly, the monotonic allocator is sufficient to solve the problem addressed by ArduinoJson: the JSON serialization.
Can’t we do better? In an older version of ArduinoJson, I implemented a full-fledge allocator with compaction, but I had to roll back the changes because the impact on code size and memory consumption was unacceptable for small microcontrollers. It’s likely that this feature will come back some day, but not until Arduino UNOs are long gone.
Reason 2: overhead
Passing through the JSON object model is less efficient regarding:
- Memory usage: a
JsonVariantis much larger than an
int, for example.
- Execution speed: accessing a member of a
JsonDocumentis much slower than accessing a
- Code size: every call you make through ArduinoJson increase the size of your program; remember that the Flash memory is quite small.
Reason 3: type safety
Once your data is captured in C++ structures, you can rely on the security provided by the type system; you don’t have to check that such member is present and have the right type, which allows detecting bugs at compile time.
Reason 4: coupling
The way information is serialized is an implementation detail; the rest of the program should not depend on it. This is a direct application of the Dependency Inversion Principle (DIP).
Moreover, you should not spread ArduinoJson everywhere in your code, you would be too dependent on ArduinoJson. What if you want to use another library? What if I change the API again? You don’t want to be at the mercy of a library developer, even me.