![]() |
| Escudo ESP12E |
Muy buenas a todos y todas!!!
Revolviendo cajas de la mudanza y junto a placas que no recordaba tener, apareció este escudo con un chip L293D. El ESP12E Motor Shield.
Un clásico entre los aficionados al ESP8266 que, pese a su antigüedad, sigue siendo una puerta de entrada perfecta al control de motores con WiFi.
¿Qué es exactamente este escudo?
El ESP12E Motor Shield es una placa de expansión diseñada exclusivamente para el NodeMCU V2-V3 (la versión con módulo ESP-12E y chip CP2102). Se encaja directamente sobre el NodeMCU y aporta, fundamentalmente, dos canales de control de motores DC o un canal para motor paso a paso, gracias al driver L293D.
No es un escudo nuevo ni revolucionario, pero su combinación de simplicidad, precio contenido y el hecho de que expone todos los pines del NodeMCU lo convierten en una pieza todavía muy útil para robótica básica, maquetas ferroviarias y automatizaciones caseras.
Lo que trae de serie:
- Driver L293D: Doble puente H, capaz de controlar 2 motores DC o 1 motor paso a paso bipolar.
- Alimentación separada: Terminales para VM (alimentación de motores, 4.5V a 36V) y VIN (alimentación de lógica, 4.5V a 9V).
- Jumper VM-VIN: Para usar una sola fuente de alimentación cuando el voltaje es compatible (4.5V–9V).
- Pines de acceso: Todos los GPIO, SPI, UART, AI (entrada analógica) y 3.3V del NodeMCU quedan expuestos.
- Terminales de tornillo: Para conectar los cables de los motores (A+, A-, B+, B-).
Especificaciones técnicas que importan
Un detalle importante: el L293D no soporta frenado activo en este diseño concreto. La placa está cableada de forma que al detener el motor, simplemente se corta la energía (coasting), no se produce un frenado dinámico.
Mapa de pines del escudo
Los pines de control están fijos por hardware. No puedes cambiarlos por software:
Pines libres del NodeMCU
El escudo solo "ocupa" D1, D2, D3 y D4. El resto de pines quedan accesibles, aunque algunos tienen consideraciones especiales:
Diagrama del escudo
Aquí tienes una representación visual generada programáticamente de la disposición del escudo y sus conexiones principales:
Tres ejemplos prácticos
Ejemplo 1: Control de dos motores DC
Este ejemplo usa los canales del escudo A y B. Los motores girarán en una secuencia de avance, giro y retroceso.
/*
* Control de dos motores DC con ESP12E Motor Shield
*
* Pines fijos:
* - Motor A: D1 (PWM velocidad), D3 (dirección)
* - Motor B: D2 (PWM velocidad), D4 (dirección)
*
* Alimentación:
* - VM: fuente externa (4.5V-36V) para los motores
* - VIN: 4.5V-9V para lógica (o puentear VM-VIN si <10V)
*/
// Pines del Motor A
const int pwmA = D1;
const int dirA = D3;
// Pines del Motor B
const int pwmB = D2;
const int dirB = D4;
// Velocidad (0-1023 para ESP8266)
const int velocidad = 800;
void setup() {
// Configurar pines como salida
pinMode(pwmA, OUTPUT);
pinMode(dirA, OUTPUT);
pinMode(pwmB, OUTPUT);
pinMode(dirB, OUTPUT);
// Asegurar estado inicial: motores detenidos
analogWrite(pwmA, 0);
analogWrite(pwmB, 0);
Serial.begin(115200);
Serial.println("Test de dos motores DC");
}
void loop() {
// 1. Ambos motores hacia adelante
Serial.println("Avanzando...");
digitalWrite(dirA, HIGH);
digitalWrite(dirB, HIGH);
analogWrite(pwmA, velocidad);
analogWrite(pwmB, velocidad);
delay(2000);
// 2. Detener
analogWrite(pwmA, 0);
analogWrite(pwmB, 0);
delay(1000);
// 3. Girar (A adelante, B atrás)
Serial.println("Girando...");
digitalWrite(dirA, HIGH);
digitalWrite(dirB, LOW);
analogWrite(pwmA, velocidad);
analogWrite(pwmB, velocidad);
delay(2000);
// 4. Detener
analogWrite(pwmA, 0);
analogWrite(pwmB, 0);
delay(1000);
// 5. Ambos hacia atrás
Serial.println("Retrocediendo...");
digitalWrite(dirA, LOW);
digitalWrite(dirB, LOW);
analogWrite(pwmA, velocidad);
analogWrite(pwmB, velocidad);
delay(2000);
// 6. Detener antes de reiniciar el ciclo
analogWrite(pwmA, 0);
analogWrite(pwmB, 0);
delay(2000);
}
Ejemplo 2: Control de motor paso a paso
El L293D puede controlar un motor paso a paso bipolar. Usaremos los cuatro pines de control (D1, D2, D3, D4) para generar la secuencia de pasos.
/*
* Motor paso a paso bipolar con ESP12E Motor Shield
*
* El motor se conecta a los terminales de Motor A y Motor B.
* La secuencia usa los 4 pines de control:
* - D1, D3: bobina 1
* - D2, D4: bobina 2
*
* Para motores paso a paso de 200 pasos (1.8°/paso)
*/
// Definición de pines
const int bobina1A = D1;
const int bobina1B = D3;
const int bobina2A = D2;
const int bobina2B = D4;
// Secuencia para motor bipolar (full-step)
const int secuencia[4][4] = {
{1, 0, 1, 0}, // Paso 1
{0, 1, 1, 0}, // Paso 2
{0, 1, 0, 1}, // Paso 3
{1, 0, 0, 1} // Paso 4
};
int pasoActual = 0;
void setup() {
pinMode(bobina1A, OUTPUT);
pinMode(bobina1B, OUTPUT);
pinMode(bobina2A, OUTPUT);
pinMode(bobina2B, OUTPUT);
digitalWrite(bobina1A, LOW);
digitalWrite(bobina1B, LOW);
digitalWrite(bobina2A, LOW);
digitalWrite(bobina2B, LOW);
Serial.begin(115200);
Serial.println("Control de motor paso a paso");
}
void loop() {
// Girar 200 pasos en sentido horario
Serial.println("Girando 200 pasos...");
for (int i = 0; i < 200; i++) {
darPaso(1);
delay(2);
}
delay(1000);
// Girar 200 pasos en sentido antihorario
Serial.println("Revirtiendo...");
for (int i = 0; i < 200; i++) {
darPaso(-1);
delay(2);
}
delay(1000);
}
// Ejecuta un paso en la dirección indicada
void darPaso(int direccion) {
pasoActual += direccion;
if (pasoActual >= 4) pasoActual = 0;
if (pasoActual < 0) pasoActual = 3;
digitalWrite(bobina1A, secuencia[pasoActual][0]);
digitalWrite(bobina1B, secuencia[pasoActual][1]);
digitalWrite(bobina2A, secuencia[pasoActual][2]);
digitalWrite(bobina2B, secuencia[pasoActual][3]);
}
Un paso más allá: control por WiFi con interfaz web
Los dos ejemplos anteriores funcionan bien, pero se quedan cortos cuando quieres controlar el motor desde el sofá, sin cables colgando ni potenciómetros. Aquí es donde el ESP8266 despliega todo su potencial: WiFi integrado y un servidor web embebido.
![]() |
| Control analógico para tren a escala con ESP8266 |
Este tercer ejemplo no es solo "otro programa". Es una aplicación completa que convierte tu NodeMCU en un punto de acceso autónomo con una interfaz web responsive, pensada para usarse tanto desde el móvil como desde el navegador del ordenador. No necesitas router, ni app, ni configuración de red. Solo alimentar el NodeMCU, conectarte a su red y abrir una dirección IP.
¿Cómo funciona?
El ESP8266 crea su propia red WiFi (modo Access Point). Cuando te conectas a ella y abres la dirección 192.168.4.1 en el navegador, el ESP te sirve una página HTML que él mismo tiene guardada en su memoria flash. Desde esa página puedes:
- Mover un slider para ajustar la velocidad del motor.
- Pulsar botones para cambiar de dirección (adelante / atrás).
- Detener el motor con un botón de parada.
Toda la comunicación entre la web y el ESP se hace con peticiones HTTP simples. El ESP interpreta esas peticiones, actualiza sus variables internas y aplica los cambios al motor mediante PWM. Además, una rampa de aceleración y frenado suaviza las transiciones para que el motor no arranque ni pare de golpe.
Datos de conexión
Descripción de la interfaz
La página web está diseñada con un estilo oscuro y controles táctiles grandes, pensados para usarse con el dedo en el móvil. Estos son los elementos que encontrarás:
- Indicador de velocidad: un número grande en la parte superior que muestra el porcentaje actual (0% a 100%).
- Slider de velocidad: barra deslizante con degradado verde → amarillo → rojo. Al moverlo, el número de arriba se actualiza en tiempo real.
- Botón "Adelante": verde, cambia el sentido de giro del motor.
- Botón "Atrás": azul, invierte el sentido.
- Botón "Parar": rojo, ancho completo, detiene el motor suavemente.
- Línea de estado: texto inferior que confirma cada acción ("Adelante", "Velocidad: 50%", "Detenido"...).
Un detalle importante: la página es responsive. Se adapta automáticamente al tamaño de la pantalla, ya sea un móvil Android, un iPhone, una tablet o un monitor de escritorio. No necesitas instalar nada.
Los handlers: el puente entre la web y el motor
Detrás de cada botón o slider hay una ruta HTTP que el ESP8266 escucha. Estas rutas se llaman handlers y son funciones que se ejecutan cuando llega una petición concreta. En este proyecto hay cuatro:
Cada handler responde con un texto plano "OK" que el JavaScript de la página usa para confirmar que la orden llegó correctamente. Si no hay respuesta, la web muestra un mensaje de error.
¿Por qué separar la web en un archivo aparte?
En proyectos pequeños, es tentador meter todo el HTML dentro del .ino como una cadena gigante. Pero cuando la web crece (y esta ya tiene casi 100 líneas entre CSS, HTML y JavaScript), el archivo principal se vuelve ilegible.
La solución es usar un archivo .h separado con la página embebida en PROGMEM. Esto tiene dos ventajas enormes:
- Organización: el .ino queda limpio, solo con la lógica del programa.
- Memoria: PROGMEM guarda la web en la memoria flash del ESP8266, no en RAM. El ESP8266 solo tiene unos 40 KB de RAM libre, así que meter una web de varios KB en RAM lo colgaría.
La estructura de archivos en el IDE de Arduino queda así:
ControlTren/
├── ControlTren.ino
└── web_page.h
Para crear el archivo web_page.h en el IDE:
pulsa la flecha junto al botón de verificar → Nueva pestaña → nómbrala web_page.h. El IDE la colocará automáticamente en la misma carpeta que el .ino.
El programa completo
Archivo web_page.h:
/*
* web_page.h
* Página HTML/CSS/JS embebida en PROGMEM.
* Se sirve desde el ESP8266 sin consumir RAM dinámica.
*/
#ifndef WEB_PAGE_H
#define WEB_PAGE_H
#include <Arduino.h>
const char PAGINA_HTML[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Control de Tren</title>
<style>
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
body {
margin: 0; padding: 20px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: #1a1a2e; color: #eee;
display: flex; flex-direction: column;
align-items: center; min-height: 100vh;
}
h1 { font-size: 1.5em; margin: 10px 0 20px; color: #4ade80; }
.panel {
background: #16213e; border-radius: 16px;
padding: 20px; width: 100%; max-width: 420px;
box-shadow: 0 8px 24px rgba(0,0,0,0.4);
}
.velocidad-label {
font-size: 2.5em; font-weight: bold; text-align: center;
color: #4ade80; margin: 10px 0;
font-variant-numeric: tabular-nums;
}
input[type=range] {
width: 100%; height: 40px;
-webkit-appearance: none; background: transparent;
margin: 10px 0;
}
input[type=range]::-webkit-slider-runnable-track {
height: 12px; border-radius: 6px;
background: linear-gradient(to right, #4ade80, #facc15, #ef4444);
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none; width: 36px; height: 36px;
border-radius: 50%; background: #fff;
border: 3px solid #4ade80; margin-top: -12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.5);
cursor: pointer;
}
input[type=range]::-moz-range-track {
height: 12px; border-radius: 6px;
background: linear-gradient(to right, #4ade80, #facc15, #ef4444);
}
input[type=range]::-moz-range-thumb {
width: 36px; height: 36px; border-radius: 50%;
background: #fff; border: 3px solid #4ade80; cursor: pointer;
}
.botones {
display: grid; grid-template-columns: 1fr 1fr;
gap: 12px; margin-top: 20px;
}
button {
padding: 18px 10px; font-size: 1.1em; font-weight: bold;
border: none; border-radius: 12px; cursor: pointer;
color: #fff; transition: transform 0.1s, opacity 0.2s;
user-select: none;
}
button:active { transform: scale(0.95); opacity: 0.85; }
.btn-adelante { background: #22c55e; }
.btn-atras { background: #3b82f6; }
.btn-parar { background: #ef4444; grid-column: span 2; }
.btn-parar-emergencia { background: #dc2626; grid-column: span 2; }
.estado {
margin-top: 16px; text-align: center;
font-size: 0.9em; color: #94a3b8;
}
.indicador {
display: inline-block; width: 10px; height: 10px;
border-radius: 50%; margin-right: 6px;
background: #64748b; vertical-align: middle;
}
.indicador.on { background: #4ade80; box-shadow: 0 0 8px #4ade80; }
</style>
</head>
<body>
<h1>🚂 Control de Tren</h1>
<div class="panel">
<div class="velocidad-label" id="velLabel">0%</div>
<input type="range" id="slider" min="0" max="100" value="0" step="1">
<div class="botones">
<button class="btn-adelante" onclick="setDir(1)">▶ Adelante</button>
<button class="btn-atras" onclick="setDir(-1)">◀ Atrás</button>
<button class="btn-parar" onclick="parar()">■ Parar</button>
<button class="btn-parar-emergencia" onclick="emergencia()">🛑 PARADA EMERGENCIA</button>
</div>
<div class="estado">
<span class="indicador" id="ind"></span>
<span id="estadoTxt">Desconectado</span>
</div>
</div>
<script>
const slider = document.getElementById('slider');
const velLabel = document.getElementById('velLabel');
const ind = document.getElementById('ind');
const estadoTxt= document.getElementById('estadoTxt');
let direccionActual = 0;
slider.addEventListener('input', () => {
velLabel.textContent = slider.value + '%';
});
slider.addEventListener('change', enviarVelocidad);
let throttleTimer = null;
slider.addEventListener('input', () => {
if (throttleTimer) return;
throttleTimer = setTimeout(() => {
enviarVelocidad();
throttleTimer = null;
}, 100);
});
function enviarVelocidad() {
fetch('/velocidad?valor=' + slider.value)
.then(r => r.text())
.then(txt => { marcarConectado(true); })
.catch(() => marcarConectado(false));
}
function setDir(d) {
direccionActual = d;
fetch('/direccion?valor=' + d)
.then(r => r.text())
.then(() => {
marcarConectado(true);
estadoTxt.textContent = d === 1 ? 'Adelante' : 'Atrás';
})
.catch(() => marcarConectado(false));
}
function parar() {
slider.value = 0;
velLabel.textContent = '0%';
fetch('/parar')
.then(r => r.text())
.then(() => {
marcarConectado(true);
estadoTxt.textContent = 'Parado';
})
.catch(() => marcarConectado(false));
}
function emergencia() {
slider.value = 0;
velLabel.textContent = '0%';
direccionActual = 0;
fetch('/emergencia')
.then(r => r.text())
.then(() => {
marcarConectado(true);
estadoTxt.textContent = 'EMERGENCIA';
})
.catch(() => marcarConectado(false));
}
function marcarConectado(ok) {
if (ok) {
ind.classList.add('on');
} else {
ind.classList.remove('on');
estadoTxt.textContent = 'Desconectado';
}
}
setInterval(() => {
fetch('/estado')
.then(r => r.json())
.then(d => {
marcarConectado(true);
estadoTxt.textContent = 'Vel: ' + d.vel + ' | Dir: ' +
(d.dir === 0 ? 'Parado' : (d.dir === 1 ? 'Adelante' : 'Atrás'));
})
.catch(() => marcarConectado(false));
}, 2000);
</script>
</body>
</html>
)rawliteral";
#endif
Archivo ControlTren.ino:
/*
* ============================================================
* CONTROL DE TREN A ESCALA N - Ibertren Cuco 020
* ============================================================
*
* NodeMCU + ESP12E Motor Shield (L293D)
*
* Modo: Access Point WiFi
* Red: TrenControl / tren1234
* URL: http://192.168.4.1
*
* Frecuencia PWM: 2.5 kHz (óptima para motor de escobillas
* de escala N). Si tuvieras motor coreless,
* cambiar a 20000 y poner disipador al L293D.
*
* Página web en archivo separado: web_page.h
* ============================================================
*/
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include "web_page.h"
// ==================== CONFIGURACIÓN WIFI ====================
const char* SSID_AP = "TrenControl";
const char* PASSWORD_AP = "tren1234";
// ==================== PINES DEL SHIELD ====================
#define PIN_PWM_A 5 // D1 -> GPIO5 (velocidad PWM, Motor A)
#define PIN_DIR_A 0 // D3 -> GPIO0 (dirección, Motor A)
// ==================== PARÁMETROS DE CONTROL ====================
const int PWM_MAX = 1023;
const int VELOCIDAD_MAX = 900;
const int PASO_RAMPA = 5;
const int INTERVALO_RAMPA = 30;
const int FRECUENCIA_PWM = 2500; // 2.5 kHz, óptimo escala N
// ==================== ESTADO GLOBAL ====================
int velocidadObjetivo = 0;
int velocidadActual = 0;
int direccion = 0;
unsigned long ultimaRampa = 0;
// ==================== SERVIDOR WEB ====================
ESP8266WebServer server(80);
// ============================================================
// FUNCIONES AUXILIARES
// ============================================================
void aplicarDireccion(int dir) {
if (dir == 1) {
digitalWrite(PIN_DIR_A, HIGH);
} else if (dir == -1) {
digitalWrite(PIN_DIR_A, LOW);
}
}
void aplicarVelocidad(int v) {
if (v < 0) v = 0;
if (v > VELOCIDAD_MAX) v = VELOCIDAD_MAX;
analogWrite(PIN_PWM_A, v);
}
// ============================================================
// HANDLERS DE LAS RUTAS WEB
// ============================================================
void handleRaiz() {
server.send_P(200, "text/html", PAGINA_HTML);
}
void handleVelocidad() {
if (server.hasArg("valor")) {
int pct = server.arg("valor").toInt();
if (pct < 0) pct = 0;
if (pct > 100) pct = 100;
velocidadObjetivo = map(pct, 0, 100, 0, VELOCIDAD_MAX);
if (velocidadObjetivo > 0 && direccion == 0) {
direccion = 1;
aplicarDireccion(direccion);
}
server.send(200, "text/plain", "OK");
} else {
server.send(400, "text/plain", "Falta parametro valor");
}
}
void handleDireccion() {
if (server.hasArg("valor")) {
int d = server.arg("valor").toInt();
if (d < -1) d = -1;
if (d > 1) d = 1;
direccion = d;
aplicarDireccion(direccion);
server.send(200, "text/plain", "OK");
} else {
server.send(400, "text/plain", "Falta parametro valor");
}
}
void handleParar() {
velocidadObjetivo = 0;
server.send(200, "text/plain", "OK");
}
void handleEmergencia() {
velocidadObjetivo = 0;
velocidadActual = 0;
direccion = 0;
analogWrite(PIN_PWM_A, 0);
server.send(200, "text/plain", "OK");
}
void handleEstado() {
String json = "{\"vel\":" + String(velocidadActual) +
",\"dir\":" + String(direccion) + "}";
server.send(200, "application/json", json);
}
// ============================================================
// SETUP
// ============================================================
void setup() {
Serial.begin(115200);
Serial.println("\n\n=== Control de Tren Ibertren Cuco 020 ===");
pinMode(PIN_PWM_A, OUTPUT);
pinMode(PIN_DIR_A, OUTPUT);
analogWriteRange(PWM_MAX);
analogWriteFreq(FRECUENCIA_PWM); // 2.5 kHz
analogWrite(PIN_PWM_A, 0);
digitalWrite(PIN_DIR_A, LOW);
WiFi.softAP(SSID_AP, PASSWORD_AP);
Serial.print("AP: ");
Serial.println(SSID_AP);
Serial.print("IP: ");
Serial.println(WiFi.softAPIP());
server.on("/", handleRaiz);
server.on("/velocidad", handleVelocidad);
server.on("/direccion", handleDireccion);
server.on("/parar", handleParar);
server.on("/emergencia", handleEmergencia);
server.on("/estado", handleEstado);
server.begin();
Serial.println("Servidor listo en http://192.168.4.1");
}
// ============================================================
// LOOP
// ============================================================
void loop() {
server.handleClient();
unsigned long ahora = millis();
if (ahora - ultimaRampa >= INTERVALO_RAMPA) {
ultimaRampa = ahora;
if (velocidadActual < velocidadObjetivo) {
velocidadActual += PASO_RAMPA;
if (velocidadActual > velocidadObjetivo) velocidadActual = velocidadObjetivo;
aplicarVelocidad(velocidadActual);
} else if (velocidadActual > velocidadObjetivo) {
velocidadActual -= PASO_RAMPA;
if (velocidadActual < velocidadObjetivo) velocidadActual = velocidadObjetivo;
aplicarVelocidad(velocidadActual);
if (velocidadActual == 0 && direccion == 0) {
aplicarDireccion(0);
}
}
}
}
Detalles que marcan la diferencia
La rampa de aceleración. Fíjate en que el código no aplica directamente la velocidad que pides desde la web. En su lugar, guarda una velocidad objetivo y va acercando la velocidad actual hacia ella en pasos pequeños. Esto simula la inercia de un motor real y evita tirones bruscos. Puedes ajustar la suavidad cambiando PASO_RAMPA (más grande = más brusco) y INTERVALO_RAMPA (más grande = más lento).
La frecuencia PWM. El programa usa analogWriteFreq(2500), es decir, 2.5 kHz. Esta frecuencia es un buen equilibrio para el L293D: lo suficientemente alta para que el motor no zumbe, pero no tanto como para que el chip se caliente en exceso. Si oyes un pitido agudo, sube a 4000 Hz. Si el L293D se calienta mucho, baja a 1000 Hz.
El estado inicial seguro. Antes de crear el Access Point, el código configura los pines como salida y los deja en reposo (PWM a 0, dirección en LOW). Esto evita que el motor arranque solo al enchufar el NodeMCU, algo que puede pasar si los pines quedan flotando.
El auto-arranque de dirección. Si mueves el slider sin haber pulsado antes "Adelante" o "Atrás", el código asume que quieres ir hacia adelante. Es un pequeño detalle de usabilidad que evita que el motor se quede parado sin saber por qué.
Cómo usarlo desde el móvil
- Alimenta el NodeMCU (por USB o con la fuente externa).
- En el móvil, ve a Ajustes → WiFi y conéctate a la red MotorControl con la contraseña motor1234.
- Android avisará de que la red "no tiene acceso a Internet". Es normal: el ESP no tiene salida a Internet, solo sirve la web local. Elige "Mantener conexión".
- Abre Chrome (o cualquier navegador) y escribe 192.168.4.1.
- Ya tienes el panel de control en pantalla.
Si quieres, puedes añadir la página a la pantalla de inicio del móvil como si fuera una app. En Chrome: menú de tres puntos → "Añadir a pantalla de inicio". Así la abres con un solo toque.
¿Y si quiero controlarlo desde fuera de casa?
Este ejemplo usa modo Access Point, lo que significa que el alcance está limitado a la cobertura WiFi del ESP8266 (unos 20-30 metros en interior, más en exterior). Para controlarlo desde fuera de casa necesitarías:
- Modo Station: conectar el ESP a tu router doméstico en lugar de crear su propia red. Tendrías que cambiar WiFi.softAP() por WiFi.begin() y usar la IP que te asigne el router.
- Redirección de puertos: abrir el puerto 80 en tu router hacia la IP del ESP. Esto expone el control a Internet, con los riesgos de seguridad que conlleva.
- Un broker MQTT: si quieres algo más robusto y seguro, MQTT es el camino. Pero eso ya es otro proyecto.
Para uso doméstico, el modo Access Point es más que suficiente. Y si tienes la maqueta en una habitación concreta, la cobertura del ESP llega de sobra a cualquier punto de esa habitación.
Reflexión final
Este tercer ejemplo muestra cómo un pequeño ESP12E Motor Shield, que a primera vista parece solo un driver de motores, se convierte en el corazón de una aplicación completa cuando le añades el WiFi del ESP8266. La combinación de hardware sencillo y software bien estructurado es lo que hace que estos proyectos sean tan satisfactorios.
Lo mejor de todo: no necesitas nada más que la placa, un motor y un navegador. Ni apps, ni cables, ni configuraciones complicadas. Enchufas, te conectas y controlas. Así debería ser siempre la electrónica.
Si te gusta el contenido o tienes alguna duda estare encantado de leer y contestar, Saludos a todos y todas
Otros articulos de la web que te pueden interesar:
- ESP8266: Cómo usar LittleFS para guardar información en la memoria Flash
- ESP32-C3 Super Mini con OLED SH1106: Tutorial de menús y controles físicos
- ESP32 con OLED 128x32: Velocímetro y dashboard para vehículos RC
Saludos a todas y todos!!!







No hay comentarios :
Publicar un comentario