DIY Projects

ESP32, GPIO pins and associated functions. I/O, PWM, RTC, I2C, SPI, ADC, DAC

The ESP32 is a micro-controller which has WiFi and Bluetooth connectivity (BLE, BT4.0 and Bluetooth Smart) as well as a GPIO. The pins are multi-function, ie it is possible to define its use by programming. I/O, PWM, RTC, I2C, SPI, ADC, DAC. You may have noticed that development boards have a more limited number of pins. Some pins are reserved (access to flash memory, programming, etc.). Each development board manufacturer chooses which pins they display.


The ESP32 is available in 46 versions currently. The trend is expected to increase further in the future as announced by Espressif on this blog post announcing the launch of the ESP32-C3. We clearly end up getting lost! Fortunately Espressif has put online a search engine for designers of connected objects and Makers who design their own PCBs.

This article summarizes the pins that can be used – regardless of the manufacturer of your ESP32 development board – to access the various functions offered by the ESP32. I2C port, I2S, UART (serial port), Touch (capacitive key) …

The pins available on the development boards are different for each manufacturer and depend on the equipment on board the board (LoRa radio module, GSM module, GPS, screen OLED SSD1306, micro-SD card reader …)

This article takes into account the technical specifications of the latest generation of ESP32 DevkitC v4 card. Please feel free to point out any errors or clarifications in the comments.

Quick access to themes:

How to interpret the pin number on your development board?

You have probably noticed that the number of pins of the GPIO expansion connector varies from manufacturer to manufacturer. First, some pins are reserved for access to flash memory through the SPI bus. Then, each manufacturer chooses the pins that it leaves available (exposes) to the user (developer) according to its own design and the equipment integrated into the development board (OLED screen, sensor, camera, micro card reader SD …).

The majority of consumer ESP32 development board manufacturers mainly use two versions:

Whatever the device, you will need to add additional external flash memory on which the program will be stored (developed with the Arduino IDE) and possibly other data (HTML interface, audio files, images, configuration files, etc.). As we will see later in the article, some pins of the ESP32 are reserved for communicating with Flash memory.

  ESP32-D0WDQ6-V3 ESP32-D0WD
Housing (mm) QFN 6×6 QFN 5×5
Brooches 48 pins + GND (49)

ROM 448 No

SAM 520 Ko


Working voltage 2.3 V to 3.6 V
GPIO x34
ADC converter Up to 18 channels. 9 to 12 bit resolution
DAC converter 2 8-bit channels
I2C x2
I2S x2
SPI x4
Security 1024 bit OTP


Secure Boot, Flash Encryption

Operation -40°C to 125°C

Source: Espressif technical documentation

As you can see, there is no need to worry too much. Espressif has ensured the compatibility of the pins whatever the case and whatever the generation. The difference is mainly found in the amount of flash memory or PSRAM (memory extension of the processor of the ESP32) associated.


The ESP42-PICO-D4 is a version that combines on a single chip an ESP32 SoC, a crystal oscillator, filter capacitors, as well as 4MB of flash memory in a single 7x7mm QFN package. With its very small footprint, it is particularly well suited to mobile applications (connected watches, bracelet and activity tracker, etc.).


This generation launched in 2028 is still available in the Espressif catalog. You might find it on many entry-level development boards.

Pin identification

Since version 4 of the official Espressif development kit, the pins are numbered in the form GPIO27 or simply by the corresponding number on the board, here 27.

The GPIO pin does not match the pin on the ESP32 processor which is located under a metal cover. For example pin 27 of the GPIO is connected to pin 16 of the SoC

It does not matter at the programming level. We never refer to the pin on the processor but this can be confusing … especially with the generations and versions that follow one another.

If you have an older generation board (or the manufacturer has not yet sold all of these stocks), the GPIO pins are preceded by IO, for example IO27.

It’s even simpler than with the SDK for ESP8266 because you just need to indicate the pin number in the Arduino code. For example :

pinMode(27, OUTPUT);

Before detailing more precisely the functions of each spindle, here is the marking of the last generation (DevKitC v4)


ESP32 digital I/O pins

The majority of the ESP32 pins can be used as a digital input or output. Some pins are reserved or are used by the processor. For example pins 6 to 11 are reserved for access to flash memory via the SPI bus, the pins of the serial port for uploading the program or debugging

The pins framed in green can be used for digital input or output as well.

The pins framed in orange can be used but beware of unexpected behavior at startup (see explanations in the table).

It is not recommended – not to say prohibited – to use the pins framed in red. Usually these pins are reserved (and used) by the ESP32 processor. So you may run into serious problems using these pins in your projects.

GPIO pin Digital input Digital output Note
0 PULL UP Sends a PWM signal at startup.
1 TX Debug output at startup
2 Connected to the on-board LED
3 RX Takes the HIGH state at startup
5 Sends a PWM signal at startup
12 Fail to start if in PULLUP mode
14 Sends a PWM signal at startup
15 Sends a PWM signal at startup
34 x
35 x
36 x
39 x

Pins 37 and 38 are not available on most ESP32 development boards. Pins 34, 35, 36, 37, 38, and 39 can only be used as digital input.

Data collected from official documentation.

Follow this more detailed tutorial to learn how to use the digital inputs and outputs of the ESP32.

PWM outputs

The ESP32 has 16 independent channels which can be configured to generate PWM signals with different properties. All pins framed in green in the previous table can be used as a PWM pin.

Spindle to avoid (prohibited) in your projects

Some GPIO pins automatically go HIGH or output PWM signals when starting up or during reset. You may experience unexpected results in your programs when the ESP32 resets or starts up.

Spindle (GPIO) Particularity, precaution to be taken
0 Sends a PWM signal at startup.

Pin  0  is used as the boot pin and must be low to enter UART download mode. Make sure it is not pulled down by a device while booting or the firmware will not boot!

1 Debug output at startup
2 Pin  2  is used as the boot pin and must be low to enter UART download mode. Make sure it is not pulled up by a device during boot or you will not be able to flash any firmware on the module!
3 Takes the HIGH state at startup
5 Sends a PWM signal at startup
6 Used for SPI flash memory
12 Startup failure if in PULL-UP mode

Pin 12 is used as the boot pin to select the output voltage of an internal regulator that powers the flash chip (VDD_SDIO). This pin has an internal pull-down resistor. If it is not connected, it will display a low level when resetting (selection of default 3.3V operation). Make sure it is not pulled up by a device during boot or the ESP32 might not boot.

14 Sends a PWM signal at startup
15 Sends a PWM signal at startup

Pin 15 can be used to stop the debug output during the startup phase. If pulled down with a resistance (pull-down), there will be no output on the serial port during the boot process. This can be useful in battery powered applications where you do not want to use the serial port at all to reduce power consumption.

Note on ESP32-PICO-D4

Pins 16 and 17 are reserved for writing to internal flash memory.

Note on ESP32-WROVER

Pins 16 and 17 are reserved for accessing PSRAM memory

GPIO consumption in OUTPUT mode (digital output)

The ESP32’s GPIO is designed to send logic signals. The GPIO will be able to deliver enough power to power a few LEDs, on the other hand, the GPIO of the ESP32 cannot be used to power equipment that requires more energy such as a motor.

Each output can deliver a current of 40mA maximum.

In addition, the total power used by all the equipment connected to the GPIO must not exceed 1200mA according to the Absolute Maximum Ratings section of the official technical documentation.

Pins compatible with interrupts

An interrupt is a process that is triggered asynchronously by an external event. Interrupts are used to detect an event in real time while letting the microcontroller processor do other tasks.

Interrupts only work with digital inputs. The digital inputs that can trigger an interrupt are circled in the diagram below.

Do not use pins colored orange or red. Your program might behave unexpectedly while using these.

Warning. Some pins go HIGH or emit PWM signals on startup or during reset (already mentioned earlier). Others are used by the system to access flash memory or upload the program. They should not be used in your projects.

Follow this tutorial which explains in detail how to use the ESP32 interrupts.

Real-time (RTC) and capacitive (Touch) subsystem pins

The ESP32 processor has a very low power real time subsystem called RTC which remains active even when it is in standby.

As a reminder, the ESP32 has several standby modes. Depending on the mode activated, the different subsystems are deactivated to reduce consumption and / or save battery.

Active Mode
GPIO Wireless Bluetooth CPU ULP RTC Consumption*
95 ~ 240mA
Modem Sleep
20 ~ 68 mA
Light Sleep
0.8 mA
  Core paused
Deep Sleep
10 ~ 150 μA
RTC only
1 μA
RTC only x1

To learn more about putting the ESP32 to sleep, read this detailed article

The ESP32 therefore has

Pin identification has changed between versions of ESP32 SoCs. The following table summarizes the RTC and Touch pins of the Espressif ESP32-DevKitC v4 (2020) and ESP32-DevKitC v2 (obsolete) development boards.

RTC pin label Capacitive pin (Touch Pad) Pin tag on an ESP32 DevKitC version 4 (2020) board Pin tag on an ESP32-DevKitC V2 board (obsolete)
Map marker CPU pin (49 pins) Map marker CPU pin (39 pins)
RTC_GPIO1 Not exposed 37 Not exposed
RTC_GPIO2 Not exposed 7 Not exposed
RTC_GPIO4 34 10 IO34 6
RTC_GPIO5 35 11 IO35 7
RTC_GPIO6 25 14 IO25 10
RTC_GPIO7 26 15 IO26 11
RTC_GPIO8 Touch8 33 13 IO33 9
RTC_GPIO9 Touch9 32 12 IO32 8
RTC_GPIO10 Touch0 4 4 IO4 26
RTC_GPIO11 Touch1 0 0 IO0 25
RTC_GPIO12 Touch2 2 2 IO2 24
RTC_GPIO13 Touch3 15 15 IO15 23
RTC_GPIO14 Touch4 13 13 IO13 16
RTC_GPIO15 Touch5 12 12 IO12 14
RTC_GPIO16 Touch6 14 17 IO14 16
RTC_GPIO17 Touch7 27 16 IO27 12

Here is the pinout of the ESP32 DevKitC version 4 (2020) kit.

The circled number corresponds to the processor pin.

The number indicated on the development board corresponds to the GPIO, it is this number that must be used in the Arduino code of the project.

Source: identification of the RTC and capacitive (Touch) pins (pinout) of the official ESP32 DevkitC v4 kit  according to the official Espressif documentation.

Read this article to learn more about PSTN or touch pins.

Pin EN (Enable)

The EN (ENable) pin enables the 3.3V regulator to be activated. By default, the regulator is enabled. To deactivate the regulator, it is necessary to ground (GND) voltage It is pulled up, then connect to the earth to deactivate the 3.3V regulator. This means that you can use this pin connected to a push button to restart your ESP32, for example.

I2C bus

The ESP32 has 2 independent I2C buses. Each bus can play the role of main equipment (bus pilot) or secondary equipment.

GPIO I2C bus n ° 1 I2C bus n ° 2
SDA 21 User defined
SCL 22 User defined

However, it is possible to use any digital pin if the default pins (21 and 22) are not exposed on the development board. To do this, simply indicate the SDA and SCL pins to use when initializing the bus like this


The I²C interfaces support the following modes:

SPI bus

The ESP32 has 3 SPI buses. SPI, HSPI (H for Hardware) and VSPI (V for Virtual).

By default, the HSPI and VSPI buses are connected to the following pins


As for the I2C bus, it is possible to manually choose any pin that you want to use to communicate with SPI equipment (OLED screen, LCD screen, sensor, micro SD card reader, etc.) by switching to sets the pins during bus initialization.


12-bit (18-channel) Analog-to-Digital Converter (ADC)

The ESP32 is equipped with a 12-bit Analog / Digital converter (or ADC in English which stands for  A nalog to D igital C onverter) having 18 independent channels on the pins listed in the table below.

The ESP32’s ULP processor is also designed to access the ADC converter even when the processor is idle. This greatly reduces energy consumption. The CPU can be woken up by a threshold setting and / or other triggers.

GPIO ADC channel
0 ADC2_CH1
2 ADC2_CH2
4 ADC2_CH0
12 ADC2_CH5
13 ADC2_CH4
14 ADC2_CH6
15 ADC2_CH3
25 ADC2_CH8
26 ADC2_CH9
27 ADC2_CH7
32 ADC1_CH4
33 ADC1_CH5
34 ADC1_CH6
35 ADC1_CH7
36 ADC1_CH0
37 ADC1_CH1
38 ADC1_CH2
39 ADC1_CH3

Knowing the channel is not very important, on the other hand it must always be kept in mind that the voltage on the spindle must never exceed 3V3. Beyond this tension, you have a great chance of break the ESP32 development board. There is a discussion on GitHub about this.

The sampling being carried out on 12-bits, the returned value will be between 0 (0V) and 4095 (3V3).

It is possible to adjust the resolution from 9 to 12-bits (see the next paragraph) which will give

The analogRead() method is available on the ESP32-Arduino library, all you have to do is pass as a parameter the pin on which you want to retrieve the analog value.

For example to read the value of a potentiometer connected to pin 35

val = analogRead(35); 
Serial.print("Angle actuel :"); 

Advanced functions of ADC converter

There are other more advanced functions that allow fine tuning of data acquisition parameters.

Function Description
analogReadResolution(resolution) Set the sample bits and the resolution. This can be a value between 9 (0 – 511) and 12 bits (0 – 4095). The default resolution is 12 bits.

9-bits (0-511), 10-bits (0-1023), 11-bits (0-2047) and 12-bits (0-4095)

analogSetWidth(width) Set the sample bits and the resolution. This can be a value between 9 (0 – 511) and 12 bits (0 – 4095). The default resolution is 12 bits.

9-bits (0-511), 10-bits (0-1023), 11-bits (0-2047) and 12-bits (0-4095)

analogSetCycles(cycles) Define the number of cycles per sample. The default is 8. Range 1 to 255
analogSetSamples(samples) Set the number of samples in the range. The default is 1 sample. It has the effect of increasing sensitivity.
analogSetClockDiv(attenuation) set the ADC clock separator. The default is 1. Range from 1 to 255
analogSetAttenuation(attenuation) Set the input attenuation for all ADC pins. The default is ADC_11db. Accepted values:
  • ADC_0db: does not define any attenuation (1 V input = CAN reading of 1088).
  • ADC_2_5db: defines an attenuation of 1.34 (1 V input = CAN reading of 2086).
  • ADC_6db: defines an attenuation of 1.5 (input 1 V = CAN reading of 2975).
  • ADC_11db: defines an attenuation of 3.6 (1 V input = CAN reading of 3959).
analogSetPinAttenuation(pin, attenuation) Set the input attenuation for the specified pin. The default is ADC_11db. The attenuation values ​​are the same as for the previous function.
adcAttachPin(pin) Attach a pin to the ADC (also clears any other analog mode that might be activated). Returns a TRUE or FALSE result.
adcStart(pin), adcBusy(pin)andresultadcEnd(pin) Start an ADC on the attached pin bus. Check if the conversion on the pin’s ADC bus is in progress (returns TRUE or FALSE). Get the result of the conversion: returns a 16-bit integer.

Digital to Analog Converter (DAC)

The ESP32 is equipped with a Digital-to-Analogue converter (or D igital to A nalogic C onverter) offering two 8-bit channels. They are accessible on pins 25 and 26.

GPIO ADC channel
25 DAC1
26 DAC2

Infrared interface

The infrared interface supports eight channels of infrared remote transmission and reception. By programming the pulse waveform, it supports various infrared protocols. Eight channels share a 512 x 32 bit memory block to store the transmit or receive waveform.


09/02/2021  Publication of the article

French version

Click to rate this post!
[Total: 1 Average: 5]
Exit mobile version