Domina Lego Power Functions con Arduino y Control Bluetooth
Componentes y suministros
| Arduino UNO | 1 |
| Driver doble puente H L293D (Texas Instruments) | 1 |
| Protoboard (genérica) | 1 |
| Conector 9V a Jack barril | 1 |
| Cable extensible Lego Power Functions (Ref: 8886) | 3 |
| Módulo Bluetooth HC-05 | 1 |
Acerca del proyecto
¿Tienes un modelo Lego Power Functions con motores y servomotores? En este tutorial te muestro cómo controlarlo con Arduino y pocos componentes electrónicos. Explico circuitos y programación en detalle para principiantes. El modelo Lego lo construyes tú (si no tienes un hijo), yo no ayudo con eso.
También aprenderemos a usar MIT App Inventor para programar nuestra propia app de control remoto Android. ¡Pronto tendrás tu propio rover Lego Marte en el jardín!
Este es mi primer proyecto Arduino y mi hijo tiene un coche Lego Technic 9398 4X4 Crawler con Power Functions: un servomotor Lego para dirección y dos motores L para tracción. Me dejó usarlo (sin cortar cables). Aquí probamos el prototipo terminado:
Entendiendo el cableado Power Functions
Compra cables extensibles Lego Power Functions (ref 8886). Córtalos (en serio). Haremos cables "break-out" con brick Lego en un extremo y pines en el otro. Solda los pines. El cableado:

GND = tierra (terminal negativo de la batería). C1 y C2 invierten polaridad para cambiar dirección de motores/servos. TechnicRobot tiene un video explicativo detallado. (ADVERTENCIA: Lo haces bajo tu responsabilidad).
- Conector servo: suelda pines a los 4 cables. Usa enchufe gris claro.
- Cable alimentación (caja baterías a protoboard): solo +9V y GND, usa enchufe gris oscuro (macho).
- Cable motor: solo C1 y C2, enchufe gris claro.

Controlar motor Lego con chip L293D
Queremos control de velocidad variable (PWM) para motores DC y control de posición para servo. Arduino facilita PWM: analogWrite(pin, dutyCycle) (0-255). Pines PWM marcados con ~.
Pines Arduino: 5V, máx 30 mA. Motores Lego: 9V, >100 mA. Necesitamos un "dispositivo de conmutación" intermedio y poder invertir dirección: puente H. Usamos L293D, que integra dos puentes H. Conectamos los dos motores L en paralelo a un lado y el servo al otro. (Para control independiente de cada motor, necesitarías otro L293D). El servo también necesita GND y +9V Lego.
El chip aísla +9V Lego de +5V Arduino. Nunca los conectes juntos o dañarás algo. Pero une todas las tierras (GND) con los pines GND del L293D.

Pines Arduino usados:
- Motor: pin 9 (velocidad), pines 2 y 5 (dirección).
- Servo: pin 3 (posición), pines 6 y 8 (dirección izq/der).
Definimos constantes y variables globales:
// Pines motor
const int controlPin1A = 2;
const int controlPin2A = 5;
const int ENablePin = 9;
// Pines servo
const int controlPin3A = 6;
const int controlPin4A = 8;
const int servoENablePin = 3;
// Variables motor
int motorSpeed = 0; // 0..255
int motorDirection = 1; // 1=adelante, 0=atrás
// Variables servo
int steering = 0; // 0..255
int steeringDirection = 0; // 0=izq, 1=der
En setup() declaramos salidas y ponemos a LOW:
void setup() {
pinMode(controlPin1A, OUTPUT); pinMode(controlPin2A, OUTPUT); pinMode(ENablePin, OUTPUT);
pinMode(controlPin3A, OUTPUT); pinMode(controlPin4A, OUTPUT); pinMode(servoENablePin, OUTPUT);
digitalWrite(ENablePin, LOW); digitalWrite(servoENablePin, LOW);
}
Lógica L293D para dirección:
- EN1,2 1A 2A: High High Low → Motor izquierda (adelante); High Low High → Motor derecha (atrás).
- EN3,4 3A 4A: High High Low → Servo izquierda; High Low High → Servo derecha.
Subrutina para actualizar motores/servo:
void SetMotorControl() {
if (motorDirection == 1) { digitalWrite(controlPin1A, HIGH); digitalWrite(controlPin2A, LOW); }
else { digitalWrite(controlPin1A, LOW); digitalWrite(controlPin2A, HIGH); }
analogWrite(ENablePin, motorSpeed);
if (steeringDirection == 0) { digitalWrite(controlPin3A, HIGH); digitalWrite(controlPin4A, LOW); }
else { digitalWrite(controlPin3A, LOW); digitalWrite(controlPin4A, HIGH); }
analogWrite(servoENablePin, steering);
}
App RC Android simple con joystick
Usamos MIT App Inventor 2. Instala MIT AI2 Companion en tu Android. En PC, abre el enlace a mi app RC en Firefox/Chrome (no IE). Inicia sesión con Gmail para ver código. Con la Companion app en el móvil, puedes ver y modificar el código en el navegador y probar al instante.
En la vista Designer ves el pad naranja con bola azul (joystick). En vista Blocks, el bloque principal rastrea el dedo arrastrando la bola:


La posición del dedo se guarda en currentX y currentY y calcula steering y speed (rango -100..0..+100). Limita valores si el dedo sale del pad. Genera cadena de comando:
RC,steering,speed,\n
La cadena se envía por Bluetooth al Arduino. El carácter newline (\n) indica fin de comando.
Leer comandos Bluetooth en Arduino
Conecta módulo HC-05. Mi módulo tiene 6 pines; usamos 4: VCC (5V), GND, TXD, RXD. Cruza líneas: TXD del módulo a RXD Arduino (pin 0), RXD módulo a TXD Arduino (pin 1). Cuidado: El módulo es 3.3V. RXD del módulo no puede ir directo a TXD Arduino (5V). Haz divisor de tensión con tres resistencias de 1 kΩ para bajar a ~3.3V (2/3 de 5V). TXD módulo (3.3V) sí puede ir directo a RXD Arduino (Arduino lo lee como HIGH).
Como pines 0 y 1 comparten USB, desconecta RXD/TXD del módulo al subir código por USB.
Empareja HC-05 con Android: Bluetooth on, abre app, pulsa "Bluetooth connect", haz visible el móvil, busca HC-05, código "1234". Debe aparecer "connected" en verde.
Código de recepción:
#define INPUT_SIZE 30
void loop() {
char input[INPUT_SIZE + 1];
byte size = Serial.readBytesUntil('\n', input, INPUT_SIZE);
input[size] = 0;
char* command = strtok(input, ","); // "RC"
char* RCsteering = strtok(NULL, ","); // -100..100
char* RCspeed = strtok(NULL, ","); // -100..100
int iRCsteering = atoi(RCsteering);
int iRCspeed = atoi(RCspeed);
// ... resto del programa
}
La función strtok trocea la cadena por comas. atoi convierte a entero. Luego multiplicamos por 2.55 para pasar de rango ±100 a 0..255 y llamamos a SetMotorControl().
¿Qué sigue?
Ahora que Arduino controla tu modelo Lego, podrías usarlo como plataforma robótica: añade sensores ultrasónicos, programa evitación de obstáculos, haz tu rover autónomo. O añade más comandos y funciones. Primero, encuentra forma de que Arduino detecte pérdida de conexión Bluetooth y pare el modelo. Cuéntame tu solución.
Pronto verás que protoboard y cables sueltos no aguantan en un modelo móvil. Consigue un shield de motores Adafruit con bornes grandes y recablea/reprograma. También liberarás pines digitales para entradas. Considera un shield de sensores para mejores conexiones.
¡Cuéntame tus proyectos!
Código
Legocar_v3_bluetooth (Arduino)
/* Lego Powerfunctions car model controlled over bluetooth
Arduino Uno controls motors and servo
Remote controlled with android app developed with MIT App Inventor 2
Circuit:
* Serial communication (uses Uno pin 0,1) Bluetooth-module attached (detach when loading over USB)
* L293D with motor (uses Uno digital pins 2,5,9)
* L293D with servo (uses Uno digital pins 6,8,3)
*/
#include
#include
#define INPUT_SIZE 30
const int controlPin1A = 2;
const int controlPin2A = 5;
const int ENablePin = 9;
const int controlPin3A = 6;
const int controlPin4A = 8;
const int servoENablePin = 3;
int motorSpeed = 0;
int motorDirection = 1;
int steering = 0;
int steeringDirection = 0;
void setup() {
Serial.begin(9600);
Serial.setTimeout(1000);
pinMode(controlPin1A, OUTPUT); pinMode(controlPin2A, OUTPUT); pinMode(ENablePin, OUTPUT);
pinMode(controlPin3A, OUTPUT); pinMode(controlPin4A, OUTPUT); pinMode(servoENablePin, OUTPUT);
digitalWrite(ENablePin, LOW); digitalWrite(servoENablePin, LOW);
}
void loop() {
char input[INPUT_SIZE + 1];
byte size = Serial.readBytesUntil('\n', input, INPUT_SIZE);
input[size] = 0;
char* command = strtok(input, ",");
char* RCsteering = strtok(NULL, ",");
char* RCspeed = strtok(NULL, ",");
int iRCsteering = atoi(RCsteering);
int iRCspeed = atoi(RCspeed);
if (iRCsteering > 0) steeringDirection = 1; else steeringDirection = 0;
steering = int(2.55 * abs(iRCsteering));
if (iRCspeed > 0) motorDirection = 1; else motorDirection = 0;
motorSpeed = int(2.55 * abs(iRCspeed));
SetMotorControl();
}
void SetMotorControl() {
if (motorDirection == 1) { digitalWrite(controlPin1A, HIGH); digitalWrite(controlPin2A, LOW); }
else { digitalWrite(controlPin1A, LOW); digitalWrite(controlPin2A, HIGH); }
analogWrite(ENablePin, motorSpeed);
if (steeringDirection == 0) { digitalWrite(controlPin3A, HIGH); digitalWrite(controlPin4A, LOW); }
else { digitalWrite(controlPin3A, LOW); digitalWrite(controlPin4A, HIGH); }
analogWrite(servoENablePin, steering);
}
Repositorio GitHub con código Arduino, diagrama Fritzing y código app para MIT App Inventor: Lego-car-Arduino
Esquemáticos
Ver repositorio GitHub arriba. Incluye archivo Fritzing Lego rc car v2.fzz.
Proceso de manufactura
- Impulse la confiabilidad de componentes de transmisión de potencia: Estrategias probadas para minería, manufactura e industria
- Alquiler de energía y HVAC fiables para un control climático sin interrupciones
- Pastillas Anticonceptivas: Historia, Beneficios, Riesgos y Producción
- Energía eólica: Conversión del movimiento del aire en electricidad limpia
- Paneles de Control Eléctrico: Fundamentos de Diseño para Seguridad y ROI
- Fabricantes del Reino Unido pierden 2,5 millones de libras corrigiendo errores de diseño en proyectos de automatización
- Ocho Pasos Comprobados para Diagnosticar y Reparar su Sistema de Control de Procesos
- Dominar el control de tensión en manipulación de banda: Componentes esenciales explicados
- Derivación de funciones exponenciales de base e
- Antiderivadas de funciones exponenciales de potencia
- Dominando SaaS: estrategias para mantener el control mientras aprovecha la nube