Arduino Nano ESP32 Cheat Sheet
A technical summary of the Nano ESP32 development board, including installation, pin reference, communication ports and microcontroller specifics.
The Arduino Nano ESP32 is the first Arduino to feature an ESP32 SoC as its main microcontroller, based on the ESP32-S3. This SoC is found inside the u-blox® NORA-W106 module and provides both Bluetooth® & Wi-Fi® connectivity, as well as embedding an antenna.
In this document, you will find information regarding features of the board, and links to resources.
Note that this board is compatible with many ESP32 examples out of the box, but that the pinout may vary. You can find the complete API at ESP32-S3 API reference.
NORA-W106 (ESP32-S3)
The Nano ESP32 features the ESP32-S3 system on a chip (SoC) from Espressif, which is embedded in the NORA-W106 module. The ESP32-S3 has a dual-core microprocessor Xtensa® 32-bit LX7, and has support for the 2.4 GHz Wi-Fi® band as well as Bluetooth® 5. The operating voltage of this SoC is 3.3 V.
The NORA-W106 also embeds an antenna for Bluetooth® and Wi-Fi® connectivity.
Memory
The Nano ESP32 has
- 384 kB ROM
- 512 kB SRAM
- 16 MB of Flash (external, provided via GD25B128EWIGR)
- 8 MB of PSRAM
Datasheet
The full datasheet is available as a downloadable PDF from the link below:
Arduino ESP32 Board Package
This board is based on the Arduino ESP32 Board Package, that is derived from the original ESP32 Board Package. It provides a rich set of examples to access the various features on your board, which is accessed directly through the IDE.
To install the Board Package, go the board manager and search for Nano ESP32. For more detailed instructions to install the Board Package, please refer to the Getting Started with Nano ESP32 article.
ESP32 Pin Map
The Nano ESP32's default pins are designed to match the Nano form factor. This pin mapping is done in the official Arduino ESP32 Board Package (see just above). See below the pin map to understand how the physical pins correlate to the ESP32:
Nano | ESP32 |
---|---|
D0 | GPIO44 |
D1 | GPIO43 |
D2 | GPIO5 |
D3 | GPIO6 |
D4 | GPIO7 |
D5 | GPIO8 |
D6 | GPIO9 |
D7 | GPIO10 |
D8 | GPIO17 |
D9 | GPIO18 |
D10 | GPIO21 |
D11 | GPIO38 |
D12 | GPIO47 |
D13 | GPIO48 |
A0 | GPIO1 |
A1 | GPIO2 |
A2 | GPIO3 |
A3 | GPIO4 |
A4 | GPIO11 |
A5 | GPIO12 |
A6 | GPIO13 |
A7 | GPIO14 |
BOOT0 | GPIO46 |
BOOT1 | GPIO0 |
See the pinout below for a better visual translation:
Arduino Bootloader Mode
The Nano ESP32 has a feature that we call Arduino Bootloader-mode, what this means is that you are able to put the board in a sort of recovery mode by double pressing the reset button while the board is powered on.
This mode is useful if you've uploaded a sketch that produces some unwanted behaviour. Maybe the sketch causes it to become undetectable by your computer, or maybe its an HID sketch that took over your keyboard and mouse and you need to regain control of your computer. It lets you turn the board on without actually running any sketch.
To enter bootloader-mode, press the reset button, and then press it again once you see the RGB LED flashing. You'll know that you've successfully entered bootloader-mode if you see the green LED pulsing slowly.
Some boards from the first limited production batch were assembled with a different RGB LED which has the green and blue pins inverted. Read our full Help Center article here
ROM Boot Mode
In addition to the normal bootloader-mode, the Arduino Nano ESP32 lets you enter ROM boot mode. This is rarely needed, but there are some cases where it might be useful, for example you may want to follow this process to:
- Update the Arduino bootloader already on the board. This can resolve issues with Nano ESP32 being misidentified as other ESP32 boards.
- Restore the ability to upload regular Arduino sketches to a Nano ESP32 that has been flashed with a third party firmware.
If you need to reflash the bootloader, you can follow the steps of this Help Center article
Default Sketch
The default sketch loaded on the Nano ESP32 board is found in the code snippet below:
1void setup() {2 // put your setup code here, to run once:3 pinMode(LED_RED, OUTPUT);4 pinMode(LED_GREEN, OUTPUT);5 pinMode(LED_BLUE, OUTPUT);6 pinMode(LED_BUILTIN, OUTPUT);7}8
9void loop() {10 digitalWrite(LED_BUILTIN, HIGH);11 digitalWrite(LED_RED, LOW);12 digitalWrite(LED_GREEN, HIGH);13 digitalWrite(LED_BLUE, HIGH);14
15 delay(1000);16
17 digitalWrite(LED_BUILTIN, LOW);18 digitalWrite(LED_RED, HIGH);19 digitalWrite(LED_GREEN, LOW);20 digitalWrite(LED_BLUE, HIGH);21
22 delay(1000);23
24 digitalWrite(LED_BUILTIN, HIGH);25 digitalWrite(LED_RED, HIGH);26 digitalWrite(LED_GREEN, HIGH);27 digitalWrite(LED_BLUE, LOW);28
29 delay(1000);30 digitalWrite(LED_BUILTIN, LOW);31}
MicroPython
The Nano ESP32 has support for MicroPython, a micro-implementation of Python® that can easily be installed on your board.
To get started with MicroPython, please visit MicroPython 101, a course dedicated towards learning MicroPython on the Nano ESP32.
In this course, you will fundamental knowledge to get started, as well as a large selection of examples for popular third-party components.
Reset Your Board
If you have installed MicroPython but wish to go back to classic Arduino / C++ programming, it is easy to do so. Simply double tap the RESET button on the board (there's only one button). The board will enter boot mode (you should see a pulsing green light), and will be visible in the Arduino IDE.
Arduino Cloud
Nano ESP32 is supported in the Arduino Cloud platform. You can connect to the Cloud either through "classic" Arduino, using the C++ library, or via MicroPython:
API
The Nano ESP32 can be programmed using the same API as for other Arduino boards (see language reference).
However, the ESP32 platform provides additional libraries and built-in functionalities that may not available in the standard Arduino API.
For more information, see the ESP32-S3 API
Peripherals API
To learn more about the ESP32-S3's peripherals (e.g. ADC, I2C, SPI, I2S, RTC), refer to the Peripherals API section.
Sleep Modes
The Nano ESP32 can be programmed to draw a minimal amount of power, making it suitable for power constrained designs, such as solar/battery powered projects.
The Sleep Modes section in the ESP32 docs explains how to configure your board to draw minimal power, introducing the light sleep and deep sleep
Power Considerations
To power the Nano ESP32 you may either use a USB-C® cable, or the VIN pin. When using the VIN pin, use voltages within the range of 5-18 V as the MP2322GQH converter on the board may otherwise be damaged.
Input Voltage (VIN)
- If you're using the USB-C® connector you must power it with 5 V.
- The recommended input voltage on the VIN pin is 6-21 V.
If you flip the board to view its underside, you'll find a solder jumper labelled "3.3V". 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 turn on when plugged in to the USB port, or when its powered through the VIN pin. Instead you must provide exactly 3.3 V directly to the 3.3 V pin of your board. 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.
Operating Voltage
The internal operating voltage of the ESP32-S3 SoC is 3.3 V, and you should not apply voltages higher than that to the GPIO pins.
5V Pin / VBUS
The Nano ESP32 is the first board to not feature a 5V pin. It has instead been replaced with VBUS, which is a more accurate description of the pin's capabilities.
VBUS
provides 5 V whenever powered via USB. If powered via the VIN pin, it is disabled. This means that while powering the board through the VIN pin, you can't get 5 V from the board, and you need to use a logic level shifter or an external 5 V power supply.This measure is taken to prevent the board's microcontroller from accidentally receiving 5 V, which will damage it.
Pins
The Nano ESP32 has two headers: the analog and digital. Listed here are the default pins that comply with previous Nano form factor designs.
The following pins are available on the board:
Pin | Type | Function |
---|---|---|
D13/SCK | Digital | SPI Serial Clock / LED Built in |
D12/CIPO | Digital | SPI Controller In Peripheral Out |
D11/COPI | Digital | SPI Controller Out Peripheral In |
D10 | Digital | GPIO |
D9 | Digital | GPIO |
D8 | Digital | GPIO |
D7 | Digital | GPIO |
D6 | Digital | GPIO |
D5 | Digital | GPIO |
D4 | Digital | GPIO |
D3 | Digital | GPIO |
D2 | Digital | GPIO |
D1/RX | Digital | GPIO 1 / UART Receiver (RX) |
D0/TX | Digital | GPIO 0 / UART Transmitter (TX) |
A0 | Analog | Analog input 0 |
A1 | Analog | Analog input 1 |
A2 | Analog | Analog input 2 |
A3 | Analog | Analog input 3 |
A4 | Analog | Analog input 4 / I2C Serial Datal (SDA) |
A5 | Analog | Analog input 5 / I2C Serial Clock (SCL) |
A6 | Analog | Analog input 6 |
A7 | Analog | Analog input 7 |
Note that all pins can be used as GPIO, due to the ESP32's flexibility.
Digital
The Nano ESP32 has 14 digital pins (D0-D13), that can be read by using
digitalRead()
or written to using digitalWrite()
.Pin | Type | Function |
---|---|---|
D13/SCK | Digital | SPI Serial Clock / LED Built in |
D12/CIPO | Digital | SPI Controller In Peripheral Out |
D11/COPI | Digital | SPI Controller Out Peripheral In |
D10 | Digital | GPIO |
D9 | Digital | GPIO & RX1 |
D8 | Digital | GPIO & TX1 |
D7 | Digital | GPIO |
D6 | Digital | GPIO |
D5 | Digital | GPIO |
D4 | Digital | GPIO |
D3 | Digital | GPIO |
D2 | Digital | GPIO |
D0/RX | Digital | GPIO 0 / UART Receiver (RX0) |
D1/TX | Digital | GPIO 1 / UART Transmitter (TX0) |
Note that all analog pins can be used as digital pins as well, but not vice versa.
Analog
There are 8 analog input pins on the Nano ESP32, with 2 reserved for I2C communication (A4/A5). The ESP32-S3 embeds two SAR ADCs,
ADC1
and ADC2
, where each ADC uses 4 channels each. Pin | Type | Function | ADC channel |
---|---|---|---|
A0 | Analog | Analog input 0 |
|
A1 | Analog | Analog input 1 |
|
A2 | Analog | Analog input 2 |
|
A3 | Analog | Analog input 3 |
|
A4 | Analog | Analog input 4 / I2C Serial Datal (SDA) |
|
A5 | Analog | Analog input 5 / I2C Serial Clock (SCL) |
|
A6 | Analog | Analog input 6 |
|
A7 | Analog | Analog input 7 |
|
Please note that
is also used for Wi-Fi® communication and can fail if used simultaneously.ADC2
For more details, see Analog to Digital Converter (link to Espressif docs).
PWM
Pulse width modulation (PWM) is supported on all digital pins (D0-D13) as well as all analog pins (A0-A7), where the output is controlled via the
analogWrite()
method. 1analogWrite(pin,value);
Due to timer restrictions, only 5 PWM signals can be generated simultaneously.
I2C
The default pins used for the main I2C bus on the Nano ESP32 are the following:
Pin | Function | Description |
---|---|---|
A4 | SDA | I2C Serial Data |
A5 | SCL | I2C Serial Clock |
To connect I2C devices you will need to include the Wire library at the top of your sketch.
1#include <Wire.h>
Inside
void setup()
you need to initialize the library, and initialize the I2C port you want to use.1Wire.begin() //SDA & SDL
And to write something to a device connected via I2C, we can use the following commands:
1Wire.beginTransmission(1); //begin transmit to device 12Wire.write(byte(0x00)); //send instruction byte 3Wire.write(val); //send a value4Wire.endTransmission(); //stop transmit
Second I2C Bus
The Nano ESP32 has a second I2C bus, accessed via
Wire1
. To use it, you will need to set two free pins for SDA & SCL.For example:
1//initializes second I2C bus on pins D4,D52Wire1.begin(D4, D5); //sda, scl
and Wire
can be used simultaneously, a great feature when working with devices that may share the same addresses.Wire1
SPI
The Nano ESP32's SPI pins are listed below:
Pin | Function | Description |
---|---|---|
D10* | CS | Chip Select |
D11 | COPI | Controller Out, Peripheral In |
D12 | CIPO | Controller In, Peripheral Out |
D13 | SCK | Serial Clock |
*Any GPIO can be used for chip select.
The following example shows how to use SPI:
1#include <SPI.h>2
3const int CS = 10;4
5
6void setup() {7 pinMode(CS, OUTPUT);8
9 SPI.begin();10
11 digitalWrite(CS, LOW);12
13 SPI.transfer(0x00);14 15 digitalWrite(CS, HIGH);16}17
18void loop() {19}
Second SPI Port (HSPI)
The Nano ESP32 has a second SPI port (HSPI). To use it, we need to create an object using
SPIClass
, and initialize communication on a specific set of pins.The HSPI port's default pins are:
(SCK), GPIO14
(CIPO), GPIO12
(COPI), GPIO13
(CS). As some of these pins are not accessible on the Nano ESP32, you will need to configure them manually. See the definitions at the top of the code example below.GPIO15
1//define SPI2 pins manually2//you can also choose any other free pins3#define SPI2_SCK D24#define SPI2_CIPO D35#define SPI2_COPI D46#define SPI2_CS D57
8//create SPI2 object9SPIClass SPI2(HSPI);10
11void setup() {12//initialize SPI communication13 SPI2.begin(SPI2_SCK, SPI2_CIPO, SPI2_COPI, SPI2_CS);14}
USB Serial & UART
The Nano ESP32 board features 3 hardware serial ports, as well as a port exposed via USB.
refers to the USB port.Serial
refers to the first hardware serial port (UART), accessible via the board's RX/TX pins (D0, D1).Serial0
is the second UART port, which can be assigned to any free GPIOs.Serial1
is the third UART port, which can also be assigned to any free GPIOs.Serial2
Serial (Native USB)
Sending serial data to your computer is done using the standard
Serial
object.1Serial.begin(9600);2Serial.print("hello world");
To send and receive data through UART, we will first need to set the baud rate inside
void setup()
.Serial0 (UART)
Please note:
is shared with the bootloader/kernel, which prints a few messages at boot/reset, and in the event of a crash, the crash dumps is printed via FreeRTOS on this serial port. For these reasons, you may want to use the Serial0
or Serial1
ports to avoid any interference (read more).Serial2
The default pins for UART communication on the Nano ESP32 are the following:
Pin | Function | Description |
---|---|---|
D0 | RX | Receive Serial Data |
D1 | TX | Transmit Serial Data |
To send and receive data through UART, we will first need to set the baud rate inside
void setup()
. Note that when using the UART (RX/TX pins), we use the Serial0
object.1Serial0.begin(9600);
To read incoming data, we can use a while loop() to read each individual character and add it to a string.
1while(Serial0.available()){2 delay(2);3 char c = Serial0.read();4 incoming += c;5 }
And to write something, we can use the following command:
1Serial0.write("Hello world!");
Serial1 & Serial2 (UART)
The Nano ESP32 features 2 additional hardware serial ports that have no pre-defined pins, and can be connected to any free GPIO. Therefore, to use them, their TX and RX pins need to be manually assigned.
To use
Serial1
and Serial2
, you need to initialize them in your program's setup()
function:1//initialization2Serial1.begin(9600, SERIAL_8N1, RX1PIN, TX1PIN);3Serial2.begin(9600, SERIAL_8N1, RX2PIN, TX2PIN);4
5//usage6Serial1.write("Hello world!");7Serial2.write("Hello world!");
- Replace
andRXPIN
with the GPIOs you want to assign (e.g.TXPIN
,D4
).D5
- You can then use commands such as
andSerial1.write()
.Serial1.read()
The
SERIAL_8N1
parameter is the configuration for serial communication.
= data word length (8-bit). Can be changed to 5,6,7-bits.8
= parity, in this case "none". Can be changed to "even" (E) or "odd" (O).N
= stop bit, other option available is 2.1
I2S
The Inter-IC Sound (I2S or IIS) protocol is used for connecting digital audio devices with a variety of configurations (Philips mode, PDM, ADC/DAC).
The default pin configuration for I2S is:
Pin | Definition |
---|---|
D7 |
|
D8 |
|
D9 |
|
D9 |
|
D10 |
|
The default pins can be changed by using the
setAllPins()
method:1I2S.setAllPins(sck, fs, sd, sd_out, sd_in)
To inialitize the library, use the
begin()
method: 1I2S.begin(mode, sampleRate, bitPerSample)
To read data, use the
read()
method, which will return the last sample.1I2S.read()
Examples for different modes & different audio devices are available in the Board Package under Examples > I2S.
Further reading:
Dual Core
The ESP32-S3 is based on the dual-core XTensa LX7, which can run code separately on two cores. This is enabled through FreeRTOS, by setting up tasks that run on each core (similarly to how
void loop()
is implemented). The cores available are 0
and 1
.The example below is a modified version of the BasicMultiThreading example found in the Arduino ESP32 Board Package, and demonstrates how to use two common operations simultaneously:
- Blink an LED using one task on a specific core (0),
- Read an analog pin using a second task on a specific core (1).
1/* Basic Multi Threading Arduino Example2 3 Modified 16th October 2023 by Karl Söderby4
5 Set up two tasks that run on each core of a Nano ESP32 (ESP32-S3 XTensa LX7 MCU),6 one that blinks an LED, one that reads an analog signal.7
8 These tasks will execute infinitely.9
10 This example code is in the Public Domain (or CC0 licensed, at your option.)11 Unless required by applicable law or agreed to in writing, this12 software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR13 CONDITIONS OF ANY KIND, either express or implied.14*/15
16// Define the cores17#define CORE_0 018#define CORE_1 119
20#define ANALOG_INPUT_PIN A0 //Specify analog pin21#define LED_BUILTIN 13 // Specify the on which is your LED22
23
24int counter = 0;25// Define two tasks for Blink & AnalogRead.26void TaskBlink(void *pvParameters);27void TaskAnalogRead(void *pvParameters);28TaskHandle_t analog_read_task_handle; // You can (don't have to) use this to be able to manipulate a task from somewhere else.29
30void setup() {31 Serial.begin(115200);32 uint32_t blink_delay = 1000; // Delay between changing state on LED pin33
34 //create task for blinking an LED35 xTaskCreatePinnedToCore(36 TaskBlink, "Task Blink" // A name just for humans37 ,38 2048 // The stack size can be checked by calling `uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);`39 ,40 (void *)&blink_delay // Task parameter which can modify the task behavior. This must be passed as pointer to void.41 ,42 2 // Priority43 ,44 NULL // Task handle is not used here - simply pass NULL45 ,46 CORE_0 // Core on which the task will run47 );48
49 //create a task for reading analog signals50 xTaskCreatePinnedToCore(51 TaskAnalogRead, "Analog Read", 2048 // Stack size52 ,53 NULL // When no parameter is used, simply pass NULL54 ,55 1 // Priority56 ,57 &analog_read_task_handle // With task handle we will be able to manipulate with this task.58 ,59 CORE_1 // Core on which the task will run60 );61}62
63void loop() {64 //loop is empty, the tasks are instead looped infinitely65}66
67void TaskBlink(void *pvParameters) { // This is a task.68 uint32_t blink_delay = *((uint32_t *)pvParameters);69
70 pinMode(LED_BUILTIN, OUTPUT);71
72 for (;;) { // A Task shall never return or exit.73 counter++;74 digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)75
76 delay(1000);77 digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW78
79 delay(1000);80 Serial.print("Core ");81 Serial.print(CORE_0);82 Serial.print(": Blink task complete. Times run: ");83 Serial.println(counter);84 }85}86
87void TaskAnalogRead(void *pvParameters) { // This is a task.88 (void)pvParameters;89
90 for (;;) {91 // read the input on analog pin:92 int sensorValue = analogRead(ANALOG_INPUT_PIN);93 // print out the value you read:94 Serial.print("Core ");95 Serial.print(CORE_1);96 Serial.print(": Analog reading task, value is: ");97 Serial.println(sensorValue);98 delay(500); // 100ms delay99 }100}
When running this example, open the Serial Monitor tool and you will see what happens on each core.
- The task is created in the
,xTaskCreatePinnedToCore()
- inside
we specify a number of parameters, most importantly what core and what function to run,xTaskCreatePinnedToCore()
- code inside task functions are placed inside the
statement, that will loop infinitely.for (;;){}
More information about dual-core on the ESP32 along with a detailed explanation of the example is available at Basic Multi Threading Example.
IO Mux & GPIO Matrix
The ESP32-S3 SoC features an IO mux (input/output multiplexer) and a GPIO matrix. The IO mux acts as a data selector and allows for different peripherals to be connected to a physical pin.
The ESP32-S3 chip has 45 physical GPIOs, but many more digital peripherals. The IO mux provides the flexibility of routing the signals to different GPIOs, thus changing the function of a specific pin.
This technique is well known and applied within ESP32 boards, but on the Nano ESP32 we use a set of default pins for the I2C, SPI & UART peripherals to remain consistent with previous designs.
As an example, the Nano ESP32's SDA/SCL pins are attached to A4/A5 by default. These pins can be changed to e.g. D8,D9 if you need to use another set of pins. This is done through the mux / GPIO matrix.
Re-Assigning Pins
You can read more about re-assigning the peripherals through the links below:
You can also read Espressifs technical reference manual here:
Wi-Fi®
The Nano ESP32 has a NORA-W106 module which has the ESP32-S3 SoC embedded. This module supports Wi-Fi® communication over the 2.4 GHz band.
There are several examples provided bundled with the Board Package that showcase how to make HTTP requests, host web servers, send data over MQTT etc.
RGB
The ESP32 features an RGB LED that can be controlled with the
LED_RED
, LED_GREEN
and LED_BLUE
pin names. These pins are not accessible on the headers of the board, and can only be used for the RGB LED. Some boards from the first limited production batch were assembled with a different RGB LED which has the green and blue pins inverted. Read our full Help Center article here
To control them, use:
1digitalWrite(LED_RED, STATE); //red2digitalWrite(LED_GREEN, STATE); //green3digitalWrite(LED_BLUE, STATE); //blue
These pins are so called active-low, what this means in practice is that to turn on one of the LEDs, you need to write it to
LOW
, like this:1digitalWrite(LED_RED, LOW);
USB HID
Nano ESP32 can be used to emulate an HID device by using e.g.
Mouse.move(x,y)
or Keyboard.press('w')
.These are minimal examples for keyboard and mouse use:
Keyboard Example
1#include "USB.h"2#include "USBHIDKeyboard.h"3USBHIDKeyboard Keyboard;4
5void setup() {6 // put your setup code here, to run once:7 Keyboard.begin();8 USB.begin();9}10
11void loop() {12 // put your main code here, to run repeatedly:13 Keyboard.print("Hello World");14 delay(500);15}
Mouse Example
1#include "USB.h"2#include "USBHIDMouse.h"3USBHIDMouse Mouse;4
5void setup() {6 // put your setup code here, to run once:7 Mouse.begin();8 USB.begin();9}10
11void loop() {12 // put your main code here, to run repeatedly:13 Mouse.move(5, 0, 0); 14 delay(50);15}
Several ready to use examples are also available in the Board Package at Examples > USB.
Remember that if the board stops being recognised in the IDE, you can put it in Arduino Bootloader Mode to recover it.
Suggest changes
The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.
License
The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.