Cómo hacer un coche robot con Arduino y Bluetooth paso a paso
Coche (carro) robot Arduino paso a paso: materiales y coste, cableado L298N y HC-05, pilas 18650, código de marcha, control por móvil y soluciones a desvíos.
Hacer un coche con Arduino (o carro, como se dice en gran parte de Latinoamérica) es una de las formas más divertidas de aprender electrónica y programación en un mismo proyecto. Con dos motorreductores, un controlador de motores L298N, dos pilas 18650, un módulo Bluetooth HC-05 y un Arduino Uno puedes construir en un fin de semana un coche robot que manejas desde el móvil. Por el camino verás en primera persona por qué los motores no se pueden conectar directamente al Arduino, por qué la elección de la batería es tan importante y cómo unas pocas líneas de código mueven un vehículo real.
En esta guía construimos juntos un coche robot 2WD (dos motores) de principio a fin: lista de materiales y costes, montaje del chasis, tablas de conexiones, código para avanzar, retroceder y girar, y control por Bluetooth desde el móvil. Los dos problemas que más atascan a los principiantes, que el coche no vaya recto y que el Arduino se reinicie al arrancar los motores, tienen cada uno su propia sección con soluciones concretas. En las últimas secciones verás cómo manejar el mismo coche con un ESP32 o una Raspberry Pi Pico y cómo convertirlo en un robot que esquiva obstáculos o sigue líneas.




¿Cómo funciona un coche robot con Arduino?
Un coche robot se divide en cuatro partes. El Arduino es el cerebro: lee la orden que llega del móvil y decide qué motor gira, en qué sentido y a qué velocidad. El controlador L298N es el músculo: convierte las débiles señales de 5 V del Arduino en la corriente alta que necesitan los motores. Los motorreductores hacen girar las ruedas y el paquete de baterías alimenta todo. Estos coches no tienen dirección; giran haciendo que las dos ruedas vayan a distinta velocidad o en sentidos opuestos. Esto se llama tracción diferencial: si la rueda izquierda gira hacia delante y la derecha hacia atrás, el coche gira a la derecha sobre sí mismo. Una pequeña rueda loca delante o detrás mantiene el equilibrio del chasis.

| Característica | Motor TT amarillo (1:48) |
|---|---|
| Tensión de trabajo | 3–6 V |
| Relación de reducción | 1:48 (engranajes de plástico) |
| Velocidad sin carga | Unas 90–120 RPM a 3 V y 200–250 RPM a 6 V |
| Corriente sin carga | Unos 150–160 mA |
| Corriente de bloqueo | Unos 1,1–1,5 A |
| Diámetro de rueda (en kits) | 65 mm |
| Velocidad del coche a 6 V | Unos 0,7 m/s (π × 0,065 m × 200 / 60) |
La fila más importante de la tabla es la corriente de bloqueo: cuando una rueda empuja contra un obstáculo o el coche arranca, cada motor consume durante un instante más de 1 amperio. Un pin de Arduino, en cambio, da como mucho 20–40 mA, por eso los motores siempre se conectan a través de un controlador. Al hacer este trabajo el L298N pierde unos 1,5–2,5 V; con un paquete de 7,4 V a los motores les llegan 5–6 V, justo el rango ideal de los motores TT. Explicamos el funcionamiento interno del controlador y el puente H en detalle en Control de motor DC con el L298N.
Lista de materiales
| Pieza | Cantidad | Nota |
|---|---|---|
| Kit de chasis acrílico 2WD para coche robot | 1 | Suele incluir 2 motores TT, 2 ruedas, rueda loca, interruptor, soportes de motor y tornillos |
| Arduino Uno R3 (vale un clon) + cable USB | 1 | También sirve un Nano; los números de pin son los mismos |
| Módulo controlador de motores L298N | 1 | 2 A por canal; controla dos motores por separado |
| Módulo Bluetooth HC-05 o HC-06 | 1 | Para comunicarse con un móvil Android |
| Pila de litio 18650 | 2 | Celdas de marca capaces de dar al menos 5 A |
| Portapilas 18650 doble (en serie) | 1 | Conecta las dos celdas en serie y da 7,4 V |
| Cargador de 18650 | 1 | Un cargador que cargue cada celda por separado |
| Cables jumper (macho-hembra y hembra-hembra) | 20+ | Entre el Arduino, el L298N y el HC-05 |
| Resistencias de 1 kΩ y 2 kΩ | 1 + 1 | Divisor de tensión para la entrada RXD del HC-05 |
| Condensador cerámico de 100 nF | 2–4 | En los bornes del motor; reduce el ruido eléctrico |
| Condensador electrolítico de 470–1000 µF (16 V o más) | 1 | Recomendado; en la entrada de alimentación del L298N |
| Bridas, cinta de doble cara, separadores M3 | Varios | Para fijar placas y cables |
La mayoría de los kits de chasis traen también un portapilas para 4 pilas AA; como verás enseguida, junto con el L298N se queda corto, por eso añadimos pilas 18650 a la lista. El HC-06 es el hermano más sencillo del HC-05, que solo funciona como esclavo, y es más que suficiente para manejar un coche desde el móvil. Los discos de plástico ranurados del kit son discos de encoder para un sensor de velocidad con el que más adelante podrás hacer que el coche vaya perfectamente recto; no los tires, guárdalos por ahora.
Coste: ¿en qué se va el presupuesto?
Los precios cambian constantemente según el vendedor y el tipo de cambio, así que no damos cifras; en su lugar te mostramos qué partidas se llevan el presupuesto y dónde puedes ahorrar. La regla general es: los módulos electrónicos (L298N, HC-05, resistencias) son baratos, y la mayor parte del presupuesto se va en la placa, el kit de chasis y, sobre todo, las pilas y el cargador. La batería es lo último en lo que conviene ahorrar: unas buenas celdas 18650 se recargan cientos de veces y sirven para todos tus proyectos de robots siguientes.
| Partida | Nivel de precio | Consejo de ahorro |
|---|---|---|
| Kit de chasis (con motores y ruedas) | Medio | Un kit suele salir más barato que comprar motores, ruedas y rueda loca por separado |
| Arduino Uno | Medio (clon) – alto (original) | Para aprender basta un clon; también puedes reutilizar el Uno o Nano que ya tengas |
| Controlador L298N | Bajo | Un módulo controla dos motores; también basta uno para 4WD |
| HC-05 / HC-06 | Bajo – medio | Si solo vas a manejarlo con el móvil, un HC-06 es suficiente |
| 2 pilas 18650 + cargador | La partida más cara | Las celdas muy baratas que dicen "9900 mAh" suelen ser falsas; no ahorres aquí |
| Cables, resistencias, condensadores, tornillos | Bajo | Casi todo viene ya en los kits de inicio |
¿2WD o 4WD?
| Característica | 2WD (2 motores + rueda loca) | 4WD (4 motores) |
|---|---|---|
| Giro | Gira sobre sí mismo con facilidad y de forma cerrada | Gira derrapando las ruedas de lado (skid steer); le cuesta sobre alfombra |
| Consumo | Unos 0,3–0,6 A en marcha | Aproximadamente el doble |
| Autonomía | Mayor | Menor |
| Terreno irregular | La rueda loca puede engancharse en los bordes | Mejor agarre |
| Ir recto | La rueda loca puede desviar el coche al girar sobre su eje | Más estable |
| Conexión al L298N | Cada motor en su propio canal | Los dos motores de cada lado en paralelo en un canal |
| Ideal para | Primer coche, robot seguidor de línea | Exteriores, cargas más pesadas |
Para tu primer coche recomendamos 2WD: es más barato, consume menos, gira sobre sí mismo con facilidad y encaja mejor con proyectos posteriores como un robot seguidor de línea. Si montas un 4WD, conecta en paralelo los dos motores de cada lado a los mismos bornes OUT y comprueba que ambos giran en el mismo sentido. Así, un canal del L298N lleva la corriente de dos motores; en marcha normal no hay problema, pero si las ruedas se bloquean se puede superar el límite de 2 A por canal y la protección térmica del controlador corta los motores.
Alimentación: ¿por qué dos pilas 18650?
La mayoría de los problemas de un coche robot vienen de una batería mal elegida. La fuente correcta debe cumplir dos condiciones a la vez: dejar suficiente tensión a los motores después de la pérdida del L298N y no hundirse cuando los motores piden varios amperios al arrancar. Dos celdas 18650 de litio en serie (2S) dan 8,4 V con carga completa y 7,4 V de media, y entregan varios amperios sin esfuerzo. El Arduino Uno recomienda 7–12 V en su entrada VIN, así que el mismo paquete puede alimentar tanto los motores como el Arduino. Con celdas de 2500 mAh, un coche 2WD que consume de media 0,8 A en marcha (motores y placas) funciona en teoría unas 3 horas; como nunca descargas la batería por completo, 2–2,5 horas es una cifra más realista. Para calcularlo con tus propios valores usa la herramienta Duración de la batería.

| Fuente de alimentación | Tensión | Capacidad de corriente | Para un coche robot |
|---|---|---|---|
| Pila de 9 V | 9 V | Muy baja | No sirve; la causa más común de reinicios |
| 4 pilas AA alcalinas | 6 V (cae rápido con carga) | Media | Floja; tras el L298N a los motores les llegan unos 4 V |
| 4 pilas AA NiMH (recargables) | 4,8 V | Buena | Tensión insuficiente con el L298N |
| 2 pilas 18650 de litio (2S) | 7,4 V (8,4 V cargadas) | Alta (varios amperios) | La mejor opción |
| 3 pilas 18650 de litio (3S) | 11,1 V (12,6 V cargadas) | Alta | Demasiado para motores TT; supera el límite de 12 V del jumper de 5V |
| Batería externa USB (powerbank) | 5 V | Buena | Solo para alimentar el Arduino por separado |
En lugar de adivinar cuánta carga queda, puedes medirla. Conecta el positivo de la batería (después del interruptor) a A0 mediante un divisor de tensión de dos resistencias de 10 kΩ: un paquete de 8,4 V aparece en A0 como 4,2 V, por debajo del límite de lectura de 5 V del Arduino. El divisor solo consume unos 0,4 mA, así que no afecta a la autonomía.
1// Pil + (anahtardan sonra) → 10 kΩ → A0 → 10 kΩ → GND / battery + (after the switch) → 10 kΩ → A0 → 10 kΩ → GND
2const float DIVIDER = 2.0; // iki eşit direnç gerilimi yarıya böler / two equal resistors halve the voltage
3
4void setup() {
5 Serial.begin(9600);
6}
7
8void loop() {
9 float v = analogRead(A0) * 5.0 / 1023.0 * DIVIDER;
10 Serial.print(F("Pil / Battery: "));
11 Serial.print(v, 2);
12 Serial.println(F(" V"));
13 if (v < 6.6) Serial.println(F("Sarj et / Charge now")); // hücre başına 3,3 V / 3.3 V per cell
14 delay(1000);
15}Montaje paso a paso
- Retira el papel protector de las piezas acrílicas. Si los motores vienen sin cables, suelda dos cables a cada motor y refuerza las soldaduras con silicona caliente; un cable de motor que se rompe por la vibración es la avería más frecuente.
- Fija los motores en la parte inferior del chasis con los soportes acrílicos en forma de T y los tornillos M3 largos del kit. Los dos ejes deben quedar alineados y los terminales de los motores deben mirar hacia dentro.
- Si vas a usar los discos de encoder, colócalos ahora en el lado interior del eje del motor; con las ruedas puestas es complicado.
- Monta la rueda loca en el centro del otro extremo del chasis con separadores. Elige una altura que deje el chasis paralelo al suelo.
- Encaja las ruedas a fondo haciendo coincidir el eje en forma de D; una rueda floja hace que el coche se desvíe constantemente.
- Coloca el portapilas con cinta de doble cara o velcro de forma que su peso quede cerca del eje de las ruedas. Si casi todo el peso cae sobre la rueda loca, las ruedas motrices patinan.
- Monta el Arduino y el L298N en la plataforma superior con separadores de plástico. Debes poder llegar con facilidad al conector USB del Arduino y el disipador del L298N debe quedar al aire; vigila que los tornillos metálicos no toquen las soldaduras bajo las placas.
- Conecta el interruptor en serie con el cable positivo de la batería; así podrás encender y apagar el coche sin sacar las pilas.
- Trenza los dos cables de cada motor hasta el L298N, mantén todos los cables cortos y recógelos con bridas. Antes de poner las pilas, comprueba con un multímetro que no hay cortocircuito entre los bornes de la batería.
Esquema de conexiones
Piensa en el cableado en dos partes: la parte de potencia (batería, interruptor, L298N, motores) y la de señal (los cables finos que van del Arduino al L298N y al HC-05). Quita los pequeños jumpers de los pines ENA y ENB del L298N; conectaremos esos pines a las salidas PWM del Arduino para ajustar la velocidad por código. El jumper de 5V del L298N, en cambio, se queda puesto: como el paquete está por debajo de 12 V, el propio regulador de la placa alimenta la lógica del controlador.

| Borne del L298N | Conexión |
|---|---|
| OUT1, OUT2 | Motor izquierdo (en 4WD, los dos motores izquierdos en paralelo) |
| OUT3, OUT4 | Motor derecho (en 4WD, los dos motores derechos en paralelo) |
| 12V | Positivo de la batería a través del interruptor |
| GND | Negativo de la batería y pin GND del Arduino (tierra común) |
| 5V | Libre con el Arduino Uno; alimenta la placa con el ESP32 y la Pico |
| Jumper de 5V | Se queda puesto (batería por debajo de 12 V) |
| Jumpers de ENA y ENB | Se quitan; los pines van a salidas PWM del Arduino |
| Conexión | Arduino Uno | ESP32 | Raspberry Pi Pico |
|---|---|---|---|
| L298N ENA (velocidad motor izquierdo) | D5 (PWM) | GPIO 25 | GP15 |
| L298N IN1 | D7 | GPIO 27 | GP14 |
| L298N IN2 | D8 | GPIO 33 | GP13 |
| L298N ENB (velocidad motor derecho) | D6 (PWM) | GPIO 26 | GP10 |
| L298N IN3 | D9 | GPIO 32 | GP12 |
| L298N IN4 | D4 | GPIO 4 | GP11 |
| HC-05 TXD | D10 (RX de SoftwareSerial) | No hace falta (Bluetooth integrado) | GP1 (RX de UART0) |
| HC-05 RXD | D11, a través de un divisor 1 kΩ / 2 kΩ | No hace falta | GP0 (TX de UART0), directo |
| HC-05 VCC | 5V | No hace falta | Salida 5V del L298N |
| Alimentación de la placa | VIN ← positivo de la batería tras el interruptor | 5V (VIN) ← salida 5V del L298N | VSYS ← salida 5V del L298N |
| GND | Común con GND del L298N y negativo de la batería | Común | Común |
Elegimos D5 y D6 como pines de velocidad a propósito. En el Uno, la librería Servo desactiva el PWM de los pines 9 y 10, y la función tone() el de los pines 3 y 11. Con ENA y ENB en 5 y 6, el control de velocidad sigue funcionando cuando más adelante añadas un servo o un zumbador. D2 y D3 quedan reservados para los encoders porque admiten interrupciones. Puedes ver la distribución de pines de tu placa en la herramienta Pinout.
Primer código: adelante, atrás, izquierda y derecha
Antes de pasar al Bluetooth, probemos los motores y el cableado por sí solos. El corazón del código es la función drive(izquierda, derecha): recibe la velocidad de cada motor por separado de -255 a 255; un valor positivo es hacia delante, uno negativo hacia atrás y cero es parar. Cómo se convierte el valor de velocidad en tensión lo explicamos en ¿Qué es PWM?. Antes de subir el código, pon el coche sobre una caja para que las ruedas giren en el aire; la espera de 3 segundos en setup() te da tiempo para ello.
1// Sol motor / left motor: ENA=5, IN1=7, IN2=8 — Sağ motor / right motor: ENB=6, IN3=9, IN4=4
2const int ENA = 5, IN1 = 7, IN2 = 8;
3const int ENB = 6, IN3 = 9, IN4 = 4;
4
5const int SPEED = 180; // temel hız 0-255 / base speed 0-255
6const int TRIM = 0; // % düzeltme: + sol, - sağ motoru yavaşlatır / % trim: + slows left, - slows right
7
8void drive(int left, int right) { // her biri -255 … 255 / each -255 … 255
9 if (TRIM > 0) left = left * (100 - TRIM) / 100;
10 if (TRIM < 0) right = right * (100 + TRIM) / 100;
11 digitalWrite(IN1, left > 0); digitalWrite(IN2, left < 0);
12 digitalWrite(IN3, right > 0); digitalWrite(IN4, right < 0);
13 analogWrite(ENA, abs(left));
14 analogWrite(ENB, abs(right));
15}
16
17void forward() { drive(SPEED, SPEED); }
18void backward() { drive(-SPEED, -SPEED); }
19void turnLeft() { drive(-SPEED, SPEED); } // yerinde sola / spin left in place
20void turnRight() { drive(SPEED, -SPEED); } // yerinde sağa / spin right in place
21void stopCar() { drive(0, 0); }
22
23void setup() {
24 int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
25 for (int p : pins) pinMode(p, OUTPUT);
26 stopCar();
27 delay(3000); // tekerlekleri kaldırmak için zaman / time to lift the wheels
28}
29
30void loop() {
31 forward(); delay(1500);
32 stopCar(); delay(500);
33 backward(); delay(1500);
34 stopCar(); delay(500);
35 turnLeft(); delay(600);
36 stopCar(); delay(500);
37 turnRight(); delay(600);
38 stopCar(); delay(2000);
39}| Movimiento | Motor izquierdo | Motor derecho | Código |
|---|---|---|---|
| Adelante | Adelante | Adelante | drive(180, 180) |
| Atrás | Atrás | Atrás | drive(-180, -180) |
| Giro a la izquierda sobre sí mismo | Atrás | Adelante | drive(-180, 180) |
| Giro a la derecha sobre sí mismo | Adelante | Atrás | drive(180, -180) |
| Curva abierta a la izquierda | Adelante lento | Adelante | drive(90, 180) |
| Parar | Parado | Parado | drive(0, 0) |
Con las ruedas en el aire, el coche debe ir hacia delante, hacia atrás, a la izquierda y a la derecha por turnos. Si una rueda gira al revés, no toques el código: intercambia los dos cables de ese motor en el borne OUT del L298N. Si giran al revés las dos ruedas, intercambia los cables de ambos motores. Si los motores zumban pero no giran, el valor de SPEED es demasiado bajo: la mayoría de los motores TT necesitan un PWM de al menos 80–120 para arrancar, y ese umbral sube a medida que se descarga la batería.
Control por Bluetooth desde el móvil (HC-05)
El HC-05 funciona como un cable serie inalámbrico entre el móvil y el Arduino: la app del móvil envía una letra, el Arduino la lee y hace el movimiento correspondiente. La mayoría de las apps de mando que encuentras en Play Store buscando "Bluetooth RC Car" o "Bluetooth RC Controller" envían F para avanzar, B para retroceder, L para la izquierda, R para la derecha y S para parar al soltar el botón; algunas usan además G, I, H y J para las diagonales y 0–9 y q para la velocidad. Los pines, los patrones del LED y los comandos AT del módulo están en Módulo Bluetooth HC-05.

- Mientras subes el código de abajo, el interruptor del coche puede quedarse apagado; el Arduino y el HC-05 se alimentan por USB. Si el LED del HC-05 parpadea rápido, el módulo está esperando conexión.
- Busca el HC-05 en los ajustes Bluetooth de tu móvil Android y emparéjalo con el PIN 1234 (o 0000 si falla).
- Abre la app de mando, concede los permisos de Bluetooth y dispositivos cercanos y elige el HC-05 en la lista. Al conectarse, el LED del módulo da dos destellos cortos cada dos segundos.
- Deja el Arduino conectado por USB, abre el Monitor Serie a 9600 baudios y pulsa los botones de la app. En pantalla aparece la letra que envía cada botón; si tu app envía otras letras, cambia las líneas case del código.
- Desconecta el cable USB, enciende el interruptor, pon el coche en el suelo y conduce.
1#include <SoftwareSerial.h>
2
3SoftwareSerial bt(10, 11); // RX, TX → HC-05 TXD, RXD (RXD bölücüyle / RXD via divider)
4
5const int ENA = 5, IN1 = 7, IN2 = 8; // sol motor / left motor
6const int ENB = 6, IN3 = 9, IN4 = 4; // sağ motor / right motor
7const int TRIM = 0; // % düzeltme / % trim
8const unsigned long TIMEOUT = 600; // ms; 0 = kapalı / 0 = disabled
9
10int speed = 200; // 0-255
11unsigned long lastCmd = 0;
12
13void drive(int left, int right) {
14 if (TRIM > 0) left = left * (100 - TRIM) / 100;
15 if (TRIM < 0) right = right * (100 + TRIM) / 100;
16 digitalWrite(IN1, left > 0); digitalWrite(IN2, left < 0);
17 digitalWrite(IN3, right > 0); digitalWrite(IN4, right < 0);
18 analogWrite(ENA, abs(left));
19 analogWrite(ENB, abs(right));
20}
21
22void setup() {
23 int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
24 for (int p : pins) pinMode(p, OUTPUT);
25 drive(0, 0);
26 Serial.begin(9600); // gelen harfleri görmek için / to see incoming letters
27 bt.begin(9600); // HC-05 veri modu hızı / HC-05 data mode baud rate
28}
29
30void loop() {
31 if (bt.available()) {
32 char c = bt.read();
33 Serial.println(c);
34 lastCmd = millis();
35 int half = speed / 2;
36 switch (c) {
37 case 'F': drive(speed, speed); break; // ileri / forward
38 case 'B': drive(-speed, -speed); break; // geri / backward
39 case 'L': drive(-speed, speed); break; // yerinde sola / spin left
40 case 'R': drive(speed, -speed); break; // yerinde sağa / spin right
41 case 'G': drive(half, speed); break; // ileri-sol / forward-left
42 case 'I': drive(speed, half); break; // ileri-sağ / forward-right
43 case 'H': drive(-half, -speed); break; // geri-sol / back-left
44 case 'J': drive(-speed, -half); break; // geri-sağ / back-right
45 case 'S': drive(0, 0); break; // dur / stop
46 case 'q': speed = 255; break; // tam hız / full speed
47 default:
48 if (c >= '0' && c <= '9') speed = map(c - '0', 0, 9, 100, 240); // hız kademesi / speed level
49 }
50 }
51 if (TIMEOUT > 0 && millis() - lastCmd > TIMEOUT) drive(0, 0); // komut yoksa dur / no command: stop
52}| Letra | Movimiento | Motor izquierdo / derecho |
|---|---|---|
| F | Adelante | +velocidad / +velocidad |
| B | Atrás | −velocidad / −velocidad |
| L | Giro a la izquierda | −velocidad / +velocidad |
| R | Giro a la derecha | +velocidad / −velocidad |
| G, I | Adelante-izquierda, adelante-derecha | Un lado a media velocidad |
| H, J | Atrás-izquierda, atrás-derecha | Un lado a media velocidad |
| S | Parar | 0 / 0 |
| 0–9, q | Nivel de velocidad | 0 → 100, 9 → 240, q → 255 |
El TIMEOUT del código es una medida de seguridad: estas apps envían la misma letra una y otra vez mientras mantienes pulsado el botón, así que si durante 600 ms no llega ninguna letra el código supone que se ha perdido la conexión y para el coche. De este modo el coche no sigue rumbo a la pared si el móvil queda fuera de alcance o la app se cierra. Si tu app envía la letra una sola vez por pulsación, el coche se parará a los 600 ms; en ese caso pon TIMEOUT a 0 para desactivar esta función. Además, no usamos delay() en ningún punto de loop(); las esperas largas retrasan las órdenes, y el porqué lo tienes en millis() frente a delay().
El coche no va recto: causas y solución
Si el coche se va desviando poco a poco hacia un lado aunque des a los dos motores el mismo PWM para "adelante", tranquilo: es el problema más habitual de los coches robot. Los motorreductores baratos giran a distinta velocidad incluso con la misma tensión; las diferencias de rozamiento en los engranajes, escobillas e imanes hacen que cada motor sea un poco distinto. Si a eso le sumas una rueda floja, una rueda loca que cambia de orientación o el peso cargado a un lado, desviarse 20–30 cm en 2 metros es lo normal. Corrige primero las causas mecánicas y luego compensa la diferencia restante por software.
| Síntoma | Causa probable | Solución |
|---|---|---|
| Siempre se desvía al mismo lado | Los motores giran a distinta velocidad | Corrección por software con TRIM, o encoders |
| Da un volantazo al arrancar y luego se endereza | Un motor arranca más tarde o la rueda loca cambia de orientación | Arranque suave; rueda de bola (ball caster) en lugar de rueda loca |
| El desvío cambia cada vez | Rueda floja, neumático que patina o soporte de motor torcido | Encaja la rueda a fondo en el eje y aprieta los tornillos |
| Gira sobre sí mismo en lugar de avanzar | Los cables de un motor están invertidos | Intercambia los cables de ese motor en el borne OUT |
| El desvío aumenta al bajar la batería | Con poca tensión crece la diferencia entre motores | Carga la batería; ajusta TRIM con la batería llena |
| Tira hacia un lado al acelerar | El peso está cargado a un lado | Coloca batería y placas en el centro, cerca del eje de las ruedas |
Una vez resueltos los problemas mecánicos, haz el ajuste fino por software. La constante TRIM del código frena en porcentaje el motor más rápido: un valor positivo frena el motor izquierdo y uno negativo el derecho. Ajústalo así:
- Carga las pilas por completo; calibrar con la batería llena da resultados coherentes.
- Pega en el suelo una tira de cinta recta de 2 metros y coloca el coche al principio, alineado con la cinta.
- En loop() del primer código deja solo forward() y una espera de 3 segundos, y deja que el coche avance.
- Si el coche se desvía a la derecha, el motor izquierdo es más rápido: sube TRIM en 3; si se desvía a la izquierda, bájalo en 3.
- Repite hasta que el desvío en 2 metros sea de pocos centímetros y copia el mismo valor de TRIM en el código Bluetooth.
- Calibra a la velocidad que más uses; la diferencia entre motores cambia un poco con la velocidad.
El siguiente nivel para ir perfectamente recto y medir distancias es el encoder. Colocas en los ejes los discos de 20 ranuras del kit y cuentas cada ranura con un sensor de velocidad de horquilla basado en el LM393. Conecta las salidas de los sensores a los pines D2 y D3, que admiten interrupciones, y compara los pulsos de las dos ruedas: si el lado izquierdo se adelanta, frenas un poco el motor izquierdo. Este sencillo control proporcional (P) mantiene el coche recto sin importar la carga de la batería ni el suelo. Una rueda de 65 mm recorre unos 20,4 cm por vuelta, así que cada pulso equivale a 1 cm aproximadamente. Explicamos cómo funcionan las interrupciones en Interrupciones en Arduino.
El Arduino se reinicia al arrancar los motores
Si el Arduino se reinicia o el HC-05 pierde la conexión (el LED vuelve a parpadear rápido) cuando el coche arranca, cambia de sentido o choca con algo, el problema está casi siempre en la alimentación. Al arrancar, dos motores juntos pueden pedir 2–3 A; una batería débil no puede darlos y su tensión cae de golpe durante un instante. El procesador del Uno se reinicia por seguridad cuando su alimentación baja de 2,7 V (brown-out). A eso se suman el ruido eléctrico de las escobillas de los motores y la caída de tensión en cables finos. Estas son las soluciones, empezando por la más eficaz:
- Cambia la batería: usa dos pilas 18650 cargadas en lugar de una pila de 9 V o pilas AA gastadas; aquí se acaban la mayoría de los problemas.
- Alimentación por el camino correcto: alimenta el Arduino desde la batería por VIN; no conectes la salida 5V del L298N a VIN.
- Condensadores en los motores: suelda un condensador cerámico de 100 nF entre los dos bornes de cada motor; elimina el ruido de las escobillas en su origen.
- Condensador de reserva: conecta un electrolítico de 470–1000 µF a los bornes 12V y GND del L298N (positivo a 12V). Cubre el pico breve de corriente del arranque.
- Arranque suave: en lugar de saltar a 255 de golpe, sube la velocidad por pasos como se muestra abajo; el pico de corriente se reduce.
- Para antes de invertir: pasar directamente de adelante a atrás lleva la corriente del motor al máximo; para 100–200 ms antes de cambiar de sentido.
- Cables de potencia gruesos y cortos: no uses cables jumper ni protoboard entre la batería y el L298N; usa cable de al menos 0,5 mm² y borneras.
- Alimentación separada: si el problema sigue, alimenta el Arduino con una powerbank y los motores con la batería, y une los dos GND.
1// Yumuşak kalkış: ilk koddaki drive() ile kullan / soft start: use with drive() from the first sketch
2void rampTo(int target) {
3 for (int s = 60; s < target; s += 20) {
4 drive(s, s);
5 delay(15); // yaklaşık 10 adımda tam hız / full speed in about 10 steps
6 }
7 drive(target, target);
8}
9
10// Kullanım: forward() yerine rampTo(SPEED) / usage: rampTo(SPEED) instead of forward()Coche robot con ESP32 y Raspberry Pi Pico
El ESP32 lleva Bluetooth clásico integrado, así que no necesitas el HC-05: la librería BluetoothSerial crea la misma conexión serie con el móvil y las apps de mando anteriores funcionan sin cambios. Las entradas del L298N consideran HIGH todo lo que supera unos 2,3 V, por lo que las señales de 3,3 V del ESP32 son suficientes. Alimenta la placa ESP32 desde la salida 5V del L298N a su pin 5V (VIN); no conectes la batería directamente a ese pin. Este código no compila en el ESP32-S3 ni en el ESP32-C3, porque solo tienen BLE.
1#include "BluetoothSerial.h"
2
3BluetoothSerial bt;
4
5const int ENA = 25, IN1 = 27, IN2 = 33; // sol motor / left motor
6const int ENB = 26, IN3 = 32, IN4 = 4; // sağ motor / right motor
7
8int speed = 200; // 0-255
9unsigned long lastCmd = 0;
10
11void drive(int left, int right) {
12 digitalWrite(IN1, left > 0); digitalWrite(IN2, left < 0);
13 digitalWrite(IN3, right > 0); digitalWrite(IN4, right < 0);
14 analogWrite(ENA, abs(left));
15 analogWrite(ENB, abs(right));
16}
17
18void setup() {
19 int pins[] = {ENA, IN1, IN2, ENB, IN3, IN4};
20 for (int p : pins) pinMode(p, OUTPUT);
21 drive(0, 0);
22 bt.begin("BlueGrays-Car"); // telefonda görünecek ad / name shown on the phone
23}
24
25void loop() {
26 if (bt.available()) {
27 char c = bt.read();
28 lastCmd = millis();
29 switch (c) {
30 case 'F': drive(speed, speed); break; // ileri / forward
31 case 'B': drive(-speed, -speed); break; // geri / backward
32 case 'L': drive(-speed, speed); break; // yerinde sola / spin left
33 case 'R': drive(speed, -speed); break; // yerinde sağa / spin right
34 case 'S': drive(0, 0); break; // dur / stop
35 case 'q': speed = 255; break; // tam hız / full speed
36 default:
37 if (c >= '0' && c <= '9') speed = map(c - '0', 0, 9, 100, 240);
38 }
39 }
40 if (millis() - lastCmd > 600) drive(0, 0); // komut yoksa dur / no command: stop
41}La Raspberry Pi Pico estándar no tiene Bluetooth, así que conectas el HC-05 a los pines de UART0. Como la Pico trabaja a 3,3 V, esta vez no hace falta divisor de tensión. Alimenta la Pico por el pin VSYS y el HC-05 directamente desde la salida 5V del L298N; funcionando con batería y sin USB, el pin VBUS no tiene tensión. En el código de la Pico la velocidad se indica en porcentaje de -100 a 100:
1from machine import Pin, PWM, UART
2import time
3
4bt = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1)) # GP0 → HC-05 RXD, GP1 ← HC-05 TXD
5
6ena = PWM(Pin(15)); ena.freq(1000) # sol motor hızı / left motor speed
7enb = PWM(Pin(10)); enb.freq(1000) # sağ motor hızı / right motor speed
8in1, in2 = Pin(14, Pin.OUT), Pin(13, Pin.OUT)
9in3, in4 = Pin(12, Pin.OUT), Pin(11, Pin.OUT)
10
11def drive(left, right): # -100 … 100 (%)
12 in1.value(left > 0); in2.value(left < 0)
13 in3.value(right > 0); in4.value(right < 0)
14 ena.duty_u16(int(abs(left) * 655))
15 enb.duty_u16(int(abs(right) * 655))
16
17speed = 80
18last = time.ticks_ms()
19drive(0, 0)
20
21while True:
22 if bt.any():
23 c = bt.read(1)
24 last = time.ticks_ms()
25 if c == b'F': drive(speed, speed) # ileri / forward
26 elif c == b'B': drive(-speed, -speed) # geri / backward
27 elif c == b'L': drive(-speed, speed) # yerinde sola / spin left
28 elif c == b'R': drive(speed, -speed) # yerinde sağa / spin right
29 elif c == b'S': drive(0, 0) # dur / stop
30 elif c == b'q': speed = 100 # tam hız / full speed
31 elif c and 48 <= c[0] <= 57: # '0'…'9' hız kademesi / speed level
32 speed = 40 + (c[0] - 48) * 6
33 if time.ticks_diff(time.ticks_ms(), last) > 600:
34 drive(0, 0) # komut yoksa dur / no command: stopSiguientes pasos: mejora tu coche
- Robot que esquiva obstáculos: añade delante un sensor de distancia HC-SR04 y un servomotor que lo gire a izquierda y derecha; los detalles en la guía Robot que esquiva obstáculos.
- Robot seguidor de línea: coloca 2–3 sensores infrarrojos TCRT5000 bajo la parte delantera y sigue una línea negra en el suelo; consulta Robot seguidor de línea.
- Mando con joystick: crea un mando de verdad, sin móvil, con un segundo Arduino, un módulo joystick y un nRF24L01.
- Mando infrarrojo: conduce con los botones del mando de la tele; asigna los códigos de Receptor IR y mando a distancia a las órdenes de marcha.
- Conducción por Wi-Fi: haz que un ESP32 sirva una página de mando que se abra en el navegador del móvil; la guía Servidor web ESP32 y WebSocket explica la base.
- Encoders y distancia: con sensores de velocidad haz que el coche avance exactamente 1 metro y gire justo 90 grados; es la base de los robots que resuelven laberintos.
- Brazo robótico: monta sobre el coche un pequeño brazo robótico con servos para transportar objetos.



Errores frecuentes y soluciones
- No gira ningún motor: los GND no son comunes, el interruptor está apagado, se quitaron los jumpers de ENA y ENB pero no se conectaron los pines, o la batería está descargada.
- El LED del L298N está encendido pero los motores solo zumban: el PWM está por debajo del umbral de arranque o la tensión de la batería es baja; sube la velocidad y carga la batería.
- El código no se sube: puede que estén mal elegidos el puerto o la placa; si conectaste el HC-05 a los pines 0 y 1, desconéctalo al subir. Otras causas en No se puede subir el código a Arduino.
- El móvil ve el HC-05 pero no se conecta: el módulo está conectado a otro móvil, la app no tiene el permiso de "dispositivos cercanos" o el PIN de emparejamiento es incorrecto.
- El coche responde tarde: hay un delay() en loop() o se imprime demasiado en el Monitor Serie; haz las esperas con millis().
- El disipador del L298N se calienta mucho: las ruedas están frenadas o, en un 4WD, la corriente por canal es excesiva; revisa el rozamiento mecánico.
- El coche da un tirón al encenderlo: al arrancar, los pines están indefinidos durante un instante; configúralos como salidas y llama a drive(0, 0) en las primeras líneas de setup().
Un coche robot con Arduino es un punto de partida genial que enseña control de motores, gestión de la alimentación, comunicación inalámbrica y depuración en un solo proyecto. Al terminarlo tendrás una base que se vuelve un poco más lista con cada sensor nuevo. En la app BlueGrays encontrarás paso a paso, con esquemas y código, los proyectos de coche controlado por Bluetooth con L298N, robot que esquiva obstáculos y detección de suelo blanco y negro con TCRT5000.
Preguntas frecuentes
¿Qué se necesita para hacer un coche con Arduino y cuánto cuesta?
Para un coche Bluetooth básico bastan un kit de chasis 2WD (2 motores TT, ruedas y rueda loca), un Arduino Uno, un controlador L298N, un módulo Bluetooth HC-05, dos pilas 18650 con portapilas y algunos cables jumper. Los precios dependen del vendedor; los módulos son baratos y la mayor parte del presupuesto se va en la placa, el kit de chasis y las pilas con su cargador. Si ya tienes un kit de inicio, el coste baja bastante.
¿Qué batería usar en un coche robot con Arduino?
La mejor opción son dos pilas 18650 de litio en serie: dan 7,4 V, dejan 5–6 V a los motores tras la pérdida de unos 2 V del L298N y entregan la corriente alta que hace falta al arrancar. Una pila de 9 V no da suficiente corriente y provoca reinicios, y con 4 pilas AA los motores van lentos con el L298N.
¿Por qué mi coche Arduino no va recto?
Los motorreductores baratos giran a distinta velocidad incluso con el mismo PWM, y las ruedas flojas, la rueda loca y un peso mal repartido aumentan el desvío. Corrige primero lo mecánico y después frena un poco el motor más rápido con un valor de corrección (trim) en el código. Para ir perfectamente recto necesitas encoders que midan e igualen la velocidad de las dos ruedas.
¿Por qué se reinicia el Arduino cuando arrancan los motores?
Los motores piden varios amperios al arrancar y la tensión de una batería débil cae de golpe; el procesador del Uno se reinicia cuando su alimentación baja. Usa pilas 18650 cargadas, añade condensadores de 100 nF en los bornes de los motores y uno de 470–1000 µF en la entrada del L298N, y sube la velocidad poco a poco. Si sigue, alimenta el Arduino con otra fuente y une los GND.
¿Un coche Bluetooth con HC-05 funciona con iPhone?
No. El HC-05 y el HC-06 usan el perfil de puerto serie del Bluetooth clásico, e iOS no permite que las apps normales abran ese tipo de conexión. Para controlarlo con un iPhone necesitas un módulo BLE como el HM-10 o un ESP32 con BLE; los móviles Android se conectan al HC-05 sin problemas.
¿Puedo usar un shield de motores L293D en lugar del L298N?
Sí. El shield de motores L293D se coloca encima del Arduino Uno y puede controlar cuatro motores DC, lo que simplifica el cableado en coches 4WD. Pero su corriente continua es de solo unos 0,6 A por canal, así que se queda corto antes que el L298N cuando los motores se bloquean, y el shield ocupa muchos pines. Si buscas algo más eficiente, los controladores con MOSFET como el TB6612FNG pierden mucha menos tensión.
Proyectos para hacer después de leer esto
Ver todos los proyectos
Coche controlado por Bluetooth con L298N
Proyecto de coche robot 4WD (cuatro motores, tracción en las cuatro ruedas) que se puede controlar desde el teléfono con Arduino y el módulo Bluetooth HC-05. Un total de cuatro ruedas se accionan simu

Robot para evitar obstáculos
¿Qué le parece construir un vehículo inteligente que encuentre su propio camino? El Robot Evitador de Obstáculos explora constantemente su entorno gracias al sensor ultrasónico que lleva delante. Cuan

Controlar un LED desde el móvil por Bluetooth
Proyecto de control inalámbrico que enciende y apaga LEDs con comandos enviados desde el teléfono con módulo Bluetooth HC-06. Enseña el intercambio de datos Bluetooth a través de la comunicación serie

TCRT5000 Detección de superficie blanca y negra
Proyecto que detecta el color del suelo con el sensor TCRT5000 y enciende el LED rojo en suelo negro y el LED verde en suelo blanco. Enseña la lógica de detección del umbral de color que constituye la

Medición de distancia con TCRT5000
Proyecto que mide la cantidad de luz reflejada por la superficie con el sensor infrarrojo TCRT5000 y la muestra como un valor analógico en la pantalla LCD I2C. Enseña los fundamentos de la detección ó

HC-SR04 Medición de distancia (pantalla en serie)
Sensor ultrasónico HC-SR04 para medir distancias y mostrar el resultado en cm en el monitor serie. Enseña el principio del cálculo de distancias con ondas sonoras.

Sensor de aparcamiento con HC-SR04
Proyecto de sensor de aparcamiento con sensor HC-SR04 que aumenta la frecuencia del pitido del zumbador a medida que se acerca el objeto y avisa con un LED. Enseña lógica de retroalimentación proporci

Uso del servomotor
Proyecto de uso básico que posiciona el servomotor en ángulos de 0°, 90° y 180° en secuencia. Enseña la biblioteca de servomotores y la lógica de control de ángulos.

