Transforma un viejo coche RC en un vehículo controlado por joystick con Arduino
Componentes y suministros
| Arduino UNO | × | 1 |
| Arduino USB Host Shield | × | 1 |
| Mando inalámbrico Xbox 360 | × | 1 |
| Receptor inalámbrico Xbox 360 | × | 1 |
| Controlador de motor L293D (o SN754410) | × | 1 |
| Regulador 7812 | × | 1 |
| Regulador 78S12 | × | 1 |
| Interruptor | × | 1 |
| Disipadores térmicos | × | 1 |
| Conector de alimentación (power plug) | × | 1 |
| Conector de batería para 8 pilas AA 1,5V con enchufe 9V | × | 1 |
Sobre el proyecto
1. Consigue el coche
Primero necesitas un viejo coche RC. Tuve la suerte de encontrar un monster truck. ¡Puede ser muy interesante!
Retira toda la electrónica excepto los cables que controlan los dos motores.

2. Arduino y el Shield
Toma una placa Arduino (elegí Arduino UNO) y enchufa el USB Host Shield encima.

3. Fija Arduino al coche
Monta el shield sobre el Arduino UNO y el USB Host Shield y atorníllalos al coche. Usé uno de los agujeros de la antigua placa electrónica.

4. Haz el circuito
Lo hice en una protoboard, pero también puedes hacerlo en una placa perforada. Básicamente el circuito consta de dos drivers (L293D o SN754410) y dos reguladores de voltaje. Los reguladores limitan el voltaje de las pilas. Sugiero usar 10-12 pilas AA 1,5V para tener un máximo de 15-18V, lo que dará más tiempo de juego. Como los motores requieren mucha corriente para arrancar el coche desde reposo (unos 2A), necesitamos un regulador potente como el 78S12.
Si quieres más info sobre cómo funciona el driver, mira aquí.

5. Fija el circuito al coche
Busca un hueco en el coche RC para colocar el circuito. En mi monster truck hay mucho espacio. Una vez posicionado, conecta el circuito a los dos motores. Finalmente enchufa el receptor inalámbrico en el USB Host Shield.

6. El código
El código se basa en los ejemplos de la librería USB Host Library 2.0 alojada en GitHub por Kristian Lauszus (circuits@home).
/* Example sketch for the Xbox Wireless Receiver library - developed by Kristian Lauszus
Soporta hasta cuatro mandos inalámbricos
Para más info: https://blog.tkjelectronics.dk/2012/12/xbox-360-receiver-added-to-the-usb-host-library/
o email: kristianl@tkjelectronics.com */
#include <XBOXRECV.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
USB Usb;
XBOXRECV Xbox(&Usb);
#define motorPinOne 5 // Debe tener PWM
#define motorPinTwo 6 // Debe tener PWM
#define motor2PinOne 4
#define motor2PinTwo 7
#define BRAKE 2
int pulse = 0;
int forward = 0;
int brake_on = 0;
void setup() {
TCCR1B = TCCR1B & 0b11111000 | 0x02;
Serial.begin(115200);
if (Usb.Init() == -1) {
Serial.print(F("\r\nOSC did not start"));
while(1); // halt
motors_stop();
center();
}
Serial.print(F("\r\nXbox Wireless Receiver Library Started"));
pinMode(motorPinOne, OUTPUT);
pinMode(motorPinTwo, OUTPUT);
pinMode(motor2PinOne, OUTPUT);
pinMode(motor2PinTwo, OUTPUT);
pinMode(BRAKE, OUTPUT);
digitalWrite(BRAKE, LOW);
}
void loop() {
Usb.Task();
if (Xbox.XboxReceiverConnected) {
for (uint8_t i = 0; i < 4; i++) {
if (Xbox.getButtonPress(L2, i)) {
Serial.print("L2: "); Serial.print(Xbox.getButtonPress(L2, i));
pulse = Xbox.getButtonPress(L2, i);
forward = 0;
clockwise();
}
if (Xbox.getButtonPress(R2, i)) {
Serial.print("R2: "); Serial.println(Xbox.getButtonPress(R2, i));
pulse = Xbox.getButtonPress(R2, i);
forward = 1;
counterClockwise();
}
// Lectura de joysticks analógicos
if (Xbox.getAnalogHat(LeftHatX, i) > 7500 || Xbox.getAnalogHat(LeftHatX, i) < -7500 ||
Xbox.getAnalogHat(LeftHatY, i) > 7500 || Xbox.getAnalogHat(LeftHatY, i) < -7500 ||
Xbox.getAnalogHat(RightHatX, i) > 7500 || Xbox.getAnalogHat(RightHatX, i) < -7500 ||
Xbox.getAnalogHat(RightHatY, i) > 7500 || Xbox.getAnalogHat(RightHatY, i) < -7500) {
if (Xbox.getAnalogHat(LeftHatX, i) > 7500) {
Serial.print(F("LeftHatX: ")); Serial.print(Xbox.getAnalogHat(LeftHatX, i)); Serial.print("\t");
if (Xbox.getAnalogHat(LeftHatX, i) > 26000) turn_right(); else center();
}
if (Xbox.getAnalogHat(LeftHatX, i) < -7500) {
Serial.print(F("LeftHatX: ")); Serial.print(Xbox.getAnalogHat(LeftHatX, i)); Serial.print("\t");
if (Xbox.getAnalogHat(LeftHatX, i) < -26000) turn_left(); else center();
}
if (Xbox.getAnalogHat(LeftHatY, i) > 7500 || Xbox.getAnalogHat(LeftHatY, i) < -7500) {
Serial.print(F("LeftHatY: ")); Serial.print(Xbox.getAnalogHat(LeftHatY, i)); Serial.print("\t");
}
if (Xbox.getAnalogHat(RightHatX, i) > 7500) {
Serial.print(F("RightHatX: ")); Serial.print(Xbox.getAnalogHat(RightHatX, i)); Serial.print("\t");
}
if (Xbox.getAnalogHat(RightHatX, i) < -7500) {
Serial.print(F("RightHatX: ")); Serial.print(Xbox.getAnalogHat(RightHatX, i)); Serial.print("\t");
}
if (Xbox.getAnalogHat(RightHatY, i) > 7500 || Xbox.getAnalogHat(RightHatY, i) < -7500) {
Serial.print(F("RightHatY: ")); Serial.print(Xbox.getAnalogHat(RightHatY, i));
}
Serial.println();
}
// Botones digitales
if (Xbox.getButtonClick(UP, i)) Serial.println(F("Up"));
if (Xbox.getButtonClick(DOWN, i)) Serial.println(F("Down"));
if (Xbox.getButtonClick(LEFT, i)) Serial.println(F("Left"));
if (Xbox.getButtonClick(RIGHT, i)) Serial.println(F("Right"));
if (Xbox.getButtonClick(START, i)) Serial.println(F("Start"));
if (Xbox.getButtonClick(BACK, i)) Serial.println(F("Back"));
if (Xbox.getButtonClick(L3, i)) Serial.println(F("L3"));
if (Xbox.getButtonClick(R3, i)) Serial.println(F("R3"));
if (Xbox.getButtonClick(L1, i)) Serial.println(F("L1"));
if (Xbox.getButtonClick(R1, i)) Serial.println(F("R1"));
if (Xbox.getButtonClick(XBOX, i)) { Xbox.setLedMode(ROTATING, i); Serial.println(F("Xbox")); }
if (Xbox.getButtonClick(A, i)) Serial.println(F("A"));
if (Xbox.getButtonClick(B, i)) {
Serial.println(F("B"));
digitalWrite(BRAKE, HIGH);
brake_on = 1;
pulse = 100;
if (forward) clockwise(); else counterClockwise();
}
if (Xbox.getButtonClick(X, i)) Serial.println(F("X"));
if (Xbox.getButtonClick(Y, i)) { Serial.println(F("Y")); motors_stop(); }
}
}
delay(1);
}
void clockwise() {
Serial.print("Rotation is clockwise and speed is "); Serial.println(pulse);
analogWrite(motorPinOne, pulse);
analogWrite(motorPinTwo, 0);
if (brake_on) { delay(600); digitalWrite(BRAKE, LOW); brake_on = 0; pulse = 0; }
}
void counterClockwise() {
Serial.print("Rotation is counter-clockwise and speed is "); Serial.println(pulse);
analogWrite(motorPinOne, 0);
analogWrite(motorPinTwo, pulse);
if (brake_on) { delay(600); digitalWrite(BRAKE, LOW); brake_on = 0; pulse = 0; }
}
void turn_left() {
digitalWrite(motor2PinOne, HIGH);
digitalWrite(motor2PinTwo, LOW);
}
void turn_right() {
digitalWrite(motor2PinOne, LOW);
digitalWrite(motor2PinTwo, HIGH);
}
void motors_stop() {
analogWrite(motorPinOne, 0);
analogWrite(motorPinTwo, 0);
pulse = 0;
}
void center() {
digitalWrite(motor2PinOne, LOW);
digitalWrite(motor2PinTwo, LOW);
}
Código
Fragmento de código #1 Arduino
(El mismo código completo se muestra arriba.)
GitHub
https://github.com/felis/USB_Host_Shield_2.0
Proceso de manufactura
- Construya un robot Raspberry Pi controlado por Bluetooth con retroalimentación de audio
- Lámpara de mesa RGB controlada por gestos – Iluminación interactiva y sin manos
- Controla LEDs con Alexa mediante Raspberry Pi – Guía paso a paso fácil
- Brazo Robótico de 6 Grados de Libertad Controlado por Nunchuk con Arduino
- Controla Dos Motores Paso a Paso con Arduino Nano y Joystick - Tutorial Sencillo
- Construye un robot controlado por voz con Arduino Nano
- Contador Inteligente de Plazas de Aparcamiento: Seguimiento en Tiempo Real con Arduino, Processing y PHP
- PiBot: Robot Pianista con Arduino para Interpretación Musical de Precisión
- Wi-Servo: Controla servomotores por Wi‑Fi desde un navegador web
- Construye un volante joystick personalizado con Arduino para gaming
- Construye tu Propio Coche RC Porsche con Arduino: Guía Paso a Paso