Primeros pasos con el ESP32: parpadea un LED

Prepara tu entorno, entiende el pinout y escribe tu primer programa para el ESP32 haciendo parpadear un LED. Con Arduino y con ESP-IDF.

También disponible en: EN, ES

Serie Introducción al ESP32 Parte 19 Ver la serie →
Diagrama de un LED conectado a un ESP32

El Hello World del hardware es hacer parpadear un LED. Es un ritual sencillo, pero toca todos los puntos importantes de una placa nueva: alimentación, toolchain, GPIO y carga del programa.

Qué necesitas

ElementoDetalle
PlacaESP32 DevKitC, ESP32-WROOM-32 o similar
LEDCualquier color, 2 V de caída típica
Resistencia220 Ω a 330 Ω
SoftwarePlatformIO (recomendado) o Arduino IDE 2.x

Consejo: muchos DevKits ya traen un LED en el pin GPIO2. Puedes usarlo para probar sin cablear nada, aunque suele estar invertido.

El pinout, en dos minutos

El ESP32 tiene GPIOs numerados del 0 al 39, pero no todos se pueden usar:

  • GPIO6GPIO11 están conectados a la memoria flash SPI. No los toques.
  • GPIO34GPIO39 son solo entrada (no tienen pull-up interno).
  • GPIO1 (TX0) y GPIO3 (RX0) se usan para el puerto serie.
  • GPIO0 define el modo de arranque; evita usarlo como salida.

Para un LED, cualquier GPIO de salida sirve. Usaremos GPIO2.

Código con Arduino

El core de Arduino simplifica muchísimo el arranque:

#include <Arduino.h>

constexpr int LED_PIN = 2;

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

void loop() {
  digitalWrite(LED_PIN, HIGH);
  delay(1000);
  digitalWrite(LED_PIN, LOW);
  delay(1000);
}

delay() bloquea (y a veces importa)

delay() detiene la CPU entera. En un parpadeo da igual, pero en cuanto añadas Wi-Fi o varios sensores querrás usar millis():

unsigned long last = 0;
constexpr unsigned long INTERVAL = 1000;

void loop() {
  if (millis() - last >= INTERVAL) {
    last = millis();
    digitalWrite(LED_PIN, !digitalRead(LED_PIN));
  }
}

Lo mismo con ESP-IDF (Rust)

Si prefieres Rust, el crate esp-idf-hal ofrece una API tipada. Así se ve un blink con esp-idf-svc:

use esp_idf_svc::hal::delay::FreeRtos;
use esp_idf_svc::hal::gpio::PinDriver;
use esp_idf_svc::hal::peripherals::Peripherals;

fn main() -> anyhow::Result<()> {
    esp_idf_svc::sys::link_patches();
    let peripherals = Peripherals::take()?;
    let mut led = PinDriver::output(peripherals.pins.gpio2)?;

    loop {
        led.set_high()?;
        FreeRtos::delay_ms(1000);
        led.set_low()?;
        FreeRtos::delay_ms(1000);
    }
}

La gran diferencia: en Rust el compilador te obliga a declarar el pin como salida antes de escribirlo. Muchos errores de hardware desaparecen en tiempo de compilación.

Configuración con PlatformIO

platformio.ini mínimo para el core de Arduino:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200

Y para Rust con esp-idf:

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = espidf
monitor_speed = 115200

Comprobaciones si no funciona

  1. No compila / no encuentra la placa. Instala los drivers cp210x o ch34x según el chip USB de tu placa.
  2. Se sube pero no parpadea. Revisa la polaridad del LED y la resistencia.
  3. Se reinicia en bucle. Suele ser falta de corriente: usa un puerto USB que entregue al menos 500 mA.

Siguiente paso

Con el GPIO dominado, ya tienes lo esencial. El siguiente salto natural es la conectividad (Wi-Fi, MQTT), que iremos cubriendo en el blog. De momento, puedes seguir con el monitor serie y depuración o volver al hub de la serie.

Entradas relacionadas

↑↓ navegar ↵ abrir Esc cerrar