Arduino core para ESP32 a fondo: instalar, entender y no pelearse

Cómo funciona de verdad el core de Arduino para ESP32: instalación, setup y loop sobre FreeRTOS, milis vs delay, librerías compatibles y las diferencias con Arduino clásico.

También disponible en: EN, ES

Serie Introducción al ESP32 Parte 11 Ver la serie →
Arduino core sobre el ESP32

El «Arduino core para ESP32» es la razón por la que medio mundo usa este chip. Te deja escribir pinMode() y digitalWrite() como en un Arduino UNO, pero por debajo hay un ESP32 con FreeRTOS. Entender esa capa es la diferencia entre copiar ejemplos y saber lo que haces.

Qué es exactamente

No es un Arduino emulado. Desde la versión 3.x, el core es un envoltorio sobre ESP-IDF: tus setup() y loop() corren dentro de un FreeRTOS task real (se llama loopTask), en el núcleo 1, con 8 KB de pila por defecto.

Eso explica dos cosas muy típicas:

  • Si tu loop() se queda colgado, salta el watchdog y la placa se reinicia.
  • Si tu proyecto crece, puedes crear tareas con xTaskCreatePinnedToCore().

Instalación (dos caminos)

Arduino IDE — añade la URL de placas en Preferences:

https://espressif.github.io/arduino-esp32/package_esp32_index.json

Luego instala «esp32 by Espressif» desde el Boards Manager y elige tu placa.

PlatformIO (mi recomendación) — platformio.ini:

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

setup() y loop() por dentro

void setup() {
  Serial.begin(115200);
  pinMode(2, OUTPUT);
}

void loop() {
  digitalWrite(2, !digitalRead(2));
  delay(1000);
}

Funciona, pero conviene saber:

  • delay() bloquea el task. Con Wi-Fi o varios sensores, usa millis().
  • setup() se ejecuta una vez; si quieres tareas paralelas, créalas ahí.
  • El watchdog vigila el loop: si tardas demasiado, reinicio.

Versión anti-bloqueo:

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

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

Librerías: no todas valen

  • Las de Arduino genéricas suelen funcionar si no tocan registros del AVR.
  • Las que usan timers o interrupciones específicas pueden fallar.
  • Para sensores, busca la versión «ESP32» o usa la librería del fabricante.
  • Wire (I2C) y SPI existen, pero puedes elegir pines.

Diferencias con un Arduino UNO

CosaArduino UNOESP32
Voltaje5 V3,3 V
Bits832
EEPROM1 KBno hay (usa Preferences)
ADC10 bits12 bits (y ADC2 con Wi-Fi, ojo)
Wi-Fi
Núcleos12

Guardar algo en la «EEPROM» del ESP32 se hace así:

#include <Preferences.h>
Preferences prefs;

void setup() {
  prefs.begin("mi-app", false);
  int arranques = prefs.getInt("n", 0) + 1;
  prefs.putInt("n", arranques);
  prefs.end();
}

Buenas prácticas

  1. No bloquees el loop: usa millis(), tareas o vTaskDelay.
  2. Serial a 115200 y espera un momento tras begin() si lo necesitas.
  3. No abuses de String: fragmenta la memoria. Usa char[] y snprintf.
  4. Separa el código en ficheros; un .ino de 2000 líneas es un dolor.
  5. Depura con logs, no con Serial.println por todas partes.

¿Cuándo pasar a ESP-IDF?

Cuando necesites control fino de tareas y memoria, timing preciso, particiones OTA serias o exprimir el consumo. El core de Arduino esconde mucho, y a veces eso está bien… hasta que deja de estarlo.

Resumen

  • Es un envoltorio sobre ESP-IDF; tus setup/loop son un task de FreeRTOS.
  • delay() bloquea; aprende a usar millis() desde el principio.
  • 3,3 V, sin EEPROM (usa NVS/Preferences), ADC de 12 bits.
  • No todas las librerías de Arduino compilan: revisa la compatibilidad.
  • Versión actual del core: 3.3.11 (sobre ESP-IDF 5.5.5).

Siguiente paso: ESP-IDF a fondo para cuando necesites el control total. O vuelve al hub de la serie.

Entradas relacionadas

↑↓ navegar ↵ abrir Esc cerrar