Arduino Nano ESP32 Pinout Reference

The Arduino Nano ESP32 is the first ever Arduino Nano board built around an ESP32 microcontroller, while keeping the familiar compact and breadboard-friendly Nano form factor. At its heart is the ESP32-S3, which features a dual-core 32-bit Xtensa LX7 processor that can run at speeds of up to 240 MHz, along with 2.4 GHz Wi-Fi and Bluetooth 5 Low Energy (LE) connectivity. With these wireless features, along with built-in support for MicroPython and the Arduino Cloud, the Nano ESP32 is well suited for projects such as home automation systems, IoT sensor devices, and other connected or low-power applications.

To make full use of these features, however, you first need to understand the Nano ESP32 pinout. Each pin can serve one or more purposes, and knowing how these pins work will help you connect components correctly, avoid common wiring mistakes, and get the most out of the board.

Arduino Nano ESP32 Pinout

The Nano ESP32 keeps the classic Nano form factor. It features two 1×15 pin headers along its sides, giving you 30 main connection points in total. These pins are spaced at the standard 2.54 mm distance, which means the board will snap perfectly into a standard breadboard just like earlier Nano boards.

The pinout is shown below:

arduino nano esp32 pinout

Let’s take a closer look at these pins and their functions, starting with the GPIO pins.

Arduino Nano ESP32 GPIO Pins

Out of the ESP32-S3’s 45 physical GPIOs, 24 are broken out on the Nano ESP32’s headers: the 14 digital pins (D0 through D13), the 8 analog pins (A0 through A7), and two special mode-select pins named B0 and B1.

arduino nano esp32 gpio pins

The most important rule to remember when using this board is that the ESP32-S3 chip operates strictly on 3.3V logic. This means you must never expose the GPIO pins to a 5V source. Doing so can permanently damage the board.

Also the GPIOs on the Nano ESP32 can handle source currents up to 40 mA, and sink currents up to 28 mA. Never connect devices that draw higher current directly to a GPIO.

The GPIO Matrix and the IO MUX

One of the most powerful features of the ESP32-S3 is its GPIO Matrix. You can think of it as an internal routing system inside the chip. It allows you to assign almost any digital function, such as PWM, I2C, SPI, UART, I2S or TWAI, to almost any physical pin simply by changing your code.

However, this flexibility does have a minor limitation. Because signals have to travel through the GPIO Matrix, a tiny delay is introduced. For the vast majority of projects, this delay is completely unnoticeable. But when you are dealing with extremely fast signals or highly sensitive analog readings, that tiny delay becomes a problem.

To handle those demanding tasks, the ESP32-S3 bypasses the GPIO Matrix and uses something called the IO MUX.

The IO MUX connects specific physical pins directly to the dedicated hardware inside the chip. Some of these connections are fixed and cannot be moved in software, while others have default pin assignments but they can still be moved by using the GPIO Matrix. Functions that strictly depend on the IO MUX include ADC channels, the internal JTAG debugging interface, the USB Serial/JTAG controller, and the high-speed SPI connections used for the built-in flash memory.

So, while you have the freedom to route signals like I2C or PWM to almost any pin on the Nano ESP32, you cannot freely move every function. Some features, especially analog or high-speed ones, must stay on their assigned pins because they rely on the IO MUX.

In simple terms, the Nano ESP32’s peripheral signals can be grouped like this:

Routing typePeripheral examplesWhat it means
Fixed to specific pins through the IO MUXADC1, ADC2, TouchThese functions must use their assigned pins and cannot be moved in software.
Connected to default IO MUX pins, but can also be rerouted through the GPIO MatrixUART0, UART1, SPI2These functions have standard pin locations, but they can be moved to other GPIO pins if needed.
Not assigned to fixed pins by default and routed through the GPIO MatrixUART2, SPI3, I2C, I2S, TWAI, LED PWM, LCD and Camera, SD/MMC, MCPWMThese functions are flexible and can be assigned to different GPIO pins in software.

Which Arduino Nano ESP32 pins are safe to use?

Although the Nano ESP32 exposes a good number of flexible pins, some of them may not be suitable for every project. The table below shows which pins are safe to use, and which should be used with caution.

  • – Your top priority pins. They are perfectly safe to use.
  • – Pay close attention because their behavior, particularly during boot, can be unpredictable. Use them with caution.
  Nano Pin     ESP32-S3 GPIO     Safe to use?     Type   Notes
D0 / RX GPIO44 UART-RX Used as UART0 receive (console/bootloader); repurposing may disable serial programming and debug logs
D1 / TX GPIO43 UART-TX Used as UART0 transmit (console/bootloader); repurposing may disable serial console output and printing
D2 GPIO5
D3 GPIO6
D4 GPIO7
D5 GPIO8
D6 GPIO9
D7 GPIO10
D8 GPIO17
D9 GPIO18
D10 GPIO21
D11 GPIO38
D12 GPIO47
D13 GPIO48 LED Shared with the onboard LED_BUILTIN status LED
A0 GPIO1
A1 GPIO2
A2 GPIO3 Strapping Pin ADC1_CH2; also selects the JTAG signal source configuration; Default state: Floating
A3 GPIO4
A4 GPIO11
A5 GPIO12
A6 GPIO13
A7 GPIO14
B0 GPIO46 Strapping Pin / RGB LED Controls ROM debug message printing at boot; also drives the onboard RGB LED’s red channel; Default state: LOW (Pull-down)
B1 GPIO0 Strapping Pin / RGB LED Determines the primary boot mode (HIGH for normal boot, LOW enters Download Mode); also drives the onboard RGB LED’s green channel; Default state: HIGH (Pull-up)

The image below shows which GPIO pins can be used safely.

arduino nano esp32 safe gpio pins

Arduino Nano ESP32 Interrupt Pins

Unlike microcontrollers with dedicated, singular interrupt pins, the Nano ESP32 uses an advanced Interrupt Matrix. This matrix allows absolutely any functional GPIO pin to be configured as an external interrupt source.

The following trigger configurations are supported:

ModeTrigger ConditionTypical Use Cases
LOWPin remains at LOW levelLevel-triggered events
HIGHPin remains at HIGH levelLevel-triggered events
CHANGEPin changes state (either direction)Encoder reading, pulse counting
FALLINGPin transitions from HIGH to LOWButton press detection (pull-up)
RISINGPin transitions from LOW to HIGHButton press detection (pull-down)

Arduino Nano ESP32 RTC GPIO Pins

Some GPIOs on the ESP32-S3 are connected to the RTC (real-time clock) low-power domain. These are called RTC GPIOs, and on the full chip they span GPIO0 through GPIO21.

Nearly every pin exposed on the Nano ESP32 falls inside this range: B1 (GPIO0), A0-A3 (GPIO1-4), D2-D7 (GPIO5-10), A4-A7 (GPIO11-14), D8-D9 (GPIO17-18), and D10 (GPIO21) are all RTC-capable. Only D11, D0, D1, D12, D13, and B0 (GPIO38, 43, 44, 47, 48, and 46) fall outside this range.

arduino nano esp32 rtc gpio pins

These pins matter most when the board is in deep sleep. They can wake the chip up when an external event happens, such as a button press, a PIR motion sensor detecting movement, or an accelerometer sending an alert signal.

Arduino Nano ESP32 Strapping Pins

Strapping pins are a special set of highly sensitive GPIOs that determine how the microcontroller behaves the moment it wakes up. At the exact millisecond the ESP32-S3 boots or resets, the chip checks the voltage levels on these specific pins, and that tells it how to boot, how to handle debugging, and what voltage to send to the flash memory.

The ESP32-S3 actually has four strapping pins in total, and three of them are broken out on the Nano ESP32’s headers:

arduino nano esp32 strapping pins
PinGPIODefault StateCore Function During Boot Sequence
B1GPIO0Pull-up (HIGH)Determines the primary boot mode. If allowed to remain HIGH, the chip boots normally. If pulled LOW during reset, it enters Download Mode, letting you flash new firmware.
A2GPIO3FloatingSelects the configuration for the JTAG signal source, used for advanced debugging.
B0GPIO46Pull-down (LOW)Controls diagnostic messages. If pulled HIGH, the chip prints debug messages to the console during the boot sequence.

Each of these pins has a weak internal pull-up or pull-down resistor. These resistors set a default state for the pin if nothing else is connected to it. So, you don’t need to worry about them for everyday use. The board is already configured correctly out of the box.

Warning:

Strapping pins should always be used with extra care. Before connecting sensors or modules to B0, B1, or A2, make sure they won’t force the wrong logic level during startup.

For instance, if a sensor or switch accidentally holds B1 (GPIO0) LOW when you power on the board, the Nano ESP32 will silently enter Download Mode and refuse to run your sketch. Likewise, A2 (GPIO3) is one of the board’s regular analog inputs (ADC1_CH2) — if you’re using it for analog sensing, remember that it’s also sampled during every boot.

Arduino Nano ESP32 SPI Flash and PSRAM Pins

The Nano ESP32 relies on two dedicated memory chips inside the NORA-W106-10B module: a 128 Mbit (16 MB) external flash (GD25B128EWIGR), connected over Quad-SPI, and 8 MB of PSRAM connected over Octal SPI. Both communicate with the ESP32-S3 over their own dedicated GPIOs, entirely separate from the pins broken out on the Nano headers — so there’s no risk of accidentally reassigning them in your own sketches.

Arduino Nano ESP32 ADC Pins

The ESP32-S3 integrates two separate, high-performance 12-bit SAR ADCs: ADC1 and ADC2.

A0 (GPIO1) through A3 (GPIO4) belong to ADC1, while A4 (GPIO11) through A7 (GPIO14) belong to ADC2.

arduino nano esp32 adc pins

Note that the default resolution for the ADC pins are 12-bit (returns a value between 0-4095).

Notes:

Please note that A4 and A5 are reserved for I2C communication.

ADC2 is also used for Wi-Fi communication and can fail if used simultaneously.

ADC Attenuation

Inside the chip, the ADC uses a baseline internal reference voltage, known as Vref, to measure incoming analog signals. While this exact voltage varies slightly from chip to chip, the median Vref is roughly 1.1V.

To measure voltages higher than Vref safely, the ESP32-S3 uses a software-controlled feature called attenuation. Attenuation essentially scales down the incoming voltage before the ADC processes it. By increasing the attenuation level in your code, you expand the maximum measurable range of your analog pins.

There are 4 available attenuation options:

Attenuation ConfigurationMeasurable Input Voltage Range
ADC_ATTEN_DB_0 (0 dB)0 mV ~ 950 mV
ADC_ATTEN_DB_2_5 (2.5 dB)0 mV ~ 1250 mV
ADC_ATTEN_DB_6 (6 dB)0 mV ~ 1750 mV
ADC_ATTEN_DB_11 (11 dB)0 mV ~ 3100 mV

Arduino Nano ESP32 Capacitive-Touch Pins

The Nano ESP32 features built-in capacitive touch sensing. It allows you to turn a bare wire, a piece of copper tape, or a conductive surface into a touch button without needing external mechanical switches.

The ESP32-S3 has 14 capacitive touch channels, and on the Nano ESP32, every single one of them is broken out: A0-A7 and D2-D7

arduino nano esp32 touch pins

Unlike other functions, capacitive touch channels are not freely remappable. Each touch channel is tied to a particular GPIO.

Touch channelArduino pinESP32-S3 GPIO
TOUCH1A0GPIO1
TOUCH2A1GPIO2
TOUCH3A2GPIO3
TOUCH4A3GPIO4
TOUCH5D2GPIO5
TOUCH6D3GPIO6
TOUCH7D4GPIO7
TOUCH8D5GPIO8
TOUCH9D6GPIO9
TOUCH10D7GPIO10
TOUCH11A4GPIO11
TOUCH12A5GPIO12
TOUCH13A6GPIO13
TOUCH14A7GPIO14

How to Use the Capacitive-Touch Pins

To use capacitive touch on the Nano ESP32, you do not need to install any external libraries. The ESP32 Arduino core includes a native touchRead(pin) function.

For example, simply connect a conductive touch pad to any touch-capable pin such as A0, then read it with

int touchValue = touchRead(A0);

Check the value when the pad is untouched and when it is touched, then choose a threshold between those readings. If the value rises above the threshold, you can treat it as a touch.

Arduino Nano ESP32 I2C Pins

The Nano ESP32 features two completely independent hardware I2C controllers: I2C0 and I2C1

arduino nano esp32 i2c pins

To maintain physical compatibility with classic Arduino Nano shields and wiring, the primary I2C0 bus is pre-assigned to the standard A4 and A5 pins. However, you are not strictly locked into these pins and can re-route the SDA and SCL lines to almost any available GPIO on the board.

A second, completely independent I2C1 bus can be initialized on any two free pins.

InterfaceArduino ObjectSDA PinSCL PinRemarks
I2C0WireA4 (GPIO 11)A5 (GPIO 12)Default primary I2C bus. Maintains classic Nano pinout compatibility.
I2C1Wire1UnassignedUnassignedSecondary I2C bus. Completely free to be mapped to any available GPIO.

How to Use the Default I2C Bus (I2C0)

If you wire your sensor or peripheral directly to A4 and A5, you only need to call Wire.begin() without any parameters during setup.

#include <Wire.h>

void setup() {
  // Initializes I2C0 on default pins (A4=SDA, A5=SCL)
  Wire.begin(); 
}

void loop() {
  Wire.beginTransmission(0x3C); // Begin communication with device address (e.g., 0x3C)
  Wire.write(0x00);             // Send data byte
  Wire.endTransmission();       // End communication
}

How to Use the Secondary I2C Bus (I2C1)

If you are running multiple devices with conflicting I2C addresses, you can split them across the two hardware buses. You initialize the Wire1 object by explicitly passing your chosen SDA and SCL pins into its begin() function.

#include <Wire.h>

// Define custom GPIO pins for the secondary I2C bus
const byte I2C1_SDA = D5;
const byte I2C1_SCL = D6;

void setup() {
  // Initialize the primary bus on default A4/A5
  Wire.begin();

  // Initialize the secondary bus on custom pins
  Wire1.begin(I2C1_SDA, I2C1_SCL);
}

void loop() {
  // Communicate over the secondary bus
  Wire1.beginTransmission(0x3C);
  Wire1.write(0x00);
  Wire1.endTransmission();
}

Note that Wire and Wire1 can run at the same time, which is handy when working with devices that share the same address.

Warning:

Whichever pins you use, remember to add external pull-up resistors, typically between 4.7 kΩ and 10 kΩ, on both the SDA and SCL lines. Relying only on the chip’s weak internal pull-ups (around 45 kΩ) can cause signals to rise too slowly on longer wires or higher-capacitance buses, leading to communication errors.

Arduino Nano ESP32 UART Pins

The Nano ESP32 has three hardware UART controllers: UART0, UART1, and UART2, plus a separate native-USB serial port.

arduino nano esp32 uart pins

UART0 is mainly used for the hardware console and low-level debugging. By default, UART0 is assigned to GPIO43 for TX and GPIO44 for RX. These pins are important because they output the ESP32-S3’s ROM bootloader messages and allow you to debug your code through a serial monitor. Reassigning these pins in your software is highly discouraged because doing so will completely disable your main debugging console.

UART1 is assigned by default to GPIO17 for TX and GPIO18 for RX. However, it can be moved to other GPIO pins via the GPIO Matrix.

UART2 is completely unassigned by default, which means you can map it to almost any GPIO pin through the GPIO Matrix.

The table below shows the default TX and RX pins for each UART controller on the Nano ESP32.

InterfaceArduino ObjectTXRXRemarks
Serial (native USB)SerialGPIO20 (D+)GPIO19 (D-)USB CDC console; not a UART peripheral. Uses differential data, not TX/RX.
UART0Serial0GPIO43 (D1)GPIO44 (D0)Hardware console and ROM bootloader output. Reassigning is discouraged.
UART1Serial1GPIO17GPIO18Completely free to be mapped to any GPIO.
UART2Serial2UnassignedUnassignedCompletely free to be mapped to any GPIO.

How to Use the Serial1 and Serial2 UART Ports

To use the unassigned UART controllers, you must define which pins you want them to use and pass those pins into the begin() function during setup. Here is an example of configuring both Serial1 and Serial2 on custom pins:

// Define custom GPIO pins for UART1
const byte RX1_PIN = D2;
const byte TX1_PIN = D3;

// Define custom GPIO pins for UART2
const byte RX2_PIN = D4;
const byte TX2_PIN = D5;

void setup() {
  // Initialize native USB for standard Serial Monitor debugging
  Serial.begin(115200);

  // Initialize Serial1 (Baud rate, Protocol, RX Pin, TX Pin)
  Serial1.begin(9600, SERIAL_8N1, RX1_PIN, TX1_PIN);
  
  // Initialize Serial2
  Serial2.begin(115200, SERIAL_8N1, RX2_PIN, TX2_PIN);
}

void loop() {
  // Example: Read data coming in from Serial1 and echo it out to Serial2
  if (Serial1.available()) {
    char incomingByte = Serial1.read();
    Serial2.print(incomingByte);
    
    // Also print to the native USB Serial Monitor for debugging
    Serial.print("Forwarded: ");
    Serial.println(incomingByte);
  }
}

Arduino Nano ESP32 SPI Pins

The Nano ESP32 contains four SPI controllers: SPI0, SPI1, SPI2, and SPI3.

arduino nano esp32 spi pins

SPI0 and SPI1 are strictly reserved for the chip’s internal Flash memory and PSRAM, which we discussed earlier. Therefore, you cannot use them. That leaves SPI2 and SPI3 fully available for your applications.

SPI2 is mapped to the default Arduino SPI object and its pins are pre-configured to match the classic Arduino Nano form factor layout.

SPI SignalArduino PinESP32-S3 GPIORemarks
SCK (Clock)D13GPIO 48Shared with the onboard built-in LED.
CIPO / MISO (RX)D12GPIO 47Controller In, Peripheral Out.
COPI / MOSI (TX)D11GPIO 38Controller Out, Peripheral In.
CS / SS (Chip Select)D10GPIO 21Default hardware chip select, though almost any free digital pin can be used as a software-controlled CS.

Finally, SPI3 is completely unassigned by default. You can freely map it to any available GPIO pin using the GPIO Matrix.

How to Use the Default SPI Bus

If you wire your peripheral to the standard Nano SPI pins (SCK = D13, MISO = D12, MOSI = D11), you can use the built-in SPI object. You simply call SPI.begin() without any parameters to initialize the bus.

#include <SPI.h>

// You can use almost any digital pin for Chip Select (CS)
const int CS = D10;

void setup() {
  pinMode(CS, OUTPUT);  // Configure the CS pin as an output
  SPI.begin();  // Initialize the default SPI bus
  digitalWrite(CS, LOW);  // Pull CS LOW to select the active device
  SPI.transfer(0x00);  // Transfer data
  digitalWrite(CS, HIGH);  // Pull CS HIGH to deselect the device and end communication
}

void loop() {
}

How to Use the Secondary SPI Bus

To the secondary SPI Bus, we need to create an object using SPIClass, and initialize communication on a specific set of pins.

#include <SPI.h>

// Define custom GPIO pins for the secondary SPI bus
#define SPI2_SCK D2
#define SPI2_CIPO D3
#define SPI2_COPI D4
#define SPI2_CS D5

// Create a new SPI object
SPIClass SPI2(HSPI);

void setup() {
  pinMode(CUSTOM_CS, OUTPUT);  // Configure the custom CS pin

  SPI2.begin(SPI2_SCK, SPI2_CIPO, SPI2_COPI, SPI2_CS);  // Initialize the secondary bus

  // Communicate over the secondary bus
  digitalWrite(CUSTOM_CS, LOW);
  hspi.transfer(0xAA);
  digitalWrite(CUSTOM_CS, HIGH);
}

void loop() {
}

Arduino Nano ESP32 I2S Pins

The Nano ESP32 features 2 hardware I2S controllers (I2S0 and I2S1) designed specifically for transferring high-fidelity, synchronized digital audio.

arduino nano esp32 i2s pins

There is one slightly confusing point about the pins. The Nano ESP32 datasheet says I2S does not have fixed pins and I2S signals can be safely routed to almost any available GPIO pin. However, the Nano ESP32 User Manual defines these convenient/default I2S pin macros:

I2S SignalArduino macroArduino PinESP32-S3 GPIODescription
BCLK / SCKPIN_I2S_SCKD7GPIO10Determines the data transfer speed.
WS / LRC / FSPIN_I2S_FSD8GPIO17Indicates whether the data is for the Left or Right audio channel.
Data OutPIN_I2S_SD, PIN_I2S_SD_OUTD9GPIO18Transmits audio data from the ESP32 to a DAC or amplifier.
Data InPIN_I2S_SD_IND10GPIO21Receives audio data from a microphone (e.g., INMP441).

How to Use I2S on the Nano ESP32

To use I2S on the Nano ESP32, include the <ESP_I2S.h> library provided by the ESP32 Arduino Core. You must use an I2SClass object specifically to stop colliding with Arduino’s I2S.h file and then call I2S.setPins() before initializing the bus to tell the microcontroller which pins you are using.

#include <ESP_I2S.h>

// Instantiate the Espressif I2S object
I2SClass i2s;

void setup() {
  Serial.begin(115200);

  // Map the I2S signals to Arduino macro
  // Syntax: setPins(BCLK, WS, DOUT, DIN)
  i2s.setPins(PIN_I2S_SCK, PIN_I2S_FS, PIN_I2S_SD_OUT, PIN_I2S_SD_IN);

  // Initialize the I2S bus
  if (!i2s.begin(I2S_MODE_STD, sampleRate, I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO)) {

    Serial.println("Failed to start I2S");
    while (1)
      ;
  }
}

void loop() {
  // Audio processing here
}

Note that for output-only use, this is enough:

i2s.setPins(PIN_I2S_SCK, PIN_I2S_FS, PIN_I2S_SD_OUT);

For an I2S microphone, you would instead use DIN:

i2s.setPins(PIN_I2S_SCK, PIN_I2S_FS, -1, PIN_I2S_SD_IN);  // no DOUT

And if you need both input and output simultaneously:

i2s.setPins(PIN_I2S_SCK, PIN_I2S_FS, PIN_I2S_SD_OUT, PIN_I2S_SD_IN);

How to Use Two I2S Controllers Simultaneously

Normally,

I2SClass i2s;

lets the driver automatically allocate an available controller (I2S_NUM_AUTO). The library also lets you explicitly select a controller.

I2SClass i2s0(I2S_NUM_0);
I2SClass i2s1(I2S_NUM_1);

You can then give them completely different pins:

i2s0.setPins(D7, D8, D9);
i2s1.setPins(D2, D3, D4);

Arduino Nano ESP32 PWM Pins

Every exposed GPIO pin on the Nano ESP32, including all digital pins (D0-D13) as well as all analog pins (A0-A7), can output a high-resolution PWM signal.

arduino nano esp32 pwm pins

The ESP32-S3 has 8 independent hardware PWM channels. This means you can output up to 8 completely different PWM signals simultaneously.

By default, the PWM resolution on the Nano ESP32 is set to 8 bits (values from 0 to 255) to maintain compatibility with classic Arduino code. However, the Nano ESP32 is more powerful and supports configurable resolution up to 14-bit (values from 0 to 16383) for incredibly precise control.

The default PWM frequency is set to 1 kHz, but it is fully adjustable up to tens of megahertz depending on the resolution you choose (higher frequency requires lower resolution).

Note:

Due to timer restrictions, only 5 PWM signals can be generated simultaneously on the Nano ESP32. Plan your pin usage accordingly if your project needs to drive more outputs than that at once.

How to Generate a PWM Signal

To generate a PWM signal, you first need to set the desired PWM pin as an output using the pinMode(pin, OUTPUT) function inside the setup() part of your sketch. After that, you use the analogWrite(pin, value) function to set the PWM output. In this function, pin is the PWM-capable pin number, and value controls the duty cycle.

const int PWM_PIN = D5;

void setup() {
  pinMode(PWM_PIN, OUTPUT);
}

void loop() {
  analogWrite(PWM_PIN, 64);   // About 25%
}

To change the frequency and resolution of the PWM signal, you use analogWriteFrequency() and analogWriteResolution() functions.

const int MOTOR_PIN = D5;

void setup() {
  pinMode(MOTOR_PIN, OUTPUT);
  
  // Set the PWM frequency to 5 kHz (good for many motor drivers)
  analogWriteFrequency(5000);
  
  // Set the resolution to 12-bit (Values from 0 to 4095)
  analogWriteResolution(12);
}

Arduino Nano ESP32 TWAI (CAN) Pins

The Nano ESP32 features a single hardware CAN controller. Espressif refers to their CAN peripheral as TWAI (Two-Wire Automotive Interface), but it is fully compatible with the classic ISO 11898-1 (CAN Specification 2.0B) standard.

Because standard CAN bus speeds go up to 1 Mbps, the TWAI signals (TX, RX, BUS-OFF, and CLKOUT) can be routed through the GPIO Matrix to any available pin on the board without any problem.

Note:

The Nano ESP32 only includes a built-in CAN-compatible controller, but it does not include a CAN transceiver. The controller produces ordinary 3.3 V TX/RX logic signals rather than the differential CANH and CANL signals used on a real CAN bus. Therefore, to safely connect your Nano ESP32 to a CAN bus, you must use an external 3.3V CAN transceiver chip such as the SN65HVD230.

Arduino Nano ESP32 USB Interface

One of the greatest advantages of the Nano ESP32 is its native USB controller. Because of this, the board does not have a separate UART-to-USB bridge chip, such as the CP2102 or CH340, to communicate with a computer.

This native USB stack also lets the Nano ESP32 directly emulate USB HID devices, such as a physical keyboard and mouse, without any extra hardware.

Arduino Nano ESP32 Onboard LEDs

The board carries three onboard LEDs:

arduino nano esp32 onboard leds

Power LED (green) is wired directly to the 3.3V rail and lights up whenever the board is powered. It isn’t connected to a GPIO and can’t be controlled from your sketch.

Status LED (yellow/amber) is driven by GPIO48, the same pin as D13/SCK, and is accessible in code as LED_BUILTIN.

RGB LED sits next to the reset button and is built from three individual LEDs, each wired to its own GPIO and referenced in code as LED_RED, LED_GREEN, and LED_BLUE:

ColorGPIONotes
RedGPIO46 (B0 / D14)Shared with the BOOT0 strapping pin
GreenGPIO0 (B1 / D16)Shared with the BOOT1 strapping pin
BlueGPIO45 (D15)Not broken out on the headers

These LEDs are active-low, meaning you need to write LOW to turn a color on:

digitalWrite(LED_RED, LOW); // turns red on

Warning:

A limited number of early-production Nano ESP32 boards were assembled with an RGB LED that has its green and blue channels physically swapped. If your board’s RGB LED looks blue instead of green during bootloader mode (or yellow instead of purple), you likely have one of these units. Arduino’s Help Center has a dedicated article covering how to identify and work around this.

Arduino Nano ESP32 Power Pins

The Nano ESP32 has several power pins. These pins allow you to power the board in different ways, and some of them can also provide power to sensors, modules, and other external components.

arduino nano esp32 power pins

To help you understand how the power flows through the board, here is a simplified block diagram of the power tree:

arduino nano esp32 power tree

USB-C connector provides the easiest way to power the Nano ESP32. You can connect it to a computer, a USB power adapter, or another suitable USB power source. Arduino specifies a typical USB supply of 5 V, with a recommended operating range of 4.8 V to 5.5 V. You should not intentionally supply a voltage higher than this range through the USB-C connector. The USB voltage is regulated down to a stable 3.3 V by the MP2322GQH step-down converter, which then powers the ESP32-S3 and other parts of the board.

VIN pin allows you to power the Nano ESP32 from an external DC power source instead of using USB. The input voltage range for VIN is typically 6V to 21V. Just like power from the USB connector, power entering through VIN is reduced to 3.3 V by the MP2322GQH step-down converter. It’s important to note that the converter becomes less efficient as the input voltage increases. Arduino provides the following approximate efficiency figures for the converter:

Input VoltageTypical Efficiency
4.5 V>90%
12 V85-90%
18 V<85%

VBUS is this board’s replacement for the classic Nano “5 V” pin. There is no dedicated 5 V pin on the Nano ESP32. VBUS outputs 5 V only when the board is plugged in via USB-C. If you are powering your board using the VIN pin instead, VBUS is disabled, meaning you will need a separate 5 V supply or a logic level shifter for any 5V peripherals.

Note:

You might also see VBUS labeled as VUSB in some of the official manuals or schematics, but do not let that confuse you, as they are the exact same pin.

3V3 is the regulated output of the MP2322GQH step-down converter. You can use this pin to power external components. You must be careful not to overload this pin. The ESP32-S3 itself can pull several hundred mA during Wi-Fi transmission bursts. If your external sensors are also drawing too much power from the 3V3 pin at the exact same time, the voltage can suddenly drop. This sudden drop is called a brownout, and it will cause your board to become unstable, lose its Wi-Fi connection, or completely restart.

3.3V Solder Jumper

If you flip the board over, you’ll find a tiny solder jumper labelled “3.3V”.

arduino nano esp32 3v3 solder jumper

If you cut the small trace between the two pads, you disconnect the step-down converter from the board, and your board will no longer be powered normally through the USB-C connector or the VIN pin. Instead you must supply a properly regulated 3.3 V source directly to the 3V3 pin.

arduino nano esp32 power tree after the 3v3 jumper is cut

This can, depending on your power source, be a more energy efficient method of powering your board than powering through the VIN pin or the USB port.

Note:

Once the jumper is cut, the board cannot be powered via USB, and you won’t be able to use USB to upload sketches until that connection is fixed. To undo this later, you can simply bridge the two pads back together with a bit of solder.

Arduino Nano ESP32 Control Pins

arduino nano esp32 control pins

RESET (RST) pin and RESET button restarts the currently uploaded sketch, just like on any other Arduino board.

The reset button also has another useful function. If you double-press the RESET button, the Nano ESP32 enters Arduino Bootloader Mode. This is a recovery mode you can use if a sketch causes the board to freeze or act strangely. For example, the sketch might stop your PC from recognizing the board, or it might be an HID sketch that has taken control of your keyboard and mouse, and you need to regain control of your computer. This mode allows you to turn the board on without actually running any sketch.

To enter this mode, press the RESET button twice, with roughly 0.3 to 1 second between the two presses. When the onboard RGB LED begins to pulse slowly in green, the board is in bootloader mode and is ready for a new sketch to be uploaded.

B0 (GPIO46) and B1(GPIO0) are the same strapping pins described earlier, and can also be used to manually force the chip into Firmware Download Mode, where firmware can be written directly to the chip. This is another recovery method if the Arduino Bootloader Mode does not work. To use it, connect B1 to GND, press and release the RESET button, and then disconnect B1 from GND.

B0 pin is normally not needed when entering firmware download mode on the Nano ESP32. However, using it together with B1 can affect how the processor starts. For this reason, B0 and B1 should be used carefully when the board is being reset.

Amrit Prabhu

Amrit Prabhu

Amrit is an Electronics Engineer who loves making complex programming and hardware concepts accessible. He has more than 15 years of experience, having worked as a Senior Programmer Analyst at Mindtree Ltd. and Symantec on major projects like Windows 8, Wolters Kluwer CCH and NSE. Since 2018, he has authored hundreds of tutorials and guides for Last Minute Engineers, helping readers master everything from basic circuits to IoT. You can find him on LinkedIn