Si el core de Arduino esconde el ESP32, ESP-IDF lo enseña todo. Es el SDK oficial de Espressif y la base sobre la que se construye todo lo demás. Tiene más curva, sí, pero también te da el control que un producto necesita.
Vamos con lo importante sin perderse en la documentación.
Estructura de un proyecto
mi-proyecto/
├── CMakeLists.txt # proyecto (casi siempre igual)
├── sdkconfig # configuración generada
└── main/
├── CMakeLists.txt # registra el main
└── main.c
El CMakeLists.txt raíz:
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mi-proyecto)
Y el de main/:
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")Los comandos que vas a usar
idf.py set-target esp32s3 # elige el chip
idf.py menuconfig # configura (Kconfig)
idf.py build # compila
idf.py flash monitor # flashea y abre el monitor
menuconfig es una de las mejores cosas de ESP-IDF: cambias opciones (Wi-Fi,
logs, particiones, PSRAM) sin tocar el código, y quedan guardadas en sdkconfig.
Hola mundo con logs
#include "esp_log.h"
static const char *TAG = "app";
void app_main(void) {
ESP_LOGI(TAG, "Arrancando…");
ESP_LOGW(TAG, "Esto es un aviso");
ESP_LOGE(TAG, "Y esto un error");
}
Nada de printf: usa los niveles de log. Puedes subir o bajar el nivel por
componente desde menuconfig, y en producción apagarlos casi todos.
Tareas: el corazón de ESP-IDF
Aquí está la gran diferencia con Arduino. En lugar de un loop(), creas
tareas de FreeRTOS con prioridad y tamaño de pila propios:
void tarea_sensor(void *arg) {
while (1) {
leer_sensor();
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void app_main(void) {
xTaskCreate(tarea_sensor, "sensor", 4096, NULL, 5, NULL);
}
Ventajas reales:
- Paralelismo de verdad: una tarea mide, otra publica por MQTT.
vTaskDelayno bloquea el resto del sistema.- Controlas pila y prioridad, que es lo que evita los reinicios raros.
Particiones y OTA
La flash no es un bloque único: está particionada (tabla partitions.csv).
Por defecto hay dos ranuras de aplicación (app0 y app1) para poder hacer
OTA (actualización por Wi-Fi) con rollback si algo falla.
# Name, Type, SubType, Offset, Size
nvs, data, nvs, 0x9000, 0x4000
factory, app, factory, 0x10000, 1M
Ejemplo de partición con OTA:
# Name, Type, SubType, Size
nvs, data, nvs, 0x4000
otadata, data, ota, 0x2000
phy_init, data, phy, 0x1000
factory, app, factory, 1M
ota_0, app, ota_0, 1M
ota_1, app, ota_1, 1MWire: ¿Arduino o ESP-IDF?
| Arduino core | ESP-IDF | |
|---|---|---|
| Curva | Baja | Alta |
| Control | Medio | Total |
| Tareas | 1 loop | N tareas |
| Memoria | Automática | Tú decides |
| OTA | Fácil | Completo (rollback) |
| Logs | Serial | Niveles por componente |
Cuándo merece la pena
- Sí: producto, batería, timing fino, OTA serio, muchos periféricos.
- No: si solo quieres leer un sensor y publicar, Arduino te lleva en una tarde y te sobra.
Consejo: puedes mezclar. El core de Arduino es ESP-IDF por debajo, así que desde un sketch puedes llamar a APIs de ESP-IDF cuando las necesites.
Resumen
- ESP-IDF es el SDK oficial: CMake +
idf.py+menuconfig. - Usa tareas de FreeRTOS, no un
loop(). - Logs por niveles con
ESP_LOGxen lugar deprintf. - La flash está particionada; el OTA con rollback viene casi gratis.
- Versión actual: 6.1.
Siguiente paso: MicroPython y Lua para el extremo opuesto: cero compilación. O vuelve al hub de la serie.