Tutorial · Principiante · 1 hora
Controla un robot por Bluetooth con un módulo HC-05
Cablea un HC-05 a un Arduino, emparéjalo con tu teléfono y diseña un protocolo serie de comandos que mantenga el robot receptivo y seguro si cae el enlace.
Introducción
El HC-05 es la forma más barata de hacer un robot inalámbrico. Es un puente serie Bluetooth: lo que tu teléfono envía llega al puerto serie del Arduino como bytes ordinarios, y lo que el Arduino imprime vuelve al teléfono. Nada en tu programa tiene que saber que Bluetooth existe.
Esa simplicidad es el atractivo, y también es la trampa. Un enlace de radio no es un cable —se cae, tiene retardo y se desconecta mientras tu robot sigue conduciendo. La mayor parte de este tutorial trata de esa diferencia.
Cableado, y el error que casi todo el mundo comete
El módulo HC-05 maneja su lógica a 3,3 V, aunque la placa de adaptación acepta 5 V en VCC. El pin RX no tolera 5 V.
| HC-05 | Arduino Uno / Nano | Notas |
|---|---|---|
VCC |
5V |
El regulador de la placa se encarga de esto |
GND |
GND |
Tierra común con todo lo demás |
TXD |
D10 (RX por software) |
La salida de 3,3 V se lee bien como HIGH lógico en una entrada de 5 V |
RXD |
D11 (TX por software) a través de un divisor |
5 V directos lo dañarán con el tiempo |
EN / KEY |
D9 (opcional) |
Pon en HIGH al encender para entrar en modo de comandos AT |
Baja la línea de transmisión de 5 V del Arduino a 3,3 V con un divisor de dos resistencias —2 kΩ del pin del Arduino al RXD del HC-05, y 3,3 kΩ de esa unión a tierra. Cuesta dos componentes y evita un fallo genuinamente enloquecedor de diagnosticar, porque un módulo dañado así a menudo sigue funcionando a medias: se empareja, transmite e ignora o corrompe en silencio lo que le envías.
Usa SoftwareSerial, no los pines 0 y 1. El puerto serie hardware se comparte con el USB, así que un módulo cableado ahí lucha con el monitor serie y bloquea las subidas.
#include <SoftwareSerial.h>
SoftwareSerial bt(10, 11); // RX, TX
void setup() {
Serial.begin(115200); // USB, for debugging
bt.begin(9600); // HC-05 default baud
}
Emparejamiento
Alimenta el robot, y el LED del módulo parpadea rápido —eso es «esperando emparejar». En tu teléfono, empareja con HC-05 usando el código 1234 o 0000.
Emparejar no es conectar. El enlace solo se abre cuando una app del teléfono abre realmente el puerto serie. Cualquier terminal serie Bluetooth sirve para empezar; el LED del módulo pasa a un doble parpadeo una vez que la conexión está activa.
Diseñar el protocolo de comandos
El primer protocolo obvio es un carácter por comando, y funciona unos diez minutos:
if (bt.available()) {
char c = bt.read();
if (c == 'F') forward();
else if (c == 'B') back();
else if (c == 'S') stop();
}
Dos cosas salen mal con él.
No tiene velocidad. Cada comando es a todo gas, así que el robot o está parado o embiste. Envía un valor con el comando en su lugar —una letra y un número, terminados en nueva línea, que es trivial de analizar y trivial de escribir a mano mientras depuras:
// "F180\n" — forward at 180 of 255
char buffer[16];
if (bt.available()) {
int n = bt.readBytesUntil('\n', buffer, sizeof(buffer) - 1);
buffer[n] = '\0';
char cmd = buffer[0];
int value = atoi(buffer + 1);
...
}
Supone que el mensaje llega entero. Que bt.available() pase a no cero significa que algunos bytes están aquí, no todos. Leer un carácter por vuelta y actuar de inmediato actuará sobre medio comando. Leer hasta la nueva línea es lo que hace fiable el análisis.
El fallo que importa: perder el enlace
Un robot con cable se detiene cuando sueltas. Un robot inalámbrico sigue haciendo lo último que le dijiste —lo que, si lo último fue «adelante a toda velocidad» y acabas de salir del alcance, es un robot yendo bajo el sofá a toda velocidad.
Todo robot inalámbrico necesita un timeout de hombre muerto. La regla es simple: si no ha llegado ningún comando recientemente, detente.
unsigned long lastCommandAt = 0;
const unsigned long TIMEOUT_MS = 500;
void loop() {
if (readCommand()) lastCommandAt = millis();
// Nothing heard recently? Assume the link is gone.
if (millis() - lastCommandAt > TIMEOUT_MS) stop();
}
Para que esto ayude, el controlador tiene que seguir hablando. Haz que el teléfono envíe el comando actual repetidamente —cada 100 ms o así mientras se mantiene un botón— en lugar de una vez al pulsar y una vez al soltar. Entonces «botón soltado» y «teléfono fuera de alcance» producen el mismo resultado seguro, y nunca dependes de un mensaje de soltado que quizá nunca llegue.
Usa millis() para esto, nunca delay(). Un delay(200) en el bucle son 200 ms durante los que no se lee ningún comando, no se comprueba el timeout y el robot está sordo.
Modo de comandos AT
Para renombrar el módulo o cambiar su velocidad en baudios, mantén EN/KEY en HIGH al encender. El LED parpadea lento —aproximadamente una vez cada dos segundos— que es como sabes que estás en modo de comandos en lugar de modo de datos.
AT → OK
AT+NAME=MyRobot → OK
AT+PSWD="4821" → OK
AT+UART=38400,0,0
Los comandos deben enviarse a 38400 baudios en modo AT sin importar la velocidad en modo de datos, y la mayoría del firmware requiere retorno de carro y nueva línea. Si AT no devuelve nada, esa discordancia es casi siempre la causa.
Subir la velocidad de datos merece la pena si estás retransmitiendo telemetría, pero déjala en 9600 mientras afinas el protocolo —un enlace más rápido sobre todo hace los errores de encuadre más difíciles de ver.
Verifica antes de conducir
Tres comprobaciones, en este orden:
- Prueba de eco. Haz que el Arduino devuelva lo que reciba. Si una línea escrita vuelve intacta, el cableado y la velocidad están bien.
- Prueba de análisis. Imprime la letra de comando analizada y el valor. Confirma que
F180daFy180, noFy1. - Prueba de timeout. Envía un comando de avance, luego cierra la app o aléjate. El robot debe detenerse dentro de tu timeout. Si no lo hace, arréglalo antes de poner ruedas en el suelo.
Una vez que el enlace es fiable, el mismo protocolo de comandos encaja directo en un robot con autonomía: construye la capa inalámbrica en el proyecto de robot controlado por teléfono, o sube al ESP32, que sirve una página de control por Wi-Fi y no necesita ninguna app.
Explora el grafo
Forma parte de estos montajes
Proyectos y rutas de aprendizaje que incluyen este tutorial.
Lecturas adicionales