Firmware ESP32 (PlatformIO: Arduino primero, ESP-IDF cuando sea necesario)
Cargue también embedded-c-cpp para estándares de codificación, arquitectura, pruebas unitarias y depuración general. Esta habilidad contiene las partes específicas de ESP32.
Primero, identifique el proyecto
| Encontrar | Dónde | Por qué es importante |
|---|---|---|
| Chip y módulo exactos (ESP32-WROOM-32E, ESP32-S3-WROOM-1-N16R8, ESP32-C3-MINI-1...) | platformio.ini board =, usuario, serigrafía de la placa | Núcleos, pines, PSRAM, USB, ADC difieren mucho entre variantes |
| Framework | framework = arduino, espidf o arduino, espidf | API y modelo de configuración |
| Versión del núcleo Arduino (2.x o 3.x) | línea de registro de compilación framework-arduinoespressif32 @ x.y.z, línea platform =, o ESP_ARDUINO_VERSION_MAJOR | Varias APIs cambiaron en 3.x (LEDC, temporizadores) — el código escrito para la versión incorrecta no compilará |
| Tamaño de Flash / PSRAM | nombre del módulo (N16R8 = 16 MB flash, 8 MB octal PSRAM), board_upload.flash_size | Particiones, ubicación de memoria |
| Cableado de la placa | usuario/esquemático | Evitar pines de strapping y pines usados por flash/PSRAM/USB/LEDs |
Si la variante es desconocida y la tarea toca pines, periféricos, alimentación o memoria, averigüe antes de escribir código — un pin que funciona bien en un S3 puede impedir que un ESP32 clásico arranque.
¿Arduino o ESP-IDF?
| Quédese con Arduino (predeterminado) | Muévase a ESP-IDF (en PlatformIO: framework = espidf) o Arduino + IDF (framework = arduino, espidf) |
|---|---|
| Prototipos y la mayoría de productos | Necesita cambiar opciones de sdkconfig que el núcleo precompilado de Arduino no expone (OTA con reversión, arranque seguro, cifrado de flash, PM auto light-sleep, volcado de núcleo a flash, ajustes de FreeRTOS) |
| Muchas bibliotecas disponibles | Últimas características de IDF, control estricto de memoria/rendimiento |
| Iteración rápida | Endurecimiento de producción |
Arduino en ESP32 ya se ejecuta sobre FreeRTOS + ESP-IDF, por lo que las APIs de IDF (esp_*, xTaskCreatePinnedToCore, nvs_*, esp_sleep_*, heap_caps_*) funcionan desde código Arduino. "Arduino como componente IDF" (arduino, espidf) mantiene las bibliotecas de Arduino y agrega control de sdkconfig — la ruta de migración habitual.
Configuración, plantillas de platformio.ini y cambios de API entre 2.x y 3.x: references/platformio-setup.md.
Reglas que previenen los fallos clásicos de ESP32
- Pines: nunca use pines de flash (GPIO6–11 en ESP32), pines de PSRAM (16/17 en WROVER; 33–37 en módulos S3 con PSRAM octal) o pines USB cuando use USB; trate los pines de strapping (ESP32: 0, 2, 5, 12, 15) como "solo con cuidado" — GPIO12 en alto al arrancar impide que los módulos con flash de 3.3 V arranquen. ADC2 no funciona mientras Wi-Fi está encendido (ESP32 clásico): use pines de ADC1. Tablas completas por variante:
references/pins-and-variants.md. - No bloquee
loop()ni una tarea para siempre: bucleswhilelargos sindelay()/vTaskDelay()disparan el watchdog de tareas;while (WiFi.status() != WL_CONNECTED)necesita un tiempo de espera. - ISR: marque
IRAM_ATTR, manténgalas pequeñas, sinSerial.print, sindelay, sin llamadas a Wi-Fi; pase el trabajo a una tarea (cola / notificación de tarea / bandera). Variables compartidasvolatile+ sección crítica (spinlockportENTER_CRITICAL_ISR— el ESP32 es de doble núcleo). - Las pilas de tareas están en bytes en ESP-IDF/Arduino (a diferencia de FreeRTOS estándar que usa palabras). Mida con
uxTaskGetStackHighWaterMark(NULL)(bytes). Elloop()de Arduino tiene 8 KB por defecto (SET_LOOP_TASK_STACK_SIZE(16 * 1024);para cambiarlo). - Fuente de alimentación: la transmisión Wi-Fi consume picos de ~300–500 mA. "Se disparó el detector de brownout" significa arreglar la fuente (regulador, condensador de desacoplo, cable) — no desactive el detector de brownout.
- Heap: evite la concatenación de
Stringen bucles y los frecuentesnew/malloc(fragmentación a lo largo de días); preasigne. VerifiqueESP.getFreeHeap()/heap_caps_get_minimum_free_size(MALLOC_CAP_8BIT)con el tiempo. - Desgaste de NVS/flash: no escriba
Preferences/NVS en cada iteración del bucle; escriba solo cuando cambie, con limitación de velocidad. - Operaciones irreversibles: quema de eFuse, arranque seguro, cifrado de flash en modo release son permanentes. Nunca ejecute
espefuse.py burn_*, habilite estas opciones ensdkconfig, o useerase_flashen un dispositivo con datos, sin confirmación explícita del usuario.
Compilar, subir, monitor (PlatformIO)
pio run -e <env> # compilar
pio run -e <env> -t upload # flashear por USB/serie
pio device monitor -e <env> # monitor serie (usa monitor_speed / monitor_filters)
pio run -e <env> -t upload -t monitor # ambos
pio run -e <env> -t uploadfs # subir carpeta data/ como imagen LittleFS/SPIFFS
pio run -e <env> -t erase # borrar todo el flash (pregunta primero: borra credenciales NVS/WiFi)
pio run -e <env> -t menuconfig # solo ESP-IDF / arduino+espidf
pio test -e native # pruebas unitarias en host (ver embedded-c-cpp)
Si la subida falla con "Failed to connect / Wrong boot mode detected" → mantenga presionado BOOT (GPIO0 / GPIO9 en C3), pulse EN/RST, suelte BOOT; verifique que el cable soporte datos; cierre cualquier otro monitor serie que tenga ocupado el puerto. Confirme que la placa está conectada y el puerto antes de subir (pio device list).
Cuando se bloquea o reinicia
La salida serial pegable es la evidencia clave. Habilite monitor_filters = esp32_exception_decoder y build_type = debug para que los backtraces se decodifiquen a archivo:línea. Luego vea references/panics-and-debug.md para: tipos de Guru Meditation (LoadProhibited, StoreProhibited, IllegalInstruction, fallo de acceso Load/Store en RISC-V), stack canary, watchdog de tarea/interrupción, códigos rst:, brownout, bucles de arranque, depuración JTAG (debug_tool = esp-builtin en S3/C3/C6).
Archivos de referencia
| Archivo | Leer cuando |
|---|---|
references/platformio-setup.md | Crear/arreglar platformio.ini, elegir versión de plataforma/núcleo, cambios de API Arduino 2.x→3.x, PSRAM, USB-CDC serie, particiones y sistema de archivos, usar ESP-IDF en PlatformIO, sdkconfig |
references/pins-and-variants.md | Elegir o revisar pines, comparar ESP32/S2/S3/C3/C6, ADC, táctil, pines de despertar en sueño profundo |
references/rtos-memory-power.md | Tareas, núcleos, ISR, colas, watchdog, pila/heap/PSRAM, IRAM, sueño profundo/ligero, batería |
references/panics-and-debug.md | Cualquier bloqueo, reinicio, watchdog, brownout, bucle de arranque, fallo de subida, depuración JTAG, volcados de núcleo, motivo de reinicio |
references/connectivity-ota-security.md | Robustez Wi-Fi/BLE, NVS/Preferences, actualizaciones OTA y reversión, arranque seguro / decisiones de cifrado de flash |