WiDC: Robot FPV Wi‑Fi – Control Remoto con Video en Vivo
Componentes y suministros
| Componente | Cantidad |
|---|---|
| Arduino UNO | 1 |
| Espressif ESP8266 ESP-01 | 1 |
| Arduino Proto Shield | 1 |
| Motor DC con rueda | 1 |
| Puente H (H-bridge) | 1 |
Aplicaciones y servicios en línea
- Autodesk Fusion 360
- Arduino IDE
Sobre este proyecto
¿Qué tal usar un robot controlado remotamente para explorar tu entorno, alcanzar lugares inaccesibles, vigilancia, tomar fotos, grabar videos o transmitir video en vivo? Este tutorial te muestra cómo construir uno de forma económica para todos esos propósitos.
Este tutorial es una mejora de mi anterior proyecto (Robot Rover FPV Controlado por Wi-Fi con Arduino y ESP8266), presentando un robot casero más rápido. Se explica cómo diseñar y construir un robot de dos ruedas controlado remotamente a través de una red Wi-Fi, usando dos motores DC, un Arduino Uno y un módulo Wi-Fi ESP8266.
El robot se controla desde un navegador web ordinario mediante una interfaz HTML. Un smartphone Android puede usarse para transmitir video y audio desde el robot hacia la interfaz de control.
Al igual que en el tutorial anterior, se muestra cómo diseñar y construir una estructura de bajo costo para un proyecto robótico, usando solo herramientas comunes (sin necesidad de impresora 3D, cortadora láser o router CNC).
Los componentes usados pueden no ser los óptimos para este propósito. Por ejemplo, un NodeMCU podría reemplazar la combinación Arduino + ESP8266. Una Raspberry Pi con cámara sustituiría al smartphone y controlaría los motores. Incluso es posible usar un smartphone Android como "cerebro" del robot.
Este tutorial deriva de otro proyecto en el que participo: Joy Robot (Hackaday / Hackster), y se usa el mismo hardware por simplicidad. Se eligió Arduino Uno por su accesibilidad y facilidad de uso, y se diseñó un shield simple. En el proyecto original también se controlaban servos y matrices de LEDs, y se interfazaba con el ESP. El smartphone es reemplazado por una tablet que ejecuta otras aplicaciones. Otros tutoriales relacionados:
- Control de Matriz de LEDs con Arduino Uno: Instructables
- Servomotores Controlados por Navegador Wi-Fi: Instructables
- Robot Controlado por Wi-Fi con Wemos D1 y Blynk: Hackster
Esta guía puede adaptarse y modificarse en su forma o interfaz de control según tus necesidades.
Paso 1: Herramientas
Las siguientes herramientas se usaron para la construcción del prototipo:
- Sierra de mano (para cortar láminas de acrílico)
- Destornillador (para colocar tornillos y tuercas)
- Regla (para medir dimensiones)
- Cúter (para cortar la estructura y hacer agujeros)
- Taladro (para perforar el acrílico)
- Lija (para suavizar bordes ásperos)
- Soldador (para soldar terminales de motores)
- Computadora (para compilar y cargar el código en Arduino)
Estas herramientas se usaron para la estructura mecánica, ensamblaje y conexiones electrónicas. Algunas no son necesarias si compras la estructura en lugar de construirla. También podrías usar otros equipos (impresora 3D, cortadora láser) según lo disponible en tu makerspace.
Paso 2: Estructura mecánica y materiales
Materiales mecánicos:
- Lámina de acrílico de 2 mm
- Motorreductor DC con rueda (x2)
- Rueda loca de 30 mm (x1)
- Tornillos M2 x 10 mm (x5)
- Tuercas M2 x 1,5 mm (x5)
- Tornillos M3 x 10 mm (x9)
- Tornillos M3 x 40 mm (x4)
- Tuercas M3 x 1,5 mm (x12)
- Tornillos 5/32" x 1" (x4)
- Tuercas 5/32" (x12)
- Soporte universal para teléfono
- Soportes angulares de acero en "L" (30 x 30 mm) (x4)
Paso 3: Componentes electrónicos
- Arduino Uno
- ESP8266
- Proto Shield (para versión compacta) o protoboard común
- Resistencia de 1 kΩ (x2)
- Resistencia de 10 kΩ (x1)
- Motorreductor DC con rueda (x2)
- Módulo puente H
- Cables jumper
- Power bank USB 5V
Todos los componentes se encuentran fácilmente en tiendas en línea. La elección de componentes proviene de otro proyecto y puede optimizarse usando otro microcontrolador.
Paso 4: Diseño de la estructura
Primero diseñé la estructura mecánica en Fusion 360. También puedes comprar un kit robótico completo si no quieres construir tu propia estructura (en ese caso, salta al Paso 6). Se diseñó un bastidor de acrílico de bajo costo para montar motores y componentes, construido con herramientas ordinarias.
Se modelaron en 3D los componentes principales para definir su disposición. Algunos modelos se descargaron de GrabCAD:
- Arduino Uno
- Motorreductor
- Puente H
- Power bank
- Soporte universal para teléfono
Los componentes electrónicos se dispusieron en un plano para calcular la huella del robot. Luego se eligió la posición de motores y ruedas para una estructura estable. El diseño final consta de tres placas (base y dos laterales) unidas con soportes.
base.pdf base.svg
Paso 5: Construcción y ensamblaje de la estructura
1. Cortar la base de acrílico según el plano 2D: Puede hacerse con cortadora láser o, como en mi caso, con herramientas comunes. Transfiere las dimensiones imprimiendo el plano en papel adhesivo, pégalo al acrílico, marca con cúter y regla, rompe la lámina aplicando presión, y lija los bordes.
2. Taladrar los agujeros según el plano: Usa taladro o, si no tienes, un punzón o cúter para hacer y agrandar los orificios. Retira la plantilla adhesiva.
3. Montar componentes con tornillos y tuercas según el modelo 3D: Tornillos M3 para soportes y motores DC; M2 para electrónica; 5/32" para rueda delantera y clip del smartphone.
base.pdf
Paso 6: Ensamblaje de la electrónica
El circuito usa Arduino Uno como controlador principal, interfazando con ESP8266 para comunicación Wi-Fi. Arduino controla los motores DC mediante un puente H que maneja dos motores independientemente en ambas direcciones.
Un power bank alimenta la electrónica conectado al puerto USB del Arduino: fácil de cargar, reemplazable y proporciona 5V seguros.
Conecta todos los componentes según el esquemático. Necesitarás cables jumper para el ESP8266 (no es compatible con protoboard), puente H y motores. Puedes usar Proto Shield, protoboard común o diseñar tu propio shield para Arduino.
El ESP8266-01 no es compatible con protoboard; se conecta con jumpers pero no se fija a la estructura. Conecta USB al Arduino y pasa al siguiente paso.
wiDC_Esquematico.pdf wiDC.fzz wiDC_bb.pdf
Paso 7: Código Arduino
Instala el último Arduino IDE. No se necesitan librerías adicionales para comunicación con ESP8266 ni control de motores. Verifica el baudrate de tu ESP8266 y ajústalo en el código. Descarga el código (WiDC.ino) y reemplaza XXXXX por el SSID de tu router Wi-Fi e YYYYY por la contraseña. Conecta Arduino por USB y sube el código.
// Incluir librerías
#include <SoftwareSerial.h>
SoftwareSerial esp8266(3, 2); // RX pin = 3, TX pin = 2
// Definición de variables
#define DEBUG true
int state = 5; // Estado inicial (5 = espera)
// Pines de motores
const int motor1Pin1 = 5;
const int motor1Pin2 = 6;
const int motor2Pin1 = 9;
const int motor2Pin2 = 10;
// Velocidad de motores
int motorSpeed = 150; // PWM
void setup() {
pinMode(motor1Pin1, OUTPUT);
pinMode(motor1Pin2, OUTPUT);
pinMode(motor2Pin1, OUTPUT);
pinMode(motor2Pin2, OUTPUT);
Serial.begin(9600);
esp8266.begin(9600);
sendData("AT+RST\r\n", 2000, DEBUG); // Reset módulo
sendData("AT+CWMODE=1\r\n", 1000, DEBUG); // Modo estación
sendData("AT+CWJAP=\"XXXXX\",\"YYYYY\"\r\n", 2000, DEBUG); // Conectar Wi-Fi
delay(5000); // Esperar conexión
sendData("AT+CIFSR\r\n", 1000, DEBUG); // Mostrar IP
sendData("AT+CIPMUX=1\r\n", 1000, DEBUG); // Múltiples conexiones
sendData("AT+CIPSERVER=1,80\r\n", 1000, DEBUG); // Servidor web puerto 80
}
void loop() {
if (esp8266.available()) {
if (esp8266.find("+IPD,")) {
String msg;
esp8266.find("?");
msg = esp8266.readStringUntil(' ');
String command = msg.substring(0, 3);
Serial.println(command);
if(command == "cm1") state = 1; // Adelante
else if(command == "cm2") state = 2; // Atrás
else if(command == "cm3") state = 3; // Derecha
else if(command == "cm4") state = 4; // Izquierda
else if(command == "cm5") state = 5; // Parar
}
}
// Estado 1: Adelante
if (state == 1) {
analogWrite(motor1Pin1, motorSpeed); digitalWrite(motor1Pin2, LOW);
analogWrite(motor2Pin1, motorSpeed); digitalWrite(motor2Pin2, LOW);
}
// Estado 2: Atrás
else if (state == 2) {
digitalWrite(motor1Pin1, LOW); analogWrite(motor1Pin2, motorSpeed);
digitalWrite(motor2Pin1, LOW); analogWrite(motor2Pin2, motorSpeed);
}
// Estado 3: Derecha
else if (state == 3) {
analogWrite(motor1Pin1, motorSpeed); digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1, LOW); analogWrite(motor2Pin2, motorSpeed);
}
// Estado 4: Izquierda
else if (state == 4) {
digitalWrite(motor1Pin1, LOW); analogWrite(motor1Pin2, motorSpeed);
analogWrite(motor2Pin1, motorSpeed); digitalWrite(motor2Pin2, LOW);
}
// Estado 5: Parar
else if (state == 5) {
digitalWrite(motor1Pin1, LOW); digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1, LOW); digitalWrite(motor2Pin2, LOW);
}
}
String sendData(String command, const int timeout, boolean debug) {
String response = "";
esp8266.print(command);
long int time = millis();
while ((time + timeout) > millis()) {
while (esp8266.available()) {
char c = esp8266.read();
response += c;
}
}
if (debug) Serial.print(response);
return response;
}
Explicación del código:
Se usa SoftwareSerial en pines 2 y 3 para comunicar Arduino con ESP8266, ya que el Uno solo tiene un puerto serial hardware. El baudrate del ESP8266 debe coincidir (9600 en este caso; por defecto suelen venir a 115200, pero SoftwareSerial no funciona bien a esa velocidad).
En setup() se inicializan ambos puertos serie y se envían comandos AT al ESP8266: reset, modo estación, conexión a red Wi-Fi, obtención de IP, habilitación de múltiples conexiones e inicio de servidor web en puerto 80.
La función auxiliar sendData envía comandos, espera respuesta y la muestra en el Monitor Serie si DEBUG es true.
En loop() se escuchan comandos entrantes (+IPD,). Se extraen los primeros 3 caracteres (cm1–cm5) que definen 5 estados: adelante, atrás, derecha, izquierda, parada. El robot mantiene el estado hasta recibir otro comando.
Cada estado define las señales PWM en los pines de los motores. analogWrite permite modular la velocidad. Los motores trabajan entre 3–6V; con 5V se puede variar el voltaje promedio vía PWM entre 3–5V para controlar velocidad.
WiDC.ino
Paso 8: Interfaz de control basada en web
Se diseñó una interfaz HTML para controlar el robot. Descarga interface.rar, extrae los archivos y ábrelos en Firefox. La interfaz tiene un formulario para ingresar la IP del módulo ESP y del servidor de video/audio (app IP Webcam en Android). Incluye un botón de prueba que hace girar el robot. Las flechas del teclado controlan el movimiento.
Un smartphone Android transmite video y audio al interfaz. App recomendada: IP Webcam (Google Play).
HTML explicado:
La interfaz tiene dos divisiones: una para audio/video (servidor IP Webcam) y otra para comandos.
División audio/video: formulario con textbox y botón para ingresar IP del servidor webcam (por defecto 192.168.0.5). Video y audio se cargan en objetos <object>.
<div id="video_and_audio" style="position: absolute; top: 50px; width:25%">
<form name="myform" action="" method="GET">
IP Webcam (IP): <input type="text" name="inputbox" value="192.168.0.5">
<input type="button" name="button1" value="Load" onClick="readUrlAV(this.form)">
</form>
<object id="video" type="text/html" data="https://192.168.0.5:8080/video" style="position: absolute; width:100%; height:480px;"></object>
<object id="audio" type="text/html" data="https://192.168.0.5:8080/audio.opus" style="position: absolute; width:388px; height:30px; left:8px; top:425px;"></object>
</div>
División comandos: formulario para ingresar IP del ESP8266. Imagen de teclado e instrucciones.
<div id="commands" style="position: absolute; top: 50px; left:35%; width:65%">
<form name="myform2" action="" method="GET">
Arduino IP Address: <input type="text" name="inputbox" Value="192.168.0.5">
<input type="button" name="button3" Value="Test" onClick="testarArduino(this.form)">
</form>
<img src="images/keyboard.png" style="margin-left:100px; margin-top:50px;">
<h4> Press and hold keyboard arrow keys to move the robot </h4>
</div>
JavaScript (archivos jquery.js y myscript.js) maneja la interfaz y envía comandos al Arduino.
JavaScript explicado:
Función readUrlAV lee la IP del formulario y la carga en los objetos video y audio.
function readUrlAV(form) {
TextVar = form.inputbox.value;
VideoVar = "https://" + TextVar + ":8080/video";
AudioVar = "https://" + TextVar + ":8080/audio.opus";
document.getElementById("video").setAttribute('data', VideoVar);
document.getElementById("audio").setAttribute('data', AudioVar);
}
El script detecta pulsaciones de teclas de flecha (arriba=38, abajo=40, izquierda=37, derecha=39) y envía comandos (cm1–cm4) vía HTTP GET a la IP del Arduino. Un latch evita repeticiones.
var latch = false;
document.onkeydown = checkKeyDown;
function checkKeyDown(e) {
e = e || window.event;
if (e.keyCode == '38') { // Flecha arriba
if (!latch) { sendCommand("cm1"); latch = true; }
} else if (e.keyCode == '40') { // Flecha abajo
if (!latch) { sendCommand("cm2"); latch = true; }
} else if (e.keyCode == '37') { // Flecha izquierda
if (!latch) { sendCommand("cm3"); latch = true; }
} else if (e.keyCode == '39') { // Flecha derecha
if (!latch) { sendCommand("cm4"); latch = true; }
}
}
function sendCommand(cmd) {
TextVar = myform2.inputbox.value;
ArduinoVar = "https://" + TextVar + ":80";
$.get(ArduinoVar, { [cmd]: 1000 });
}
Al soltar cualquier flecha, se ejecuta doNothing (envía cm5 y resetea latch).
document.onkeyup = checkKeyUp;
function checkKeyUp(e) {
if (['38','40','37','39'].includes(e.keyCode)) setTimeout(doNothing, 200);
}
function doNothing() {
TextVar = myform2.inputbox.value;
ArduinoVar = "https://" + TextVar + ":80";
$.get(ArduinoVar, { "cm5": 1000 });
latch = false;
}
interface.rar
Paso 9: Uso
Al reiniciar Arduino, intentará conectar a tu Wi-Fi automáticamente. Usa el Monitor Serie para verificar la conexión y obtener la IP asignada al ESP8266. Abre el archivo HTML en Firefox e ingresa esa IP en el cuadro de texto. Desconecta Arduino del PC y conéctalo al power bank. Espera a que reconecte. Inicia la app IP Webcam en el smartphone montado en el robot. Ingresa la IP de video/audio en la interfaz y conecta al servidor. Puede ser necesario bajar la resolución de video en la app para reducir latencia. Mantén pulsadas las flechas del teclado para mover el robot y diviértete explorando.
Nota: El robot funciona en lazo abierto, por lo que es difícil que avance en línea recta; pequeñas diferencias entre motores y alineación causan desviaciones acumulativas. El robot mantiene el estado hasta recibir un comando distinto. A veces el ESP8266 pierde mensajes; si se pierde un "cm5", el robot seguirá moviéndose tras soltar la tecla. Se puede mejorar la interpretación de comandos para evitarlo.
Código
- Código Arduino (WiDC.ino)
- Interfaz web (interface.rar)
Piezas personalizadas y cajas
base_7JLgOpcox6.svg
Esquemáticos
Ver archivos PDF y Fritzing en la sección de electrónica.
Proceso de manufactura
- Construya un robot Raspberry Pi controlado por Bluetooth con retroalimentación de audio
- Proyecto Dados Digitales Arduino: Construye tu Propio Generador de Números Aleatorios con LCD
- Mando USB para juegos DIY con Arduino – Construye tu propio gamepad de alto rendimiento
- Robot Seguidor de Línea Autónomo con Arduino UNO: Guía Paso a Paso
- Construye un robot controlado por voz con Arduino Nano
- MobBob: Robot Arduino Impreso en 3D, Controlado por Smartphone Android
- Pixel Chaser: Juego LED Interactivo de Un Toque con Arduino Nano
- Levitación magnética repulsiva con Arduino: Circuito simple y guía DIY
- PiBot: Robot Pianista con Arduino para Interpretación Musical de Precisión
- Robot Asistente Doméstico Autónomo "O'nine" – Integración ROS, Alexa y Brazo Robótico
- Pong Neón en Matriz NeoPixel con Arduino Nano