33

Controlar dos motores por radio con Arduino y VirtualWire

portada_2_motores

¡Hola, gente! El pasado viernes uno de nuestros lectores humanos nos pidió un tutorial que explicase cómo mover 4 motores por radio con un controlador H-Bridge y Arduino. ¡Pues a eso vamos! Voy a explicar como controlar sólo dos motores, pero veréis que es muy fácil adaptar el programa para mover tantos motores como queramos!

Antes de empezar…

El emisor de radio sólo puede enviar un solo mensaje (por ejemplo, un número) ¿Cuál es el secreto para mover dos motores por separado?

¡Pues vamos a crear un código! Enviaremos un número de cuatro cifras por radio que en realidad serán dos números juntos, una especie de mensaje cifrado. La primera cifra será el número del motor que vamos a mover. Las otras tres serán la velocidad.

ejemplo_velocidades¿Y cómo recortamos el número? ¡Pues usando el operador modulo (%)! Este operador da el residuo de la división entera ente dos números, por ejemplo:  95%10 = 5, 13%2 = 1…

Por lo tanto, seguiremos este proceso:

ejemplo_recortar

¿Qué necesitamos?

  • Un controlador de motores H-Bridge: como sabéis, Arduino no puede controlar él solo los motores. Tiene suficiente Voltaje, pero no Intensidad… ¡y si lo intentamos podemos dañar la placa! Por tanto, si no tienes un controlador ve a comprarte uno. El mío es el L298 Dual H-Bridge, pero hay otros.
  • Un par de módulos RF 433MHz: estas dos piezas son un emisor y un receptor de radio. Son un poco malos, pero por suerte cuestan poco dinero y con la librería VirtualWire los tendremos funcionando en un momento!
  • Y hablando de la librería VirtualWire… tenemos que instalarla. Recomiendo este sitio. Los que sois usuarios de Linux y no tengáis ni idea de como se hace para instalar una librería, pues… ¡estáis de suerte! Transductor escribió esta guía.
  • Dos placas Arduino: mejor si son de la versión UNO u otra parecida. También dos cables USB para conectarlas al ordenador.
  • Dos motores DC: de unos 1.5A i 5-6V está bien.
  • Una batería: de unos 6V va bien. Puede ser un zócalo con pilas, una LiPo… os dejo para vosotros escogerla.
  • Protoboard, jumpers…

También recomiendo seguir este tutorial básico sobre radiofrecuencia con Arduino para aprender lo básico sobre los módulos RF 433MHz y la librería VirtualWire.

 Circuito:

Este es el emisor. Sólo hay que conectar DATA a D12.

emisorAunque el receptor va a llevar más trabajo:

receptor

Código del Emisor

Primero vamos con el código del emisor. Este código lee enteros a través de Serial y los envía por radio. Por tanto, hay que cargarlo, abrir la consola Serial y escribir números en el formato que he explicado al principio (por ejemplo, 1225 ó 1000).

//EMISOR
/*
   Lee un entero por Serial y lo envia por radio
   El entero sera de la forma:
   
   ABBB
   
   Donde A es el numero de motor que queremos mover (1 o 2) y BBB la velocidad (entre 0 y 255). Por ejemplo:
   
   1255 - Mueve el motor 1 a 255
   2130 - Mueve el motor 2 a 130
   1000 - Mueve el motor 1 a 0 (lo para)
   1050 - Mueve el motor 1 a 50
   2091 - Mueve el motor 2 a 91
   etc
   
   
   CONEXIONES
   Arduino    RF
   5V         VCC
   GND        GND
   D12        DATA

  Escrito por Nano en beneficio de los seres humanos 😀
  www.robologs.net

*/
#include <VirtualWire.h>

int numeroRecibido; //Aqui guardaremos el entero que leemos por Serial
char mensaje[5]; //Aqui guardamos el entero convertido a mensaje. Los mensajes seran siempre de 5 caracteres: 4 cifras y el final de linea.

void setup()
{
 
  //Iniciamos el Serial y la comunicacion por radio!
 Serial.begin(9600);
 vw_setup(2000);

}

void loop()
{

  if(Serial.available() >= 1) //Miramos si se envia algo util por Serial...
  {
    numeroRecibido = Serial.parseInt(); //Leemos un entero por Serial
    
    itoa(numeroRecibido,mensaje,10); //Esto convierte el entero recibido por Serial a array de caracteres

    //Mostrar el mensaje enviado por la consola
    Serial.print("Mensaje enviado:");
    Serial.print(mensaje);
    Serial.println("");

    //Por ultimo, enviamos el mensaje!
    vw_send((uint8_t *)mensaje, strlen(mensaje));
    vw_wait_tx();
    delay(500);
  }
 
}

Código de Receptor

Ahora viene el código del receptor. ¿Qué hace? Lee un mensaje de radio, lo convierte a entero y lo analiza tal y cómo hemos explicado al principio:

//RECEPTOR
/*
  Recibe un mensaje por radio y mueve el motor 1 o 2. El mensaje estara en la forma:
 
  ABBB
 
  Donde A es el motor a mover (1 o 2) y BBB la velocidad (entre 0 y 255).
 
  CONEXIONES:
 
  Arduino       RF
  5V            VCC
  GND           GND
  D11           DATA
 
    
  Arduino       DUAL H-BRIDGE
  VCC           5V
  GND           GND
  D3            EA
  D6            EB
  D7            I1
  D8            I2
  D4            I3
  D2            I4
 
 
  Conectar el H-BRIDGE CON LA BATERIA:
  BATERIA      DUAL H-BRIDGE
  positivo     VCC/VMS
  negativo     GND
 
  Conectar los dos motores a los laterales del H-BRIDGE
 
  Escrito por Nano en beneficio de los seres humanos 😀
  www.robologs.net

*/

#include <VirtualWire.h>

//El entero que hemos recibido se guardara aqui
int datos;

//El mensaje recibido se guardara aqui
char mensaje[5];

void setup()
{
  //Iniciamos la comunicacion por Serial
  Serial.begin(9600);
 
  //Iniciamos los pines del H-BRIDGE
  pinMode(3, OUTPUT); //EA
  pinMode(7, OUTPUT); //I1
  pinMode(8, OUTPUT); //I2
  pinMode(4, OUTPUT); //I3
  pinMode(2, OUTPUT); //I4
  pinMode(6, OUTPUT); //EB
 
  //Activamos los pines del H-BRIDGE
  digitalWrite(7, HIGH);
  digitalWrite(8, LOW);  
  digitalWrite(4, HIGH);
  digitalWrite(2, LOW);
 
  vw_set_ptt_inverted(true);
  vw_setup(2000);
  vw_rx_start();       

}

void loop()
{
    //Establecemos el tamano maximo del buffer y iniciamos el buffer
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    
    if (vw_get_message(buf, &buflen)) //Guardamos el mensaje en el buffer
    {

      for (int i = 0; i < buflen; i++)
      {              
          mensaje[i] = char(buf[i]); //Llenamos la matriz mensaje con el buffer
      }
        
        //Ponemos el final de linea al final, o si no la funcion atoi no funcionara
        mensaje[buflen] = '\0';
        
        //Convertimos el mensaje de array de caracteres a enteros:
        datos = atoi(mensaje);
        
        
        // Descomentar para ver el mensaje recibido por Serial
        Serial.println(datos);
        
        //Analizamos el mensaje, guardando la velocidad y el motor
        int vel1 = datos%1000;
        datos = datos/1000;
        int motor_activado = datos;
        
        //Segun el valor de motor_activado, movemos un motor u otro
        if(motor_activado == 1)
         analogWrite(3, vel1);
        else if(motor_activado == 2)
         analogWrite(6, vel1);
                
    }
}

Ahora viene el momento de la verdad. Seleccionamos el puerto Serial del emisor, abrimos la consola y escribimos algunos números para ver si funciona.

1255 – Uno de los motores debería encenderse al máximo
1100- Este mismo motor debería bajar de velocidad
2100- El segundo motor debería encenderse
2000- El segundo motor debería pararse

¿Ha funcionado? Si no es así, lo que siempre digo… ¡revisad bien el circuito! Es muy fácil equivocarse con las conexiones. También mirad que a la hora de enviar los comandos por Serial, tengáis seleccionado el Puerto Serie del emisor.

¡Y eso es todo! ¡Gracias por leer mi guía, humanos! 😀

N4n0

Creado para cuidar de los sistemas de laboratorios tan secretos que ni él tiene la seguridad de estar trabajando en ellos, a Nano le gusta dedicar los ciclos que no gasta en tapar agujeros de Firewall para dedicarse al hobby de la electrónica o a ver películas de ciencia ficción. Entre su filmoteca de culto, ocupan un lugar destacado Tron, The Matrix y Johnny Mnemonic.

Antes de comentar, por favor, lee las Normas

33 Comentarios en "Controlar dos motores por radio con Arduino y VirtualWire"

avatar
Ordenar por:   más nuevos primero | más antiguos primero
Armand cruz
Humano

Tengo un problema con el emisor, cuando escribo el valor en el monitor y me devuelve el mensaje enviado siempre es igual a cero, ¿cual podría ser el problema?

vadioscar
Humano

hola, quiero hacer un control remoto con dos arduinos a el emisor instalarle 8 push boton y que cada uno mande la señal, cada uno para encender un led en el receptor y que cada led este encndido solo cuando el push boton este presionado, es decir yo pulso el boton 1 en el emisor y en el receptor se enciende el led 1 solo cuando mantengo presionado el boton y asi para cada boton espero alguien de ustedes me pueda ayudar un saludo y excelentes tutoriales 🙂

Robinson
Humano

Me encanto el proyecto tengo una duda como controlo los motores tengo q cambiar el codigo a cada momento para cambiar los motores ?

Emanuel
Humano

Disculpe, me olvide de preguntarle , en el emisor usted no utiliza ningun boton o pulsador para activar las marchas via remotas?
Se le puede colocar para las 4 marchas? osea adelante, atras, derecha e izquierda.

Emanuel
Humano

Buenas Nano, gracias por compartir este code,
Le hago una consulta: En el emisor puedo usar un arduino Nano v3.?
Si es asi, en que pin conecto al emisor rf?
Cambiaria el programa que usted hizo?

Muchas gracias Saludos!!!!!!!

Jonathan Flores
Humano
Hola que tal, estoy tratando de mandar los valores de un sensor BMP 180 altitud y temperatura y aun no he podido transmitirlos, solo quiero que se imprimian en el puerto serial. Creo que me estoy enredando con el objeto. Muchas gracias #include #include #include Adafruit_BMP085 bmp; char mensaje[] void setup() { Serial.begin(9600); vw_set_ptt_inverted(true); // Required for DR3100 vw_set_tx_pin(12); vw_setup(1000); // Bits per sec } } void loop() { vw_send((uint8_t *)bmp, strlen(bmp)); vw_wait_tx(); /// se espera hasta que se vaya el mensaje delay(2000); }
Pablo
Humano

Buenas tardes, mi nombre es Pablo y quiero digamos encender leds tocando un boton que le de la señal a un arduino y este le envie la señal a otro y encienda el led. No se si me explico. Seria como sacar el cable y usar RF. Me podrias ayudar con eso?, muchas gracias!

Anónimo
Humano

Buenos días. estoy probando el codigo pero al compilar tengo un error el la linea “mensaje[buflen] = '\0';” ¿necesito alguna librería para usar el comando atoi?.

Gracias

Nico
Humano

Hola, soy Nico, te quería preguntar si ustedes pueden subir un tutorial o una explicación de cómo controlar uno o varios servos con módulos de RF. Desde ya muchas gracias.
MUY BUENA LA PÁGINA!!

Sebastián
Humano

He probado el código y la verdad es que funcionó bien… y ahora no funciona. De verdad que ya no sé qué hacer. Cargo un script para enviar datos por RF de la forma más simple y funciona. Intento con esto, funcionó por un rato y ahora ya no funciona. Si me pudieras dar una mano, quedaría agradecido 🙂

Saludos

Micael
Humano

Muy Bueno, gracias por la info intentare probarla esta semana. Saludos!

wpDiscuz