Why switch from Arduino to ESP-IDF?
If you’re like me, you love all the cheap, WiFi-y goodness of Espressif MCU’s, but hate the complexity of the Espressif IoT Development Framework (esp-idf). So you decide to go with the Arduino framework, and all is well and there is much rejoicing.
For a time. Enter the watchdog.
The idea is to reap long-running, unresponsive tasks. If a thread doesn’t yield, doesn’t ask the watchdog for more time, it gets reaped. This works well inside the esp-idf: but in the Arduino framework, watchdog behavior is unmodifiable. Tasks must complete in the default 5s, or else killed.
And then there’s the 800+ esp-idf project configuration options. That’s a lot of settings that don’t come with Arduino.
You can have it all
The good news is you can have the best of both: esp-idf AND Arduino frameworks, by embedding Arduino as a esp-idf component.
If you’re using PlatformIO, this is as simple as updating the platform.ini
with framework = espidf, arduino
[env:nodemcu-32s]
board = nodemcu-32s
platform = espressif32
framework = espidf, arduino
...
There’s even a config option to allow loop() / setup()
handlers within esp-idf.
If you switch to esp-idf’s app_main()
entrypoint, simply call initArduino
at the start and all your old Arduino code (Wire, ArduinoJson, etc) is up and running.
#include "Arduino.h"
void app_main()
{
initArduino();
...
}
Gotchas
Writing C++ inside the ESP-IDF framework
By default, PlatformIO generates main.c
boilerplate to use with the C esp-idf library. But you can write C++ that calls esp-idf C code (and vice versa) by renaming main.c
to main.cpp
and wrapping app_main()
in an extern "C"
// main.cpp
#include "Arduino.h"
extern "C"
{
void app_main()
{
initArduino();
...
}
}
You might also add build_flags = -std=c++11
to platform.ini
for good measure: without it, I got outdated warnings and errors in the build log.
Partitions
The esp32 comes with a default partition table, for carving up that precious 4MB integrated flash. While it’s possible to change how space is allocated with Arduino, esp-idf makes it so much easier. Simply steal a layout CSV from these examples and reference it in the platform.ini
board_build.partitions
section
[env:nodemcu-32s]
board = nodemcu-32s
platform = espressif32
framework = espidf, arduino
board_build.partitions = partitions_two_ota.csv
Or, write your own layout CSV – it’ll work (example) so long as it’s in the root project dir, and named correctly,
After changing partitions, clear flash with pio run -t erase
. Otherwise weird behavior happens when trying to write to the new partitions (ex. ota).