I published a new version of ArduinoJson. No important feature this time, ArduinoJson 6.17 is more of a service pack.

As you’ll see, I managed to move some static data to Flash (i.e., PROGMEM), saving a significant amount of memory on Harvard architectures (mainly AVR and ESP8266). Unfortunately, this change has no impact on von Neumann architectures (such as ESP32, megaAVR, and ARM).

Errors strings moved to Flash

The first things I moved from RAM to Flash are the error strings. DeserializationError now supports a new member function f_str(), which returns a const __FlashStringHelper* (i.e., a Flash string with a recognisable type).

To use it, simply replace c_str with f_str, like so:

DeserializationError error = deserializeJson(doc, json);

if (error) {
  Serial.print(F("deserializeJson() failed: "));
  Serial.println(error.f_str());
  return;
}

This change alone saves 86 bytes of RAM on AVR (e.g., Arduino UNO ) and 108 bytes on ESP8266. Again, this only saves memory for Harvard architectures, which uses different address spaces for program (Flash) and data (SRAM).

Float conversion tables moved to Flash

The second place where I moved data to program memory is in the float-to-string and string-to-float conversion code. This code contains three tables of constant floating-point values, which are good candidates for Flash memory.

This change is completely transparent to the user but saves a lot of RAM, especially if you use both serializeJson() and deserializeJson(). On AVR, it saves 72 bytes; and on ESP8266, it saves between 80 and 224 bytes (depending on ARDUINOJSON_USE_DOUBLE).

Again, von Neumann architectures (such as ESP32, megaAVR, and ARM) are unaffected by this change because they use the same address space for program and data.

A new error status: EmptyInput

In previous versions, IncompleteInput could mean either “empty input” or “incomplete input”, causing some surprise among the users. ArduinoJson 6.17 adds the error status EmptyInput dedicated to the “empty input” case.

This change should have no impact on your code, unless you check specific error codes in a switch statement, for example.

An easy way to detect memory pool overflows

With ArduinoJson 6, it’s always been easy to diagnose memory problems that occur during deserialization. You just need to check the result of deserializeJson() and deserializeMsgPack(); the NoMemory error indicates that memory pool is exhausted.

For serialization, however, detecting memory issues was really tricky. You had to check the result of every call to JsonVariant::set() and JsonVariant::add(). To help you detect memory issues, ArduinoJson 6.17 adds JsonDocument::overflowed() which returns:

  • false if the memory pool was sufficiently large, and the JsonDocument contains all the values you inserted
  • true if the memory pool was too small, and some values are missing from the JsonDocument

Of course, this works for both serialization and deserialization.

Filtering for MessagePack

ArduinoJson 6.15 introduced input filtering for JSON but not for MessagePack.

In ArduinoJson 6.17, you can use DeserializationOption::Filter with deserializeMsgPack() the same way you do with deserializeJson(). Please see ArduinoJson 6.15: Filtering done right for details.

There is an unusual story for this feature: it was implemented twice.
In June 2020, Luca Passarella opened a feature request, and I kindly answered that I was not ready to develop it because too few users are interested in MessagePack. In October 2020, he opened a Pull Request, but I had to decline it because it didn’t include any tests, and I don’t believe in tests written after the implementation. Realizing how bad Luca needed this feature, I started working on my own implementation but using a test-driven approach. At the same time, Luca added tests to his Pull Request and reach almost 100% coverage. In the end, I included my version because I had more confidence in it, but I was sad for the wasted effort.
I hope Luca isn’t too disappointed that his implementation wasn’t retained.

Program size

You know I always keep an eye on the size of the library, so let’s see how ArduinoJson 6.17 compares to previous versions.

Size of the examples of ArduinoJson 6.17 on ATmega328

This graph shows the size of the sample programs when compiled for an Arduino UNO . As you can see, despite the new features, ArduinoJson 6.17 shrank a little.

Conclusion

This release results from a great effort (from Luca Passarella, and me), I hope you’ll appreciate it. I recommend that you upgrade as soon as possible, especially if you use an Arduino UNO because you can free up to 7.7% of RAM capacity.

Should you have any problem or question about this release, please open an issue on GitHub.

Lastly, remember that you can support the development of the project (and learn much interesting stuff) by purchasing my book Mastering ArduinoJson.

Stay informed!

...or subscribe to the RSS feed

Global warming stripes by Professor Ed Hawkins (University of Reading)