INFORMACIÓN
El UNIT Robot Escalador V1 es un robot móvil diseñado para trepar en pared y desplazarse en techo mediante un sistema de succión con turbina brushless. Combina 4 motorreductores N20 de 12V (100 RPM) con llantas de 34×7 mm para el movimiento, y una turbina de 40 mm (KV5500) + ESC de 40A para generar el agarre. El cerebro del robot es la UNIT Pulsar ESP32-C6, que permite controlarlo de forma inalámbrica desde el celular o la computadora.
Este kit está pensado para makers, estudiantes y entusiastas que quieren construir un robot escalador real, con electrónica robusta y lista para integrarse. La PCB incluye etapa de regulación de voltaje (SMD) y headers ya ensamblados, para que se enfoquen en el montaje mecánico, el cableado, la integración de módulos ya la programación del robot.
Este robot incluye:
| Material / Componente | Cantidad | Modelo / Especificación | Uso en el robot |
| PCB | 1 | Pre-ensamblada | Placa de control |
| Llanta para motorreductor N20 | 4 | 34 × 7 mm | Tracción (ruedas) |
| Motorreductor | 4 | GA12-N20 12V 100RPM | Movimiento |
| Soporte para motorreductor | 4 | Para N20 / N30 | Montaje de motores |
| Doble puente H | 1 | TB6612FNG | Control de motores DC |
| Driver ESC | 1 | 40A | Control motor brushless (turbina) |
| Turbina | 1 | 40 mm 1413-KV5500 | Succión/adhesión a pared/techo |
| Placa de desarrollo | 1 | UNIT Pulsar ESP32-C6 | Control y WiFi/WebSockets |
| Conector ZH 1.5 mm con cable | 4 | 28 AWG 2P | Cableado rápido |
| Tornillo milimétrico M3 | 6 | M3 × 6 mm + tuerca M3 | Ensamble mecánico |
| Tornillos milimétrico M2 | 2 | M2 × 10 mm (cabeza de queso) | Ensamble mecánico |
| Tuerca M2 | 2 | M2 milimétrica | Ensamble mecánico |
| Soporte impreso en PETG | 2 | Para driver 40A | Montaje del ESC/driver |
| Soporte impreso en PETG | 2 | Para turbina | Montaje de turbina |
ESPECIFICACIONES Y CARACTERÍSTICAS
- Tipo: Robot Escalador
- Modelo: UNIT Climbin Robot V1
- Marca: UNIT Electronics
- Voltaje de funcionamiento: 12V DC
- Corriente de operación: ~12A
- Escalado en pared y techo por succión con turbina
- Tracción 4 ruedas con motorreductores N20 12V 100RPM
- Control WiFi en tiempo real con WebSockets (respuesta rápida, sin “lag”)
- Interfaz web integrada (no necesitas app): botones para avanzar, girar y activar turbina
- Watchdog de seguridad: si se pierde la conexión o dejan de llegar comandos, el robot se detiene automáticamente
- Dimensiones:
- Placa PCB: 113mm x 83mm
- Robot armado: 122.2mm x 120.4mm x 61mm
- Empaque: 170mm x 120mm x 110mm
- Peso: 192g
Nota: No incluye fuente de alimentación ni batería, por lo que se deben adquirir por separado.
DOCUMENTACIÓN Y RECURSOS
TUTORIALES
INFORMACIÓN ADICIONAL
Recomendaciones y seguridad
- No tocar la turbina cuando esté en funcionamiento.
- Usa cables de potencia adecuados (por corriente alta).
- Prueba primero en piso, luego en inclinación, y al final en pared/techo.
- Asegúrate de que la superficie esté limpia y relativamente lisa para una buena succión.
Ensamble: ¿Qué viene listo y qué tienes que armar?
PCB (pre-ensamblada):
- Regulación de voltaje (componentes SMD)
- Conectores ZH1.5mm 2p para conexión de los motorreductores
- Headers Macho / Hembra para conectar la Pulsar ESP32 C6, Puente H y Driver de ESC 40A
- Conectores XT60

Ensambla y conecta:
- Suelda los cables a cada motor y conéctalos a la PCB en su conector correspondiente.
- Monta los motorreductores con sus soportes y tornillería..
- Ensambla la turbina con sus soportes impresos en PETG y tornillería.
- Monta el ESC de 40A en su soporte y fíjalo con tornillería.
- Realiza el cableado de potencia y señal: ESC / turbina / motores (verificando polaridad y firmeza).
- Solda los headers macho al TB6612FNG (puente H) y a la UNIT Pulsar ESP32-C6.
- Por último, conecta el TB6612FNG y la Pulsar a la PCB principal en sus headers hembra correspondientes.
⚠️ Alimentación ¡Importante!
Este robot NO incluye fuente ni batería. En uso puede llegar a consumir ~12A, por lo que necesitas una alimentación de alta corriente para que funcione de forma segura y estable.
Recomendado
- Fuente conmutada 12V 30A
- Par Cables XT60 12AWG 15cm
- Cable de silicona 14AWG (Negro / Rojo)
Opción con batería (LiPo)
Puedes usar una LiPo 3S (11.1V) de mínimo 500 mAh y 30C, pero considera dos puntos:
- Peso: mientras más pesada sea la batería, más difícil será que el robot escale pared y techo.
- Duración: al consumir ~12A, la batería se descargará rápido (la autonomía dependerá del uso de la turbina y el movimiento).
📋Pasos para programar la UNIT Pulsar ESP32-C6 en Arduino IDE (con el código del UNIT Robot Escalador)
1) Instala el soporte de tarjetas UNIT Electronics ESP32
-
Abre Arduino IDE → Archivo > Preferencias.
-
En “Gestor de URLs Adicionales de Tarjetas” pega esta URL:
https://raw.githubusercontent.com/UNIT-Electronics/Uelectronics-ESP32-Arduino-Package/main/package_Uelectronics_esp32_index.json
-
Da clic en OK.
-
Ve a Herramientas > Placa > Gestor de tarjetas…
-
Busca UNIT Electronics ESP32 y presiona Instalar.
2) Selecciona la placa y el puerto
-
Conecta la UNIT Pulsar por USB.
-
Ve a Herramientas > Placa y selecciona la UNIT Pulsar ESP32-C6 (o la opción equivalente que aparezca en el paquete).
-
Ve a Herramientas > Puerto y elige el puerto COM correspondiente.
3) Instala la librería WebSocketsServer
Para instalarla:
-
Ve a Programa > Incluir librería > Gestionar bibliotecas…
-
En el buscador escribe: WebSocketsServer
-
Instala la librería WebSockets (normalmente aparece como “WebSockets by Markus Sattler”).
Esta librería es clave porque permite el control en tiempo real del robot por WebSockets (puerto 81).
4) Instala la librería ESP32Servo.h
ESP32Servo.h
-
Programa > Incluir librería > Gestionar bibliotecas…
-
Busca ESP32Servo e instálala.
5) Carga el código en Arduino IDE
-
Crea un sketch nuevo y pega el código completo.
#include <WiFi.h> // WiFi en ESP32 #include <WebServer.h> // Servidor HTTP para la página #include <WebSocketsServer.h> // Servidor WebSocket para control en tiempo real #include <ESP32Servo.h> // Control del ESC (motor brushless) // ====================== // Definición de pines TB6612FNG // ====================== #define PWMA 5 // PWM Motor A (velocidad) -> HIGH = velocidad máxima #define AIN1 3 // Dirección Motor A #define AIN2 4 // Dirección Motor A #define PWMB 15 // PWM Motor B (velocidad) -> HIGH = velocidad máxima #define BIN1 20 // Dirección Motor B #define BIN2 21 // Dirección Motor B #define STBY 19 // Standby del driver (HIGH = habilitado) // ====================== // ESC (Electronic Speed Controller) // ====================== Servo ESC; int vel_min = 1000; // Pulso mínimo típico para ESC (µs) int vel_max = 1900; // Pulso máximo típico para ESC (µs) #define ESC_PIN 9 // Pin del ESC // ====================== // LED de prueba // ====================== #define LED_PIN 6 bool ledState = false; // ====================== // Servidor HTTP + WebSocket // ====================== WebServer server(80); WebSocketsServer webSocket(81); // WebSocket en puerto 81 // ====================== // WiFi SoftAP // ====================== const char* ssid = "UNIT ROBOT ESCALADOR"; const char* password = "12345678"; // ====================== // Watchdog de seguridad // ====================== bool motorsActive = false; // true si hay movimiento activo unsigned long lastCommandTime = 0; // último comando recibido const unsigned long WATCHDOG_TIMEOUT_MS = 700; // tiempo máx sin comandos (ms) // ====================== // Prototipos de funciones // ====================== void forwardMove(); void backwardMove(); void leftMove(); void rightMove(); void stopMotors(); void toggleLED(); void handleRoot(); void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length); // ====================== // Setup // ====================== void setup() { Serial.begin(115200); // Pines de motor pinMode(AIN1, OUTPUT); pinMode(AIN2, OUTPUT); pinMode(BIN1, OUTPUT); pinMode(BIN2, OUTPUT); pinMode(STBY, OUTPUT); pinMode(PWMA, OUTPUT); pinMode(PWMB, OUTPUT); pinMode(LED_PIN, OUTPUT); // Driver TB6612FNG activo digitalWrite(STBY, HIGH); // Velocidad máxima en ambos motores (PWM HIGH) digitalWrite(PWMA, HIGH); digitalWrite(PWMB, HIGH); // LED encendido al inicio digitalWrite(LED_PIN, HIGH); // ESC ESC.setPeriodHertz(50); ESC.attach(ESC_PIN, vel_min, vel_max); ESC.writeMicroseconds(vel_min); // apagado delay(5000); // tiempo de armado del ESC // Motores detenidos al inicio stopMotors(); lastCommandTime = millis(); // WiFi en modo AP WiFi.softAP(ssid, password); Serial.print("SoftAP configurado. IP: "); Serial.println(WiFi.softAPIP()); // Servidor HTTP (solo para servir la página) server.on("/", handleRoot); server.begin(); Serial.println("Servidor HTTP iniciado"); // Servidor WebSocket webSocket.begin(); webSocket.onEvent(webSocketEvent); Serial.println("Servidor WebSocket iniciado en puerto 81"); } // ====================== // Loop principal // ====================== void loop() { server.handleClient(); // Atiende peticiones HTTP (página) webSocket.loop(); // Atiende eventos WebSocket // Watchdog: si hay movimiento y no llegan comandos, se detiene if (motorsActive && (millis() - lastCommandTime > WATCHDOG_TIMEOUT_MS)) { Serial.println("Watchdog: sin comandos recientes, deteniendo motores"); stopMotors(); } } // ====================== // Funciones de movimiento // ====================== void backwardMove () { digitalWrite(AIN1, HIGH); digitalWrite(AIN2, LOW); digitalWrite(BIN1, HIGH); digitalWrite(BIN2, LOW); motorsActive = true; Serial.println("Retroceder"); } void forwardMove() { digitalWrite(AIN1, LOW); digitalWrite(AIN2, HIGH); digitalWrite(BIN1, LOW); digitalWrite(BIN2, HIGH); motorsActive = true; Serial.println("Avanzar"); } void leftMove() { digitalWrite(AIN1, LOW); digitalWrite(AIN2, HIGH); digitalWrite(BIN1, HIGH); digitalWrite(BIN2, LOW); motorsActive = true; Serial.println("Giro izquierda"); } void rightMove () { digitalWrite(AIN1, HIGH); digitalWrite(AIN2, LOW); digitalWrite(BIN1, LOW); digitalWrite(BIN2, HIGH); motorsActive = true; Serial.println("Giro derecha"); } void stopMotors() { digitalWrite(AIN1, LOW); digitalWrite(AIN2, LOW); digitalWrite(BIN1, LOW); digitalWrite(BIN2, LOW); motorsActive = false; Serial.println("Motores detenidos"); } // ====================== // LED + ESC // ====================== void toggleLED() { ledState = !ledState; if (ledState) { digitalWrite(LED_PIN, HIGH); ESC.writeMicroseconds(vel_max); // ESC motor ON } else { digitalWrite(LED_PIN, LOW); ESC.writeMicroseconds(vel_min); // ESC motor OFF } Serial.print("LED+ESC: "); Serial.println(ledState ? "ON" : "OFF"); } // ====================== // Manejador de eventos WebSocket // ====================== void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) { switch (type) { case WStype_CONNECTED: { IPAddress ip = webSocket.remoteIP(num); Serial.printf("WS Cliente [%u] conectado desde %sn", num, ip.toString().c_str()); // Por seguridad, al conectar un nuevo cliente, detenemos motores stopMotors(); break; } case WStype_DISCONNECTED: Serial.printf("WS Cliente [%u] desconectadon", num); // Si se desconecta el cliente, detenemos el carrito stopMotors(); break; case WStype_TEXT: { // Convertir payload en String seguro String cmd; cmd.reserve(length); for (size_t i = 0; i < length; i++) { cmd += (char)payload[i]; } // Actualizar tiempo del último comando lastCommandTime = millis(); Serial.print("WS cmd: "); Serial.println(cmd); if (cmd == "fwd") { forwardMove(); } else if (cmd == "back") { backwardMove(); } else if (cmd == "left") { leftMove(); } else if (cmd == "right") { rightMove(); } else if (cmd == "stop") { stopMotors(); } else if (cmd == "toggle-led") { toggleLED(); } break; } default: break; } } // ====================== // Página HTML de control (mismo estilo, ahora con WebSocket) // ====================== void handleRoot() { String html = R"rawliteral( <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="UTF-8"> <title>UNIT ROBOT ESCALADOR</title> <style> body { font-family: sans-serif; text-align: center; background-color: #f5f5f5; margin: 0; padding: 20px; } h1 { margin-bottom: 10px; } #status { margin-bottom: 20px; font-weight: bold; } button { width: 100px; height: 100px; font-size: 30px; margin: 5px; border: none; border-radius: 10px; background-color: #eb6f0f; color: white; } .center { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 80vh; } p { -webkit-user-select: none; -webkit-touch-callout: none; user-select: none; pointer-events: none; margin: 0; } </style> </head> <body> <div class="center"> <h1>UNIT ROBOT ESCALADOR</h1> <div id="status">Conectando</div> <div> <button ontouchstart="startMove('fwd')" ontouchend="stopMove()" onmousedown="startMove('fwd')" onmouseup="stopMove()" onmouseleave="stopMove()"> <p>▲</p> </button> </div> <div> <button ontouchstart="startMove('left')" ontouchend="stopMove()" onmousedown="startMove('left')" onmouseup="stopMove()" onmouseleave="stopMove()"> <p>◄</p> </button> <button onclick="sendOnce('toggle-led')"> <p>✇</p> </button> <button ontouchstart="startMove('right')" ontouchend="stopMove()" onmousedown="startMove('right')" onmouseup="stopMove()" onmouseleave="stopMove()"> <p>►</p> </button> </div> <div> <button ontouchstart="startMove('back')" ontouchend="stopMove()" onmousedown="startMove('back')" onmouseup="stopMove()" onmouseleave="stopMove()"> <p>▼</p> </button> </div> </div> <script> let socket = null; let commandInterval = null; function setStatus(text, color) { const el = document.getElementById('status'); el.textContent = text; el.style.color = color; } function initWebSocket() { // WebSocket en puerto 81 del mismo host const wsUrl = 'ws://' + window.location.hostname + ':81/'; socket = new WebSocket(wsUrl); socket.onopen = function() { setStatus('Conectado', 'green'); }; socket.onclose = function() { setStatus('Desconectado', 'red'); stopMoveLocal(); // Reintentamos conexión setTimeout(initWebSocket, 1000); }; socket.onerror = function() { setStatus('Error de conexión', 'red'); }; socket.onmessage = function(event) { // Si en el futuro quieres enviar info desde el ESP32, se procesa aquí console.log('WS mensaje:', event.data); }; } function sendRaw(cmd) { if (socket && socket.readyState === WebSocket.OPEN) { socket.send(cmd); } } // Comando único (toggle LED/ESC) function sendOnce(cmd) { sendRaw(cmd); } // Inicia movimiento continuo en una dirección (envía cmd cada 100 ms) function startMove(direction) { stopMoveLocal(); // limpia intervalos previos sendRaw(direction); commandInterval = setInterval(() => { sendRaw(direction); }, 100); } // Detiene el movimiento (envía "stop") function stopMove() { stopMoveLocal(); sendRaw('stop'); } function stopMoveLocal() { if (commandInterval) { clearInterval(commandInterval); commandInterval = null; } } // Asegurar que al soltar el dedo o mouse en cualquier parte se detenga window.addEventListener('mouseup', stopMove); window.addEventListener('touchend', stopMove); window.addEventListener('touchcancel', stopMove); // Iniciar WebSocket al cargar la página window.addEventListener('load', initWebSocket); </script> </body> </html> )rawliteral"; server.send(200, "text/html", html); } -
Verifica que el nombre de la placa esté correcto en Herramientas.
-
Da clic en ✔ Verificar para compilar.
6) Sube el programa a la UNIT Pulsar
-
Da clic en → Subir.
-
Si Arduino IDE te pide entrar en modo de carga, normalmente se hace con los botones BOOT/RESET (si aplica en tu versión).
-
Cuando termine, abre el Monitor Serial a 115200 baudios.
7) Confirma que el WiFi del robot se creó
En el Monitor Serial debe aparecer algo similar a:
-
“SoftAP configurado. IP: …”
-
“Servidor HTTP iniciado”
-
“Servidor WebSocket iniciado en puerto 81”
8) Prueba el control desde el celular o PC
-
Conéctate a la red WiFi: UNIT ROBOT ESCALADOR
Contraseña: 12345678 -
En el navegador abre:
http://192.168.4.1
-
Usa los botones:
-
Flechas: Mover el robot
-
✇: Encender / Apagar turbina (ESC) y LED
¿Cómo controlar el UNIT Robot Escalador?
Ya programado el robot el funcionamiento es el siguiente:
- Enciende el robot y espera a que la Pulsar inicie.
- Conéctate por WiFi a la red: “UNIT ROBOT ESCALADOR” (password: 12345678).
- Abre el navegador y entra a la IP del AP (normalmente): 192.168.4.1.
- Aparecerá la página de control con flechas:
- ▲/▼/◄/► = movimiento
- Botón ✇ = enciende/apaga turbina (ESC) y el LED de prueba
- Si se pierde la conexión, el sistema aplica freno automático por watchdog.










































































Valoraciones
No hay valoraciones aún.