Skip to main content

One Firmware for all ESP32 Variants: Solving Pin Mapping Pain

For my embedded project, I needed NFC card functionality for WiFi onboarding and user interactions. When integrating NFC functionality into ESP32 projects, pin mapping became a major pain point as I was working with different ESP32 boards.

Adafruit's arduino library example sets up the NFC reader in following manner:

#include <Wire.h>
// Using the SPI breakout, define the pins for SPI communication.
#define PN532_SCK  (2)
#define PN532_MOSI (3)
#define PN532_SS   (4)
#define PN532_MISO (5)
Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);

These pins are placeholders and they would vary for each ESP32 variant and I had several: ESP-WROOM-32, ESP32-C3 Super Mini, S3, XIAO ESP32S3

I tested the reader across all these variants, different modes: SPI, I2C, wiring and reading different NFC cards.

First challenge was to figure out the mapping of pins. I found that espressif's arduino support is the best resource for it. For each board the file pins_arduino.h gives us the right pins. For the ESP32-C3 Super Mini board, the above example NFC reader code would become:

#include <Wire.h>
#define PN532_SCK  (4)
#define PN532_MOSI (6)
#define PN532_SS   (7)
#define PN532_MISO (5)
Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);

But as I iterated through these ESP32 variants it became quite a pain adjusting those pins in the firmware and flashing it. Eventually I realized what would simplify this: I could have a single firmware that will work with everything:

#include <Wire.h>
Adafruit_PN532 nfc(SCK, MISO, MOSI, SS);

These pins, SCK, MISO are just like another constant: LED_BUILTIN, each Arduino board that doesn't use default pin 13, defines it in their pins_arduino.h header. Similarly all the variants have their own respective pins_arduino.h file with right pins. As I select the board inside Arduino IDE, these variables are always available. Further this pattern isn't limited to NFC readers, all the SPI peripheral using those pins would work.