Como funciona la actualización sin cable en Arduino


¿Vale la pena el OTA en ESP32 si siempre pulso BOOT al cargar?

Imagina esto: Has perfeccionado tu prototipo basado en un ESP32. Lo instalas incluso integrado con Home Assistant integrado. Funciona perfecto… hasta que descubres un bug en el cálculo . ¿Y ahora? ¿Abrir el dispositivo sacar cables y pulsar BOOT otra vez? ¡Aquí entra el OTA para salvarte!
Sí, vale la pena implementarlo aunque la primera carga requiera el botón BOOT. Te explico paso a paso por qué.

La situación actual

Programar un ESP32 por USB/serial siempre exige pulsar BOOT (y a veces RESET) para entrar en modo de flasheo.
Esto es inherente al hardware, independientemente de si usas OTA o no.​

La clave del OTA

Después de esa primera carga, el OTA elimina el cable para siempre.

Paso 1 (instalación inicial):

  • Subes firmware con OTA incluido vía USB (sí, con BOOT).

Paso 2 (actualizaciones futuras):

  • El ESP32 se conecta a WiFi.
  • Envías nuevo firmware remotamente desde Arduino IDE (puerto de red), ESPHome o web server.
  • Cero cables, cero botones, cero contacto físico.

Código listo para usar (OTA básico)

Aquí un sketch mínimo basado en el ejemplo oficial BasicOTA. Cárgalo primero por USB:

#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
const char* ssid = "TU_WIFI"; // Cambia por tu red
const char* password = "TU_PASS"; // Cambia por tu clave
void setup() {
Serial.begin(115200);
Serial.println("Booting OTA");
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("Connection Failed! Rebooting...");
delay(5000);
ESP.restart();
}
// Config OTA
ArduinoOTA.setHostname("OTA"); // Nombre visible en red
// ArduinoOTA.setPassword("admin"); // Descomenta para contraseña
ArduinoOTA
.onStart([]() {
String type;
if (ArduinoOTA.getCommand() == U_FLASH)
type = "sketch";
else
type = "filesystem";
Serial.println("Start updating " + type);
})
.onEnd([]() {
Serial.println("\nEnd");
})
.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
})
.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
Serial.println("Ready");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
ArduinoOTA.handle(); // ¡Esencial! Mantiene OTA activo
// Aquí va tu código ...
}

Pasos para usar:

  1. Cambia SSID/PASS, compila y sube por USB (con BOOT).
  2. Abre Monitor Serie: anota la IP y hostname.
  3. En Arduino IDE: Herramientas > Puerto → selecciona el puerto de red («OTA at IP»).
  4. Sube sketches futuros sin cable.

Cuándo brilla el OTA

  • Instalaciones fijas: Cuadros eléctricos, sensores ocultos ,etc.
  • Flotas de dispositivos: 10+ ESP32 sin visitas.
  • Mantenimiento remoto: Bugs corregidos desde móvil.
  • Alta disponibilidad: Rollbacks automáticos.

Consideraciones clave

  • Seguridad: Activa contraseña con ArduinoOTA.setPassword(). Para prod, usa HTTPS/firmas.
  • Estabilidad: Siempre llama ArduinoOTA.handle() en loop.
  • WiFi: Reconexión auto si signal débil.

Conclusión práctica:

OTA = libertad total post-instalación. Una carga USB inicial, luego updates inalámbricos infinitos.

2024 04 06 19 25 03 Monitorización de gases con Arduino   Buscar con Google y 6 páginas más   Person

Una pantalla mas grande para el ESP32


En un post anterior vimos como usar una pequeña pantalla OLED con un ESP32. Ciertamente una pantalla pequeña consume menos y ocupa muy poco espacio, pero cuando no tenemos esos problemas, es mas interesante usar una pantalla algo mas grande, pues aunque pueda parecer elegante, en realidad con una pantalla tan pequeña apenas hay sitio para mostrar información (además de que posiblemente cueste lo mismo y además suelen usar los mismo pines de datos).

En este post vamos usar la AZ-Delivery 1.77″ ST7735 con ESP32 (comprado en Amazon en https://amzn.to/4pK0utQ ) y la librería de Adafruit donde solo tenemos que adaptar el constructor y asegurarnos de que el cableado coincide con los pines correctos (en nuestro caso 14,13,12,27,26).

Atención porque aunque el manual de Az-Delivery que nos ofrece este pantalla solo muestren como ejemplo un Arduino mega con un adaptador ( ver figura mas abajo), es posible conectar directamente la pantalla AZDelivery de 1.77 pulgadas ST7735 al ESP32 sin conversor de nivel lógico.

En caso de usar un Arduino Uno como hemos visto arriba, el cableado se complica dado que tenemos adaptar 4 líneas de datos a los niveles de 3.3v. Como vemos para configurar este adaptador, se debe conectar el pin VA del LCC a +3.3V y el pin VB a +5V. El pin OE debe unirse a +3.3V mediante una resistencia de arranque de 1 kΩ, mientras que el pin GND se conecta a tierra. En esta configuración, el lado “A” del LCC trabaja con señales de bajo nivel (3.3V) y el lado “B” con señales de alto nivel (5V), tal como se muestra en el diagrama de conexión.

Es muy importante destacar que como el ESP32 opera a niveles lógicos de 3.3V, compatibles con los requisitos de la pantalla (2.7V-3.3V) NO NECESITA UN SHIFTER , a diferencia del Arduino Uno o un ATMega328P que usan 5V y necesitan un shifter como el TXS0108E.

Aclarado este aspecto del conversor que NO NECESITAMOS usando un ESP32, en la imagen vemos las 8 conexiones dela pantalla , por cierto en el mismo orden que la pantalla pequeña que vimos en un post anterior:

Una vez vistas las conexiones, el cableado con los pines elegidos y funcionales debe mantenerse exactamente el mismo mapeo que usábamos en la pantalla de 0.96″:

  • SCL/SCK → GPIO14 (SCK del bus SPI)
  • SDA/MOSI → GPIO13 (MOSI)
  • RES/RST → GPIO12
  • DC/A0 → GPIO27
  • CS → GPIO26
  • VCC → 3.3V
  • GND → GND
  • LED/BL → 3.3V (o a un GPIO si quieres controlar el brillo)​

En el código también debemos ajustar el constructor de Adafruit. En lugar de:

Adafruit_ST7735 tft = Adafruit_ST7735(10, 8, 9);

Usa tus pines (CS, DC, RST):
#define TFT_CS   26
#define TFT_DC 27
#define TFT_RST 12

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

El resto del SPI (SCK=14, MOSI=13) lo maneja SPI por hardware. No hace falta pasarlos al constructor si usamos el SPI por defecto del ESP32.​

Inicialización correcta para 1.77″ 128×160

En setup() usaremos el inicializador recomendado para 1.77″ (Adafruit lo llama “INITR_BLACKTAB” o “INITR_GREENTAB”; muchas 1.77″ van bien con BLACKTAB):

void setup(void) {
SPI.begin(14, -1, 13, 26); // SCK=14, MISO sin usar (-1), MOSI=13, CS=26
tft.initR(INITR_BLACKTAB); // si ves colores raros, prueba INITR_GREENTAB
tft.fillScreen(ST77XX_BLACK);
delay(500);
show_page();
tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
tft.setTextSize(2);
tft.setFont(); // vuelve a la fuente por defecto
}

Fíjate que es setTextColor, no setTextcolour (esa grafía daría error de compilación).​

Se pueden utilizar cualquiera de los siguientes colores predefinidos:
ST77XX_BLACK
ST77XX_RED
ST77XX_BLUE
ST77XX_MAGENTA
ST77XX_ORANGE
ST77XX_WHITE
ST77XX_GREEN
ST77XX_CYAN
ST77XX_YELLOW

O también, se pueden utilizar números hexadecimales de 4-bits que representan un color específico (por ejemplo 0x2AFF)

Las fuentes se encuentran en la carpeta de la librería Adafruit_GFX: … > Arduino > libraries > Adafruit_GFX_Library > Fonts Cuando se importa una fuente específica, se debe importar la librería de fuentes después de la librería Adafruit_GFX, como en las siguientes líneas del código de ejemplo

4. Código adaptado para ESP32 y pines deseados

Aquí sin mas dilaciones un ejemplo de sketch funcional ajustado a un ESP32 con librerías Adafruit y usando los pines descritos ( y por supuesto probado en este humilde blog):

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <Adafruit_ST7735.h>

#define TFT_CS 26
#define TFT_DC 27
#define TFT_RST 12

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

void setup(void) {
// SPI en los pines que quieres: SCK=14, MOSI=13
SPI.begin(14, -1, 13, TFT_CS);

tft.initR(INITR_BLACKTAB); // o INITR_GREENTAB si hace falta
tft.fillScreen(ST77XX_BLACK);
delay(500);
show_page();
tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
tft.setTextSize(2);
tft.setFont(); // fuente por defecto (bitmap)
}

void loop() {
for (uint8_t i = 0; i < 100; i++) {
changing_value(i);
// delay(100);
}
}

void show_page() {
tft.setFont(&FreeSansBold9pt7b);
tft.fillScreen(ST77XX_BLACK);
tft.setTextColor(ST77XX_RED);
tft.setCursor(14, 22);
tft.print("AZ-Delivery");

tft.drawFastHLine(0, 35, 128, ST77XX_GREEN);

tft.drawTriangle(1, 45, 28, 70, 55, 45, ST77XX_WHITE);
tft.fillTriangle(78, 70, 104, 45, 127, 70, 0xA3F6);

tft.drawRect(1, 80, 50, 30, ST77XX_BLUE);
tft.fillRoundRect(78, 80, 50, 30, 5, 0x2D4E);

tft.fillCircle(25, 135, 15, 0x5BA9);
tft.drawCircle(102, 135, 15, ST77XX_GREEN);
tft.drawLine(45, 150, 80, 40, ST77XX_ORANGE);
}

void changing_value(uint8_t value) {
tft.setFont(&FreeSansBold9pt7b);
tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);

if (value < 10) {
tft.setCursor(15, 88);
tft.print("0");
tft.print(value);
} else {
tft.setCursor(15, 88);
tft.print(value);
}
}

Este código muestra cómo inicializar y manejar una pantalla TFT basada en el controlador ST7735 usando la librería Adafruit_ST7735 junto con Adafruit_GFX. Primero se definen los pines de conexión del display (CS, DC y RST) y luego se configura la comunicación SPI utilizando pines personalizados para SCK (14) y MOSI (13). En la función setup(), se inicializa la pantalla con un estilo determinado (INITR_BLACKTAB), se limpia con color negro y se llama a la función show_page(), que dibuja una página inicial con texto, líneas, triángulos, rectángulos y círculos de distintos colores, mostrando las capacidades gráficas de la librería.

En la función loop(), el programa recorre valores del 0 al 99 y los muestra en pantalla mediante la función changing_value(). Esta función actualiza una cifra en una posición fija de la pantalla usando una fuente más grande (FreeSansBold9pt7b) y color blanco sobre fondo negro. De esta forma, el código demuestra tanto cómo renderizar gráficos estáticos (formas y texto) como cómo actualizar valores dinámicos en la pantalla TFT, lo que resulta útil para interfaces visuales en proyectos con microcontroladores, por ejemplo, medidores o indicadores en sistemas embebidos.

Con esto mantenemos exactamente las mismas líneas SPI (14,13,12,27,26) que ya teníamos en la pantalla mas pequeña y aprovechamos la librería oficial de Adafruit para el ST7735 de la AZ-Delivery.​