Sistema Portátil de Vigilancia Remota con Cámara y Robot Móvil
Componentes y materiales
| SparkFun Arduino Pro Mini 328 - 5V/16MHz | × | 1 |
| Rueda + Motor DC con reductora + soporte | × | 1 |
| Driver Dual H-Bridge L298 SparkFun | × | 1 |
| Raspberry Pi 3 Model B | × | 1 |
| Módulo Cámara Raspberry Pi | × | 1 |
Herramientas y máquinas necesarias
| Adaptador USB-Serie FTDI FT232RL |
| Arduino IDE |
| Taladro |
| Sierra de hoja fina |
| Destornilladores |
| Soldador (genérico) |
| Cortaalambres |
Sobre el proyecto
Este interesante pero complejo proyecto cubre desde el diseño y construcción de un robot, hasta configuraciones avanzadas en Linux (Raspberry Pi), pasando por desarrollo de app Android y control remoto del robot.
Es más ambicioso que el promedio, pero aprenderás mucho examinando las ideas o replicando el proyecto completo.
Primero construiremos el robot con metacrilato, láminas plásticas, motores DC con reductora y electrónica varia. El dispositivo moverá independientemente las dos ruedas delanteras y tendrá ruedas traseras omnidireccionales (360°). Tendrá faro frontal. Luego configuraremos la Raspberry Pi alimentando el robot, instalaremos dependencias. Finalmente construiremos e instalaremos app Android para control remoto vía cámara y WiFi.
Tecnologías y conceptos explorados:
- Plataformas de desarrollo: Arduino, Raspberry Pi, Android
- Electrónica: H-bridge, transistor para carga alta, sensores infrarrojos
- Linux: Docker, Docker Compose, systemctl, streaming de vídeo
- Programación: Apps Android, Python, lenguaje Arduino, comunicación serie, MQTT
Paso 1: Materiales necesarios

Piezas:
- Lámina de metacrilato (plexiglass)
- Lámina plástica (también sirve metacrilato)
- Pegamento
- Rueda + Motor DC con reductora + soporte. Tornillos/tuercas pequeños, separadores hexagonales metálicos
- 2× Ruedas omnidireccionales (cualquier dirección)
- Pequeña linterna LED (se convertirá en faro)
- Arduino Pro Mini 328p
- 2× Sensores infrarrojos de obstáculos
- PCB
- Transistor NPN (para pilotar faro)
- Regulador L7805CV 5V
- H-bridge L298
- Resistencia 220 Ohm
- Conector USB macho
- Conector Micro USB macho
- Varios cables
- Regulador 3.3V (comunicación Arduino-Pi)
- Conectores PCB macho/hembra
- Interruptor On/Off
- Conector XT-60 hembra LiPo
- Batería LiPo 2S 1300 mAh con conector XT-60
- Power bank 5V
- Raspberry Pi 3
- Tarjeta microSD para Pi
- Carcasa Raspberry Pi
- Cámara Raspberry Pi
Herramientas: Adaptador FTDI, Arduino IDE, Taladro, Sierra fina, Destornilladores, Soldador, Cortaalambres.
Habilidades: Soldadura, programación básica Arduino, configuración servicios Linux, instalación paquetes.
Paso 2: Construcción de la plataforma robot
Especificaciones del robot:
- Tracción en ruedas delanteras con dos motores DC independientes
- Ruedas traseras omnidireccionales (360°)
- Dirección por diferencia de velocidad en ruedas delanteras (sin mecanismo dirección separado), giro sobre su eje
- Luces en parte superior
- Espacio para electrónica, baterías, carcasa Pi con cámara
- Despeje al suelo de unos cm para superar obstáculos pequeños
Revisa las imágenes para detalles y consejos de construcción.












Placa base: 18×13 cm. Motores DC con soportes metálicos, tornillos/tuercas. H-bridge en centro de placa mirando al suelo. Ruedas traseras con separadores hexagonales 2 cm (macho/hembra). Agujero grande cerca del H-bridge para pasar cables a parte superior.
Parte superior: Dos placas en "L" (12×13 cm y 6.5×13 cm) pegadas. Cubren electrónica, soportan faro y carcasa Pi. Se unen a base con separadores hexagonales 6 cm.
Paso 3: Construcción de la electrónica



Pinout (Arduino Pro Mini):
- Faro LED: D3
- Motor izquierdo: PWM (D5), EN1, EN2 (A4, A5)
- Motor derecho: PWM (D6), EN1, EN2 (A3, A2)
- Sensores IR: Frontal (A0), Trasero (A1)
- Comunicación Raspberry Pi: Tx: D11, Rx: D10
Montaje PCB y ensamblaje
- Sensores IR: Uno frontal, uno trasero. Montados en placa metálica en "L" con dos agujeros, fijada al chasis con tornillos. Centrados en chasis.
- Faro: Linterna LED 5V recortada (solo "cabeza"), cables soldados, pegada en centro parte superior. Agujero cerca para pasar cables, conector hembra 2 hilos soldado.
- Carcasa Raspberry Pi: Pi + cámara + tarjeta ≥4GB con Raspbian + conector cámara. Inserta tarjeta, conecta cámara con cuidado, cierra carcasa. Guías: instalar Raspbian, habilitar cámara.
- PCB componentes principales: Esquemático Fritzing adjunto (formato .fzz e imagen). Referencia para construir electrónica.
Pasos soldadura:
- a. Corta conectores PCB hembra: dos de 12 pines (microcontrolador), dos de 5 pines, dos de 3 pines (sensores IR), uno de 6 pines (H-bridge), uno para comunicación Pi (GND, TX, RX)
- b. Suelda conectores en cara posterior PCB
- c. Suelda conector KF301-2P
- d. Suelda transistor NPN y resistencia base
- e. Suelda regulador L7805CV 5V
- f. Suelda regulador 3.3V en línea TX Arduino→Pi
- g. Suelda pines macho a Arduino Pro Mini
- h. Suelda cables fino rojo(+), negro(-), blanco(señal) según esquemático Fritzing
- i. Suelda conector macho en protoboard para faro
- Conectores:
- a. Conector power bank 5V USB → Pi y Arduino: USB-A macho, micro USB macho, cables rojo/negro, termoretráctil, conector protoboard hembra-hembra. Corta conector hembra-hembra en dos para GND/VCC Arduino. USB-A alimenta Arduino y Pi vía micro USB.
- b. Conector batería LiPo a placa electrónica: XT-60 hembra, cables rojo/negro, termoretráctil, interruptor pequeño 10A. Negro directo XT-60 a KF301-2P. Rojo a través de interruptor.
- c. Conecta sensores IR a conectores hembra PCB con cables hembra-macho protoboard
- d. Conecta H-bridge a conector 6 pines hembra PCB con cables macho-hembra
- e. Conecta motores a bornes H-bridge
- f. Conecta alimentación principal H-bridge a KF301-2P en PCB
- Verificación: Antes de colocar Arduino en PCB, revisa todo con lupa y multímetro.
Paso 4: Código Arduino
¿Por qué capa intermedia Arduino y no conectar Pi directo a electrónica?
- Modular: reutilizas robot Arduino en otro proyecto sin Pi
- Seguridad: reemplazar Arduino Pro Mini ($3) vs Pi ($35)
- Eficiencia: Arduino no interrumpido por SO → PWM motores y polling sensores fiable
- Salvaguarda: si script Python falla, robot podría funcionar indefinidamente drenando baterías/incendio. En Arduino sketch la protección es más fiable (no depende de SO)
- Depuración: sistema desacoplado más fácil de debuggear
El sketch hace dos cosas:
- Recibe comandos motor/luz por serie y acciona motores o faro.
Ejemplos:
"M:-25:16;"= (-25 izquierda), (16 potencia) → motor izq 17%, der 36%, adelante"M:44:19;"= (44 derecha), (19 potencia) → motor izq 38%, der 5%, adelante"L:1;"= luz ON,"L:0"= luz OFF
- Polling sensores IR frontal/trasero y envía distancias por serie.
Librería necesaria: TextMotorCommandsInterpretter
Código principal en GitHub o copia abajo.
Sube código con adaptador FTDI. Para probar: conecta segunda línea serie y envía comandos motor/luz. Ej: módulo Bluetooth HC-05 + app Bluetooth en móvil → envía "L:1".
// source TextMotorCommandsInterpretter: "https://github.com/danionescu0/arduino/tree/master/libraries/TextMotorCommandsInterpretter"
#include <SoftwareSerial.h>
#include <TextMotorCommandsInterpretter.h>
const char MOTOR_COMMAND = 'M';
const char LIGHT_COMMAND = 'L';
const long maxDurationForMottorCommand = 300; // ms duración comando motor
const byte maxPwmValue = 230; // límite velocidad
const long transmitingInterval = 500; // ms entre transmisiones distancia
const int maxObstacleDetection = 1000; // lectura analógica max detección
const int minObstacleDetection = 500; // lectura analógica min detección
const byte FLASH_PIN = 3;
const byte RIGHT_MOTOR_PWM_PIN = 5;
const byte RIGHT_MOTOR_EN1_PIN = A4;
const byte RIGHT_MOTOR_EN2_PIN = A5;
const byte LEFT_MOTOR_PWM_PIN = 6;
const byte LEFT_MOTOR_EN1_PIN = A3;
const byte LEFT_MOTOR_EN2_PIN = A2;
const byte FRONT_DISTANCE_SENSOR = A0;
const byte BACK_DISTANCE_SENSOR = A1;
SoftwareSerial masterComm(11, 10); // RX, TX
TextMotorCommandsInterpretter motorCommandsInterpretter(-50, 50, -50, 50);
String currentCommand;
long lastCheckedTime;
long lastTransmitTime;
boolean inMotion = false;
void setup() {
Serial.begin(9600);
masterComm.begin(9600);
masterComm.setTimeout(10);
pinMode(FLASH_PIN, OUTPUT);
pinMode(LEFT_MOTOR_PWM_PIN, OUTPUT);
pinMode(LEFT_MOTOR_EN1_PIN, OUTPUT);
pinMode(LEFT_MOTOR_EN2_PIN, OUTPUT);
pinMode(RIGHT_MOTOR_PWM_PIN, OUTPUT);
pinMode(RIGHT_MOTOR_EN1_PIN, OUTPUT);
pinMode(RIGHT_MOTOR_EN2_PIN, OUTPUT);
lastCheckedTime = millis();
lastTransmitTime = millis();
}
void loop() {
if (masterComm.available() > 0) {
currentCommand = masterComm.readString();
processCommand();
}
if (inMotion && millis() - lastCheckedTime > maxDurationForMottorCommand) {
stopMotors();
}
if (millis() - lastTransmitTime > transmitingInterval) {
lastTransmitTime = millis();
masterComm.print(getObstacleData());
Serial.print(analogRead(BACK_DISTANCE_SENSOR));
Serial.print("---");
Serial.println(getObstacleData());
}
}
String getObstacleData() {
int frontDistance = analogRead(FRONT_DISTANCE_SENSOR);
int backDistace = analogRead(BACK_DISTANCE_SENSOR);
frontDistance = map(frontDistance, maxObstacleDetection, minObstacleDetection, 0, 10);
backDistace = map(backDistace, maxObstacleDetection, minObstacleDetection, 0, 10);
return String("F=" + String(frontDistance) + ":B=" + String(backDistace) + ";");
}
void processCommand() {
switch (currentCommand.charAt(0)) {
case (MOTOR_COMMAND): steerCar(); break;
case (LIGHT_COMMAND): toggleLight(currentCommand.charAt(2)); break;
}
}
void steerCar() {
motorCommandsInterpretter.analizeText(currentCommand);
float percentLeftMotor = motorCommandsInterpretter.getPercentLeft();
float percentRightMotor = motorCommandsInterpretter.getPercentRight();
Serial.write("Left="); Serial.println(percentLeftMotor);
Serial.write("Right="); Serial.println(percentRightMotor);
setMotorsDirection(motorCommandsInterpretter.getDirection());
analogWrite(LEFT_MOTOR_PWM_PIN, percentLeftMotor * maxPwmValue);
analogWrite(RIGHT_MOTOR_PWM_PIN, percentRightMotor * maxPwmValue);
inMotion = true;
lastCheckedTime = millis();
}
void setMotorsDirection(boolean forward) {
if (forward) {
digitalWrite(LEFT_MOTOR_EN1_PIN, HIGH);
digitalWrite(LEFT_MOTOR_EN2_PIN, LOW);
digitalWrite(RIGHT_MOTOR_EN1_PIN, HIGH);
digitalWrite(RIGHT_MOTOR_EN2_PIN, LOW);
} else {
digitalWrite(LEFT_MOTOR_EN1_PIN, LOW);
digitalWrite(LEFT_MOTOR_EN2_PIN, HIGH);
digitalWrite(RIGHT_MOTOR_EN1_PIN, LOW);
digitalWrite(RIGHT_MOTOR_EN2_PIN, HIGH);
}
}
void stopMotors() {
Serial.println("Stopping motors");
analogWrite(LEFT_MOTOR_PWM_PIN, 0);
analogWrite(RIGHT_MOTOR_PWM_PIN, 0);
inMotion = false;
}
void toggleLight(char command) {
Serial.println("Toggle light");
if (command == '1') digitalWrite(FLASH_PIN, HIGH);
else digitalWrite(FLASH_PIN, LOW);
}
Paso 5: Instalar y configurar proyecto Raspberry Pi y dependencias
Funcionamiento:

- a. App Android muestra streaming uv4l en WebView. uv4l en Pi captura cámara y streamea. Herramienta potente.
- b. Controles app Android → comandos motores/luz → servidor MQTT
- c. Servidor Python en contenedor Docker en Pi escucha MQTT y pasa comandos por serie a Arduino. Arduino controla motores/luces.
- d. Arduino mide distancias frontal/trasera y envía datos por serie a Python → MQTT → app Android muestra al usuario.
Requisitos previos: Raspbian instalado y configurado, cámara conectada y habilitada, SSH configurado. Guías: instalar Raspbian, cámara, SSH.
Para control fuera de WiFi local: port forwarding en router (puertos 9090 uv4l y 1883 mosquitto). Busca "port forwarding tu_modelo_router".
IP local Pi: ifconfig → busca wlan0 inet addr (ej. 192.168.0.102).
Prerrequisitos
- Instala git:
sudo apt-get install git - Clona repo en home:
git clone https://github.com/danionescu0/robot-camera-platform.git(ubicación importante: docker-compose.yml usa /home/pi/robot-camera-platform:/root/debug) - Desactiva consola serie Pi: guía
Instalar uv4l streaming
chmod +x uv4l/install.sh
chmod +x uv4l/start.sh
sh ./uv4l/install.sh
Si falla o más detalles: tutorial uv4l.
Configuración
- Edita
uv4l/start.sh: password, puerto, framerate, ancho, alto, rotación... - Edita
config.py: pon tu password del servidor mosquitto - Edita
docker-container/mosquitto/Dockerfile: cambia líneaRUN mosquitto_passwd -b /etc/mosquitto/pwfile user tu_password - Edita
config.py: puerto serie y baudrate (recomiendo mantener 9600; si cambias, edita también sketch Arduino)
Probar uv4l
- Inicia:
sh ./uv4l/start.sh - Test en navegador:
https://tu_ip:9090/stream - Para:
sudo pkill uv4l
Instalar Docker y Docker Compose
- Docker en Pi: blog Raspberry Pi
- Docker Compose: misma fuente
Auto-inicio servicios en reboot (systemctl)
- Copia archivos de carpeta
systemctla/etc/systemd/system/ - Habilita servicios:
sudo systemctl enable robot-camera.service sudo systemctl enable robot-camera-video.service - Reboot
- Opcional: ver estado:
sudo systemctl status robot-camera.service sudo systemctl status robot-camera-video.service
Paso 6: Configurar y compilar app Android
- Clona repo:
git clone https://github.com/danionescu0/android-robot-camera - Activa opciones desarrollador en Android: guía
- Instala Android Studio: developer.android.com
- Importa proyecto: guía
- Edita
./app/src/main/values/passwords.xml: configura credenciales MQTT y streaming.- Host MQTT: puerto 1883
- Host streaming: IP:9090
- Compila y ejecuta en dispositivo
Paso 7: Uso del robot y depuración

Uso de la app
Pantalla principal: streaming a la izquierda. Controles a la derecha: volante táctil (toca dirección deseada), botón faro abajo. Esquina sup. der.: texto "- Batt Connected".
- Primer guión: sin obstáculos. Si hay obstáculo frontal/trasero → flecha indicando dirección.
- "Batt" no implementado aún.
- "Connected" = MQTT conectado, robot usable. "Disconnected" = no conectado.
Depuración en capas
1. Capa Arduino:
- Conecta FTDI a segunda línea serie (RX pin 11, TX pin 10) → envía comandos motor/luz → verifica respuesta
- Revisa conexiones: si motores giran al revés, invierte cables. Si uno solo al revés, invierte sus cables
- Verifica conexión Arduino-H-bridge: guía SparkFun
2. Capa Raspberry Pi:
- Verifica contenedores Docker corriendo (mosquitto y python-server):
docker ps - Verifica puertos 9090 (streaming) y 1883 (mosquitto):
netstat -nltp - Verifica puerto serie existe y es correcto en
config.py:ls -l /dev/ttyS0 - Para Docker y prueba serie manual:
sudo systemctl start robot-camera.service && picocom -b 9600 /dev/ttyS0→ envía comandos motor/luz - Verifica consola serie desactivada en Pi
- Verifica streaming y MQTT accesibles desde exterior (cliente mosquitto + navegador)
3. Capa App Android:
- Verifica modo debug teléfono
- Verifica passwords.xml correcto
- Verifica streaming/MQTT accesibles desde exterior
- Mira esquina sup. der. app: ¿dice "Connected"?
- Usa debugger Android Studio para errores
Paso 8: Otros casos de uso y extensión del código
Otro caso: Robot seguidor de objetos. Sigue objeto de color/tamaño umbral específicos. Ver video arriba.
Pistas (fuera de alcance de este tutorial):
- Instala dependencias:
sudo pip3 install -r /home/pi/robot-camera-platform/navigation/requirements.txt(lento). Requiere Python 3.x. - En
navigation/config_navigation.py:
HSV = tono/saturación/valor. Rango inferior/superior para detección color. Busca "HSV color threshold detector" visual. Umbral tamaño = radio min/max (porcentaje ancho) para considerar detección.hsv_bounds = ((24, 86, 6), (77, 255, 255)) object_size_threshold = (10, 100) - Instala/configura VNC: guía
- Ejecuta script seguimiento en terminal VNC (con vídeo):
O sin vídeo:python3 object_tracking.py colored-object --show-videopython3 object_tracking.py colored-object
La gran ventaja de esta plataforma es versatilidad, adaptable a:
- Seguimiento de persona por reconocimiento facial
- Patrullaje y reporte de movimiento
- Sustituir WiFi por módem 3G → control externo, exploración zonas peligrosas
Proyecto complejo, asumo habrá errores. Pregunta en comentarios. Si te gusta, suscríbete a mi canal YouTube para más.
Código
Aplicación Android
Repositorio principal (Arduino, Python)
Esquemáticos
sketch_nWf7cZeUWL.fzz (Fritzing)
Repositorio principal
https://github.com/danionescu0/robot-camera-platform
Aplicación Android
https://github.com/danionescu0/android-robot-camera
Proceso de manufactura
- La evolución y diseño de las cámaras modernas
- Objetivos de cámara: diseño, historia e innovaciones futuras
- MrRobot: Robot Rapiro controlado por móvil Ubuntu con voz, tacto e interacción por movimiento
- Roomberry: Robot de Vigilancia con Roomba y Raspberry Pi Zero W
- Controlador de Slider Motorizado para Cámara con Bluetooth y Arduino para Tomas Cinematográficas Suaves
- Pantalla LED Interactiva con Giroscopio, Anillo NeoPixel y Arduino
- Mando universal Android con Arduino, 1Sheeld y control IR
- Mando USB para juegos DIY con Arduino – Construye tu propio gamepad de alto rendimiento
- Pixie: Reloj de pulsera NeoPixel basado en Arduino – Elegante reloj LED DIY
- Dominando reconocimiento y síntesis de voz en Arduino Due
- Controlador Inalámbrico para Presentaciones con Arduino – Puntero PowerPoint Sin Cables