Blog Search

Recent Articles

Como montar un robot controlado por radiofrecuencia

Como montar un robot controlado por radiofrecuencia

Hoy en nuestro blog, explicamos como construir tu propio robot con Arduino y controlarlo por radiofrecuencia. Es un proyecto interesante, por que manejaremos radiofrecuencia, ademas de aprender a leer la información de un joystick y procesarla.

Componentes utilizados.

-2 placas Arduino UNO Rev3. Esta será la placa encargada de recibir la información procedente del modulo de RF y procesarla para hacer las gestiones necesarias. Además la segunda placa será responsable de leer lo que sucede en el joystick y enviar esa información atravez del modulo RF.(Más información aquí)

-Chasis robot 4WD. Sobre este chasis, montaremos toda la electrónica necesaria para manejar nuestro robot. (Más información aquí)

-2 Módulos RF NRF24L01. Con estos módulos comunicaremos el Arduino que tenemos en el mando con el Arduino del robot.(Más información aquí)

-Controlador de motores L298N. Este es el encargado de aportar potencia a las señales de procedentes de nuestro Arduino Uno para controlar los motores.(Más información aquí)

-Cables protoboard. Estos cables los usamos para conectar todos los componentes que componen nuestro robot.(Más información aquí)


Proceso operativo

-El primer paso para desarrollar nuestro proyecto es hacer un esquema que nos indique el modo de conexión de todos los componentes de nuestro robot. (Ver esquema)

-A continuación cableamos toda la electrónica tal y como nos indica el esquema de conexión.

-Escribimos y compilamos el código, que manejara el robot. (Ver código)

-El último paso es probar el robot y depurar el programa hasta conseguir que funcione como deseamos.

Esquema de conexión.

-En el siguiente esquema se representan las conexiones del control TX.

-En el siguiente esquema se representan las conexiones del robot RX.

Código.

Este primer código es el ecargado de manejar el mando de control de robot.

/**
 * A Mirf example to test the latency between two Ardunio.
 *
 * Pins:
 * Hardware SPI:
 * MISO -> 12
 * MOSI -> 11
 * SCK -> 13
 *
 * Configurable:
 * CE -> 10
 * CSN -> 9
 *
 * Note: To see best case latency comment out all Serial.println
 * statements not displaying the result and load 
 * 'ping_server_interupt' on the server.
 */

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

void setup(){
  Serial.begin(9600);
  Mirf.cePin = 10;                // Cambiamos el pin CE del standar ya que usamos un shield para el joystick que no concuerda los pines con la librería
  Mirf.csnPin = 9;                // Cambiamos el pin CSN del standar ya que usamos un shield para el joystick que no concuerda los pines con la librería
  Mirf.spi = &MirfHardwareSpi;    // Configuramos el SPI de Arduino por Hardware
  Mirf.init();                    // Inciamos el módulo de RF
  Mirf.setRADDR((byte *)"clie1"); // Indicamos la dirección para recibir datos
  Mirf.payload = 4;               // Indicamos el número de datos que se espera recibir
  Mirf.config();                  // Configuramos el módulo de RF 
}

void loop(){
  uint8_t datos[Mirf.payload];    // Creamos un array con el tamaño de los datos que recibe el modulo RF
  int valor[2];                   // Variables que son modificadas según valor del joystick
  double calculos[3];             // Estas variables la usamos para calcular la velocidad que debe mandar, según posición del mando
  int vector;                     // Variable que calcula un vectos y nos dice la distancia a la que está el joystick del centro
  
  valor[0]=(analogRead(0)/2.01)-253;  // Leemos el ADC y calculamos para que de aproximadamente uno +-255 de máximo
  valor[1]=(analogRead(1)/2.01)-246;  // Leemos el ADC y calculamos para que de aproximadamente uno +-255 de máximo
  if(valor[0] >255){valor[0]=255;} if(valor[0] < -255){valor[0]=-255;}  // Nos aseguramos que no sobrepase los +255 y os -255
  if(valor[1] >255){valor[1]=255;} if(valor[1] < -255){valor[1]=-255;}  // Nos aseguramos que no sobrepase los +255 y os -255
  
  calculos[0]=valor[0];  // Copiamos los valores las variables calculo para su posterior procesamiento
  calculos[1]=valor[1];  // Copiamos los valores las variables calculo para su posterior procesamiento

  calculos[3]=sqrt((calculos[0]*calculos[0])+(calculos[1]*calculos[1]));  // Calculamos la distancia a la que está el joystick del centro 
  if(valor[0] < 0){calculos[3] *= -1;}                                    // Si es menor que 0, lo ponemos en negativo ya que el cálculo anterior no lo hace
  
  if(calculos[3] > 255){calculos[3]=255;}         // Nos aseguramos que no sea mayor que 255
  if(calculos[3] < -255){calculos[3]=-255;}       // Nos aseguramos que no sea menor que -255
  vector=calculos[3];                             // Pasamos el valor calculado que lleva decimales a una variable de 16 bit y eliminamos los decimales para enviarla posteriormente
  valor[1]=(analogRead(1)/5.11)-100;              // Volvemos a leer el joystick (Eje X) para que nos de un valor de +-100 que es lo que usa la librería del robot en el giro
  if(valor[1] > 99){valor[1]=99;}                 // Nos aseguramos que no sea mayor que 99 ya que 100 el robot lo entiende como giro sobre su propio eje
  if(valor[1] < -99){valor[1]=-99;}               // Nos aseguramos que no sea menor que -99 ya que -100 el robot lo entiende como giro sobre su propio eje
  
  datos[2]=vector>>8;        // Dividimos el vector que son 16bit en dos variables de 8 bit (2 byte) 
  datos[3]=vector;           // Dividimos el vector que son 16bit en dos variables de 8 bit (2 byte) 
  datos[0]=valor[1]>>8;      // Dividimos la variable valor que son 16bit en dos variables de 8 bit (2 byte)
  datos[1]=valor[1];         // Dividimos la variable valor que son 16bit en dos variables de 8 bit (2 byte)
  
  Mirf.setTADDR((byte *)"serv1");  // Configuramos la dirección a donde vamos a enviar los datos
  Mirf.send(datos);                // Enviamos los datos 
  while(Mirf.isSending()){}        // Esperamos que termine la emisión
  
  Serial.print("Vector: ");   // Enviamos los datos por terminal para depurar el control
  Serial.print(" ");          // Enviamos los datos por terminal para depurar el control
  Serial.print(vector);       // Enviamos los datos por terminal para depurar el control
  Serial.print(" ");          // Enviamos los datos por terminal para depurar el control
  Serial.print("Valor 0 ");   // Enviamos los datos por terminal para depurar el control
  Serial.print(valor[0]);     // Enviamos los datos por terminal para depurar el control
  Serial.print(" ");          // Enviamos los datos por terminal para depurar el control
  Serial.print("Valor 1 ");   // Enviamos los datos por terminal para depurar el control
  Serial.println(valor[1]);   // Enviamos los datos por terminal para depurar el control
  
  
  

Este siguiente código es el encargado de recibir la información del mando de control y gestionarla para hacer que el robot se mueva.

// Incluimos la librería de los motores
#include <LEANTEC_ControlMotor.h>
// Configuramos los pines que vamos a usar
ControlMotor control(2,3,4,9,5,6); // MotorDer1,MotorDer2,MotorIzq1,MotorIzq2,PWM_Derecho,PWM_Izquierdo
int led = 10;
int memoled= 0;
/**
 * An Mirf example which copies back the data it recives.
 *
 * Pins:
 * Hardware SPI:
 * MISO -> 12
 * MOSI -> 11
 * SCK -> 13
 *
 * Configurable:
 * CE -> 8
 * CSN -> 7
 *
 */
 
#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

unsigned long time=0;    // Variable para controlar el tiempo entre dato y dato
int valor[2];            // Variable para almacenar la dirección y la velocidad

//----------------------------- Configuramos Ardunio ---------------------------------------
//------------------------------------------------------------------------------------------
void setup(void){
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  Mirf.spi = &MirfHardwareSpi;    // Configuramos el SPI de Arduino por Hardware
  Mirf.init();                    // Inciamos el módulo de RF
  Mirf.setRADDR((byte *)"serv1"); // Indicamos la dirección para recibir datos
  Mirf.payload = 4;               // Indicamos el número de datos que se espera recibir
  Mirf.config();                  // Configuramos el módulo de RF
  time=0;                         // Ponemos a 0 el tiempo
}
//--------------------------- Arrancamos el programa ---------------------------------------
//------------------------------------------------------------------------------------------
void loop(void)
{
  byte datos[Mirf.payload];      // Buffer para almacenar los datos

  if(!Mirf.isSending() && Mirf.dataReady()){ // Esperamos recibir un dato
    Mirf.getData(datos);       // Copiamos al buffer los datos recibidos
    time = millis();           // Almacenamos el tiempo en la variable
    valor[0]=(datos[0]<<8)+datos[1];  // Como lo que recibimos son 4 byte (2 variables de 16bit) tenemos que unirla
    valor[1]=(datos[2]<<8)+datos[3];  // Como lo que recibimos son 4 byte (2 variables de 16bit) tenemos que unirla
    Serial.print("Robot ");    // Línea para ver en el terminal que recibe el robot
    Serial.print(valor[0]);    // Línea para ver en el terminal que recibe el robot
    Serial.print(" ");         // Línea para ver en el terminal que recibe el robot
    Serial.println(valor[1]);  // Línea para ver en el terminal que recibe el robot
    if(memoled<25)
    {digitalWrite(led, LOW);}
    if((memoled>25)&&(memoled<35))
    {digitalWrite(led, HIGH);}
    if(memoled>35)
    {memoled=0;}
    memoled++;
  
  }
  
  if ( ( millis() - time ) > 1000 ) {   // Comprobamos si desde la última vez que recibimos un dato hasta ahora ha pasado mas de 1 seg
    control.Motor(0,0);                 // Si ha pasado mas de 1 seg, paramos le robot ya que no hay recepción de datos
    Serial.println("Error de recepcion de datos"); // Línea para ver en el terminal que recibe el robot  
    delay(500);     // Paramos 0,5 seg el robot
    digitalWrite(led, HIGH);
  }
  else{                                 // Si todo está correcto y estamos recibiendo datos, seguimos
    control.Motor(valor[1], valor[0]);  // Pasamos los datos al control de motores.
  }
  
}




Imágenes del proyecto.

-En la siguiente imagen vemos el robot ya montado, con una cámara instalada en su parte superior.







Video del robot funcionando

17Comentarios

    • Avatar
      lecoquierre
      feb 25, 2015

      buenos días Me pregunto si usted me puede dar una cotización incluyendo todo lo que hay en el video, incluyendo el joystick gracias

      • Avatar
        Leantec
        mar 16, 2015

        Buenas Lecoquierre, Hemos intentado contactar con usted pero nos ha sido imposible. Si aún sigue interesado puede escribirnos directamente a store@leantec.es y estaremos encantados de detallarle un presupuesto sobre sus necesidades. Esperamos su respuesta. Un saludo. At. al Cliente Leantec.es

    • Avatar
      toan phan
      jun 21, 2015

      you can send me share with library code is not download error toanvolvo@gmail.com

    • Avatar
      Juan José
      sep 12, 2015

      Hola, muy buenas: Realicé una compra en la web para realizar un montaje similar, me gustaría si fuera posible que me aconsejara sobre cuál es la mejor forma de alimentar el controlador L298N así como el Arduino. Actualmente suministro 9V al driver (con el jumper colocado) y energizo el Arduino independientemente... el problema es que parece que los motores no tienen suficiente potencia para conseguir desplazar el robot (incluso fijando velocidad máxima). ¡Enhorabuena tanto por el blog como por la página! Muchas gracias de antemano, un saludo.

      • Avatar
        Leantec Robotics & Electronics
        sep 17, 2015

        Hola Juan José. Las pilas de 9V para la alimentación de motores suelen ser insuficientes, no por la tensión que suministran, si no más bien por la capacidad que tienen, que apenas llegan a los 200mA. Nuestro consejo es que uses 4 pilas AA si estás manejando el chasis de 2 ruedas o 6 pilas AA si estas con el chasis de 4 ruedas. Una cosa a tener en cuenta si alimentas Arduino de forma independiente a el controlador de motores, es que GND del controlador y Arduino deben estar unidos. Un saludo y si tiene alguna otra pregunta no dude en escribirnos. Servicio técnico Leantec.

    • Avatar
      Juan Carlos Mendoza
      oct 9, 2015

      Buen dia, me gustaria pudiera cotizarme todo los componentes utilizados en el carro. Y me gustaria se pusieran en contacto conmigo para la realizacion de un proyecto mechatronics@m-smartsolutions.com Espero su pronta respuesta

    • Avatar
      Ramón
      nov 15, 2015

      Buenas tardes, como puedo saber cuál es cada pin del modulo RF NRF24L01? En la placa del propio modulo no están marcadas. Gracias.

      • Avatar
        Leantec
        nov 18, 2015

        Buenos días Ramon. En nuestra entrada de hoy, hacemos un sencillo proyecto con el módulo NRF24L01 y hay tenemos el pineado de dicho módulo. Le dejo el enlace. http://www.leantec.es/blog/44_Tutorial-Arduino--Modulo-NRF24L01.html Un saludo. Servicio técnico Leantec

    • Avatar
      Maximiliano santibañez
      abr 16, 2016

      Amigo, no me funcionó, ya cheque conexiones, todo y no me funciona, saludos.

      • Avatar
        Luis Felipe
        may 11, 2016

        Amigo, te fijaste que el esquema del control del robot no coincide con los pines que declara en el código Arduino? Yo cambié las conexiones de acuerdo al código y el Serial Monitor me muestra que funciona...

    • Avatar
      tri
      may 10, 2016

      you can send me share code pls ??

    • Avatar
      tri
      may 10, 2016

      you can send me share code pls ??

    • Avatar
      rema
      ago 30, 2016

      hi sir, i have to control the robot car project. Where the rear wheels in the form of a dc motor is controlled with flex sensors and front wheels in the form of a servo motor controlled by the accelerometer sensor. Robot controller with a car connected with nrf24l01. if one of the sensors to control I can. but if it combines both to control I can not. Both sensors transmit data simultaneously . dc motors and servo motors confused receive data so that its movement is chaotic. How should I fix this? can you help me.? Can I send my program to you and you see.? Please. My email: rema_adhe@yahoo.com

    • Avatar
      Rafael Lopez Gonzalez
      nov 4, 2016

      Hola! Donde puedo encontrar la librería para controlar los modulos NRF24L01? Muchisimas gracias de antemano!

    • Avatar
      Antonio
      ene 12, 2017

      donde puedo encontar el pinout del pedido que he recibido de vosotros correspondiente a 2 modulos NRF24L01 + PA + LNA? gracias

    • Avatar
      gilmar
      feb 17, 2017

      me podrian decir que baterias puedo usar para este proyecto

    • Avatar
      CARLOS
      nov 9, 2017

      Hola, un proyecto muy interesante, ya tengo todos los componentes pero.... podriais poner un esquema de conexion con mas resolución no se ven bien las conexiones, muchas gracias.

Leave a Reply

* Name:
* E-mail: (Not Published)
   Website: (Site url withhttp://)
* Comment:
Type Code