Escribir el firmware es la mitad del trabajo. La otra mitad es llevarlo al dispositivo: la primera vez, cuando hay que corregir un error y cuando el dispositivo ya está en casa de un cliente. Para eso hay tres caminos, cada uno con su momento.
En esta guía comparo las tres formas de instalar firmware en un ESP32, cómo se configura un dispositivo recién instalado y qué hay que prever para actualizar una flota sin dejar dispositivos inservibles.
Las tres formas
| USB (Arduino IDE, esptool) | Navegador (ESP Web Tools) | OTA (por red) | |
|---|---|---|---|
| Necesita | Computador con herramientas instaladas y cable | Chrome o Edge de escritorio y cable | Que el dispositivo ya tenga un firmware con OTA y acceso a la red |
| Ideal para | Desarrollo | Instalar o reinstalar sin herramientas | Actualizar dispositivos ya instalados |
| ¿Borra la configuración? | No, salvo que borres la flash | Sí, en una instalación nueva | No |
| Riesgo | Bajo | Bajo | Si falla a mitad, el dispositivo puede quedar inservible si no hay plan B |
1. Por USB: para desarrollar
Es la forma de siempre: compilas y cargas desde Arduino IDE, PlatformIO o la línea de comandos con esptool. Durante el desarrollo es la más rápida.
Dos detalles que conviene saber:
- Cargar un sketch no borra la partición NVS. Si tu firmware guarda configuración, sobrevive a una carga nueva. Para empezar de cero, borra la flash completa (
esptool.py erase_flash). - El cable importa. Muchos cables USB solo cargan. Si el computador no ve la placa, prueba otro cable antes que otros drivers.
2. Desde el navegador: para instalar sin herramientas
Chrome y Edge de escritorio implementan Web Serial, que permite a una página web hablar con un dispositivo USB. ESP Web Tools, el componente que usa Home Assistant, aprovecha eso para instalar firmware con un botón: detecta el chip, borra la memoria y escribe el binario correcto.
Un ejemplo: un botón en un panel web que detecta si conectaste un ESP32-S3 o un ESP32-C3 e instala el firmware que corresponde a cada uno. El paso a paso está en la parte 20 de la serie.
No funciona en Safari, Firefox ni en iPhone. Para una herramienta de instalación desde un computador, no es un problema.
Después de instalar: la configuración
Un firmware genérico, igual para todos los dispositivos, necesita recibir después lo que es propio de cada uno: el Wi-Fi, su identidad en la nube, su papel en el sistema. Las formas habituales:
- Un punto de acceso con un formulario web: el dispositivo sin configurar levanta su propia red Wi-Fi; te conectas con el celular y llenas los datos (parte 16).
- Aprovisionamiento en la nube: el dispositivo pide su propio certificado la primera vez que se conecta, por ejemplo con Fleet Provisioning de AWS (parte 17).
- Bluetooth LE, con una app propia.
- Por puerto serie, para técnicos.
La configuración se guarda en la memoria NVS y sobrevive a los reinicios (parte 6).
3. Por OTA: para dispositivos ya instalados
OTA (over the air) es actualizar el firmware por la red, sin tocar el dispositivo. Es imprescindible en cuanto tienes dispositivos fuera de tu escritorio.
Cómo funciona por dentro
El esquema de particiones habitual del ESP32 tiene dos espacios para la aplicación (ota_0 y ota_1). El dispositivo ejecuta desde uno y escribe la versión nueva en el otro. Solo cuando la descarga termina y se verifica, marca la nueva como la que debe arrancar.
Si algo falla durante la descarga, el dispositivo sigue arrancando la versión anterior. Y con el rollback activo, si la versión nueva arranca pero no se marca como válida, el cargador vuelve a la anterior en el siguiente reinicio.
Con Arduino
El núcleo de Arduino para ESP32 incluye lo necesario:
ArduinoOTA: para cargar desde el IDE por la red local, durante el desarrollo.HTTPUpdate: el dispositivo descarga un binario de una URL HTTPS y se actualiza.
#include <WiFiClientSecure.h>
#include <HTTPUpdate.h>
void actualizar(const char* url) {
WiFiClientSecure cliente;
cliente.setCACert(CA_DEL_SERVIDOR); // verifica el servidor de descarga
t_httpUpdate_return r = httpUpdate.update(cliente, url);
if (r == HTTP_UPDATE_FAILED) {
Serial.printf("Falló la actualización: %s\n", httpUpdate.getLastErrorString().c_str());
}
// Si sale bien, el ESP32 se reinicia solo con la versión nueva
}
Lo que hay que prever en una flota
- No actualices todo de golpe. Prueba primero en tus propios dispositivos, después en unos pocos (canary) y luego en el resto.
- Reparte las descargas en el tiempo, con un retraso aleatorio por dispositivo, para no saturar el servidor.
- Confirma que la versión nueva funciona (por ejemplo, que vuelve a conectarse a la nube) antes de marcarla como válida.
- Verifica el origen: HTTPS con un certificado de confianza y, mejor aún, firmware firmado.
Con AWS IoT, una forma de coordinarlo es publicar la versión deseada en el Device Shadow de cada dispositivo, o usar AWS IoT Jobs, que gestiona despliegues por grupos con límites de velocidad y criterios de cancelación. Los nodos que no tienen Wi-Fi (por ejemplo, los que solo usan ESP-NOW) necesitan otra vía: que la pasarela les reenvíe el firmware, o actualizarlos por USB.
Cuál usar en cada momento
| Momento | Forma |
|---|---|
| Desarrollando | USB desde el IDE |
| Instalando un dispositivo nuevo o reinstalando uno | Navegador, con borrado completo |
| Dispositivo ya instalado en casa de alguien | OTA |
| Un dispositivo que no arranca | USB o navegador, borrando la flash |
Preguntas frecuentes
¿Puedo romper un ESP32 con una actualización fallida?
Con OTA bien hecha, no: la versión anterior sigue en su partición. Lo que sí puede pasar es que la versión nueva arranque pero no funcione (por ejemplo, que no se conecte); para eso está el rollback. Por USB siempre puedes reinstalar.
¿Cómo reseteo un ESP32 a fábrica?
Borrando la flash completa: con esptool.py erase_flash o con una instalación nueva desde ESP Web Tools. Así desaparece también la configuración guardada en NVS.
¿La OTA funciona con ESP-NOW?
No de forma estándar: la OTA descarga por TCP/IP. Para actualizar dispositivos que solo hablan ESP-NOW, la pasarela tendría que retransmitir el binario en trozos, algo posible pero bastante más complejo.