Fundamentals of ESP32 Peripheral Control: Detailed GPIO Applications and Input/Output Examples

1. What is GPIO?

GPIO (General Purpose Input Output) refers to “general-purpose input/output ports,” which are pins that can be flexibly configured as input or output through software. Typical applications in embedded development include:

  • Controlling output devices such as LED lights, relays, and buzzers

  • Detecting input devices such as buttons and dip switches

  • Interacting with sensors or other modules through high and low levels

  • Supporting communication protocols such as I2C, SPI, and I2S

2. ESP32 GPIO Features

The ESP32 chip provides a rich set of GPIO pins, with the following specific features:

  • Supports up to 39 GPIOs, numbered GPIO0 to GPIO39 (some are input-only)

  • Each GPIO can be configured for input, output, pull-up, pull-down, interrupt, and other modes

  • Supports interrupt triggers (rising edge/falling edge/level trigger)

  • Some GPIOs also support specific peripheral functions (such as PWM, ADC, I2C, SPI)

Note: Some GPIOs have special function limitations, for example, GPIO6 to GPIO11 are dedicated to Flash communication and are not recommended for general GPIO use.

3. GPIO Configuration Structure and Common Functions

In the ESP-IDF framework (the official development framework for ESP32), the use of GPIO is mainly implemented through the following structures and APIs.

3.1 GPIO Configuration Structure

ESP32 uses the <span>gpio_config_t</span> structure to configure GPIO properties:

typedef struct {uint64_t pin_bit_mask;            // GPIO bit mask to configure, e.g., (1ULL<<GPIO_NUM_2)gpio_mode_t mode;                // GPIO mode (input, output, or input/output)gpio_pullup_t pull_up_en;       // Enable pull-up or notgpio_pulldown_t pull_down_en;   // Enable pull-down or notgpio_int_type_t intr_type;      // Interrupt type (rising edge/falling edge/level)} gpio_config_t;

3.2 Common GPIO Control Functions

Here are the common functions used for GPIO in ESP-IDF:

Function Description
<span>gpio_config()</span> Initialize and configure GPIO parameters
<span>gpio_set_level()</span> Set GPIO output high/low level (0 or 1)
<span>gpio_get_level()</span> Read the current input level of GPIO
<span>gpio_set_direction()</span> Set the input/output direction of GPIO
<span>gpio_install_isr_service()</span> Install GPIO interrupt service
<span>gpio_isr_handler_add()</span> Add interrupt handler function
<span>gpio_intr_enable()</span> / <span>gpio_intr_disable()</span> Enable or disable the interrupt function of a GPIO

4. GPIO Control LED Example

The following code demonstrates how to use GPIO to control an LED connected to GPIO2.

4.1 Example Code

#include "driver/gpio.h"#include "freertos/FreeRTOS.h"#include "freertos/task.h"#define LED_GPIO GPIO_NUM_2void app_main(void) {    gpio_reset_pin(LED_GPIO);  // Reset GPIO state    gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);  // Set to output modewhile (1) {        gpio_set_level(LED_GPIO, 1);  // Turn on LED        vTaskDelay(pdMS_TO_TICKS(500));        gpio_set_level(LED_GPIO, 0);  // Turn off LED        vTaskDelay(pdMS_TO_TICKS(500));    }}

4.2 Explanation

  • <span>gpio_reset_pin()</span>: Clears any previous configuration

  • <span>gpio_set_direction()</span>: Sets the direction to output

  • <span>gpio_set_level()</span>: Sets the level state

This is a standard “LED blinking” example, toggling the level state every 500ms.

5. GPIO Listening for Key Input Example

Next, we will demonstrate how to listen for key input. Assume a button is connected to GPIO4, and when the button is pressed (level goes low), it controls the LED to light up.

5.1 Example Code

#define LED_GPIO     GPIO_NUM_2#define KEY_GPIO     GPIO_NUM_4void app_main(void) {// Configure LED pin    gpio_reset_pin(LED_GPIO);    gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);// Configure button pin    gpio_reset_pin(KEY_GPIO);    gpio_set_direction(KEY_GPIO, GPIO_MODE_INPUT);    gpio_pullup_en(KEY_GPIO);  // Enable pull-up to avoid floatingwhile (1) {int key_level = gpio_get_level(KEY_GPIO);if (key_level == 0) {  // Low level when pressed            gpio_set_level(LED_GPIO, 1);  // Turn on LED        } else {            gpio_set_level(LED_GPIO, 0);  // Turn off LED        }        vTaskDelay(pdMS_TO_TICKS(50));  // Simple debounce delay    }}

5.2 Explanation

  • The button uses input mode with an internal pull-up resistor.

  • Detect whether the button is pressed by reading the level state using <span>gpio_get_level()</span>.

  • A simple delay is used instead of hardware debounce.

6. Interrupt-Based Key Listening (Advanced)

If you do not want to poll frequently, you can use GPIO interrupt mode to detect key presses.

6.1 Interrupt Handler Configuration Example

static void IRAM_ATTR gpio_isr_handler(void* arg) {    gpio_set_level(LED_GPIO, !gpio_get_level(LED_GPIO));  // Toggle LED state}void app_main(void) {// Configure LED    gpio_reset_pin(LED_GPIO);    gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT);// Configure button as falling edge interrupt inputgpio_config_t io_conf = {        .pin_bit_mask = (1ULL << KEY_GPIO),        .mode = GPIO_MODE_INPUT,        .pull_up_en = GPIO_PULLUP_ENABLE,        .pull_down_en = GPIO_PULLDOWN_DISABLE,        .intr_type = GPIO_INTR_NEGEDGE,    };    gpio_config(&io_conf);    gpio_install_isr_service(0);  // Install ISR service    gpio_isr_handler_add(KEY_GPIO, gpio_isr_handler, NULL);  // Add ISR handler}

6.2 Explanation

  • Use <span>gpio_config()</span> to configure interrupt mode

  • Use <span>gpio_install_isr_service()</span> and <span>gpio_isr_handler_add()</span> to register the interrupt service

  • The interrupt service function must be marked with <span>IRAM_ATTR</span> to place it in IRAM

7. Conclusion

This article introduced the basics of using ESP32 GPIO, covering:

  • GPIO functionality and structure configuration

  • Common control functions

  • Example of controlling LED output

  • Example of detecting key input

  • Advanced example of using interrupts to listen for key presses

GPIO is the “first step” in embedded development. Mastering GPIO control logic is crucial for subsequent tasks such as serial communication, PWM control, and sensor reading.

In future articles, we will further explore ESP32’s PWM, ADC, UART, I2C, SPI, and other peripheral control technologies, stay tuned.

Leave a Comment