martes, 14 de abril de 2015

Robot Arduino UNO controlado desde un móvil Android, con un módulo bluetooth JY-MCU.

En este tutorial y en el siguiente vídeo se enseña a controlar el robot Andromina ON ROAD v.1.2 por medio de un móvil Android y una placa Arduino UNO. Para ello descargamos en el teléfono móvil una aplicación de GOOGLE PLAY, llamada "Arduino Bluetooth RC car", y usaremos un módulo bluetooth JY-MCU para la comunicación entre ellos. En la foto siguiente se aprecia la plataforma robótica totalmente montada, con un Arduino UNO, un módulo Bluetooth y una placa de motores L298n.
Robot con Arduino.
Vista del robot Andromina ON ROAD.
En el siguiente vídeo tutorial se enseña cómo controlamos al robot por medio de la pantalla táctil del teléfono móvil con el sistema operativo Android y la APP descargada de GOOGLE PLAY. Vemos como las 4 ruedas direccionales del robot giran las 4 a la vez o las 4 independientemente.
Vídeo de demostración de este tutorial.
Como puede apreciarse en estas fotos, en este montaje aún queda mucho espacio en el robot para colocar más componentes electrónicos, tales como sensores IR de proximidad, cámaras etc...
Robot autónomo
Vista trasera del robot.
El robot Andromina ON ROAD V.1.2. es una plataforma robótica omnidireccional (robot omnidireccional  o robot holonómico). Es un robot que puede desplazarse en cualquier dirección sin la necesidad de alcanzar previamente una orientación específica. Es decir, es capaz de realizar giros, movimientos en cualquiera de las componentes del plano, bien sean traslaciones (hacia adelante, en reversa, laterales) o rotaciones. Para que el robot sea omnidireccional necesita ser controlado por una placa de motores de 4 canales independientes. En este tutorial la placa de motores es simple y solo tiene dos canales. Lo cual permite muchos movimientos de un robot omnidireccional, pero no todos.

1-Lista de componentes: Para realizar este montaje se ha usado los mínimos componentes que necesita el robot Andromina. Usaremos:
  1. Kit Andromina robot v1.2 ON ROAD o OFF ROAD. Cualquiera de los dos robots sirven.
  2. Una placa Arduino UNO (Lseeduino o Freaduino) o cuanquier de estas Placas.
  3. Un módulo controlador de motores L298N de dos canales.
  4. Un módulo bluetooth JY-MCU.
  5. Una batería de Ion-Litio de 12 voltios.
  6. Un condensador electrolítico de 6,3 voltios y 1800 micro faradios.
  7. Un móvil con el sistema operativo Android 2.3.3 (o superior) y con la aplicación Bluetooth RC Controller instalada. Esta aplicación se tiene que descargar de Google Play. Es gratuita.
Vista superior del esquema eléctrico.
En este ejemplo básico, se han usado los componentes más económicos que hay en el mercado, para que quien quiera realizarlo puede hacerlo si tener que desembolsar mucho dinero.

2-Esquema eléctrico: En la foto siguiente se muestra el esquema eléctrico usado en este tutorial. Este es el esquema eléctrico más simple que podemos montar en este robot.
Esquema eléctrico.Arduino UNO
Vista del esquema eléctrico del robot.
Lo bueno de usar esta placa es que está preparada con 3 hileras de pines por cada salida del Arduino, el pin amarillo es la salida, el pin rojo es el positivo +5v y el pin negro es el negativo. Gracias a estas hileras de 3 pines, los 4 servo motores se conectan directamente sobre los 3 pines de la placa y se alimentan directamente desde la placa Arduino UNO. No se necesita ninguna alimentación extra para los servos. Ya que la placa Arduino proporciona toda la corriente que necesitan los 4 servos.
Pines para la conexión de los servos
Vista de las 3 hileras de pines, amarillos, rojos y negros de la placa.
Placa del robot
Vista de la placa Freaduino UNO.
Partes de la placa del robot
Descripción de los diferentes componentes de la placa.
Esta placa tiene un interruptor para conmutar entre +3,3v y +5v. Se tiene que dejar en la posición de +5v. Ya que los 4 servo motores trabajan a +5v. Este interruptor se muestra en la foto siguiente. Para ver esquemas más complejo podéis mirar en el Tutorial 2 de este blog.
Vista del interruptor de +3,3v o +5v,  en su posición +5v.
Una vez hemos acabado de montar este esquema eléctrico nos quedan libres 2 entradas digitales y las 5 entradas analógicas de la placa Arduino. Aún dispondremos de estas entradas para añadir más componentes a nuestro robot.
Como se puede ver en el esquema, el módulo Bluetooth está conectado a los pines 0 y 1 de la placa Arduino.
Módulo Bluetooth JY-MCU y Arduino
Módulo Bluetooth JY-MCU.
Módulo Bluetooth y Arduino UNO
El módulo Bluetooth conectado a los dos pines de comunicación
Estos dos pines de comunicación en serie, respectivamente Rx y Tx,  son los que usa Arduino para conectarse con el PC. Para cargar el "Sketsh" a la placa Arduino se tiene que desconectar antes el módulo Bluetooth o si no, da un error el programa IDE de Arduino y no se puede cargar el programa "Sketsh". Ya que estamos usando estos dos pines para realizar dos tareas al mismo tiempo y esto no puede ser. Cada vez que queramos carga el "Sketsh" debemos desconectar el módulo Bluetooth y una vez está el "Sketsh" bien cargado se vuelve a conectar el módulo Bluetooth.
Eléctrico eléctrico del robot.
Foto del esquema eléctrico básico del robot Andromina.
Yo tengo como costumbre colocar un condensador de 6,3 voltios y  1800 micro faradios en los 2 pines +5v y GND de la placa Arduino. De esta manera se mantiene la tensión más estable en la placa Arduino, al accionar los servomotores. Ya que estos servos están conectados directamente a la placa. Podemos ver dicho condensador en la foto anterior, en color negro. Debemos de colocar el condensador correctamente ya que las patas del condensador tiene polaridad.
Truco ; Para simplificar la realización del esquema eléctrico, yo suelo soldar los cables de alimentación de la placa de los motores L298n a los dos terminales de entrada de la placa Arduino. De esta manera, al conectar la batería de 12v al Arduino alimentamos directamente el módulo L298n a 12v. En la foto inferior se aprecia los dos cables soldados a los dos soldaduras de los terminales de entrada del conector ø2.1mm (GND y Vcc).
Cables de alimentación soldados a la placa Arduino UNO
Cables de alimentación soldados a la placa Arduino UNO por la parte trasera.
3-Módulo L298n: Para la realización de este esquema eléctrico se tienen que eliminar los dos puentes "Jumpers" que lleva de serie los dos pines ENA y ENB del módulo L298n. En la foto siguiente se ve el módulo y los dos "jumpers" a eliminar.
Módulo L298n y los 2 "jumpers".
Módulo L298n y los 2 "jumpers".
4-Módulo Bluetooth : El módulo Bluettoth que se ha usado en este tutorial es el módulo JY-MCU. Podríamos haber usado otro módulo, ya que en el mercado hay varios modelos diferentes. Yo he usado este modelo porque es bastante económico. En la foto siguiente se ve este módulo conectado directamente a los dos pines 0 y 1 la placa Arduino. De esta manera solo necesitamos dos cables de alimentación del módulo.
Módulo Bluetooth
Vista del módulo Bluetooth4
5-La aplicación "Arduino Bluetooth RC car": Esta aplicación se tiene que descargar al teléfono móvil desde GOOGLE PLAY y es totalmente gratuita. La descarga se hace directamente desde el móvil y en el link; Arduino bluetooth rc car

Aplicación Arduino Bluetooth RC car
Vista de la pantalla de control del robot.
Una vez hemos instalado la aplicación en el móvil tenemos que cambiar la configuración de la aplicación que viene de serie.
6-Sketch de Arduino UNO: A continuación se presenta el "Sketsh" que cargamos al Arduino para el control del robot y la comunicación con el móvil.

/* Programa para Andromina Robot ON ROAD 4x4 con 4 ruedas direccionales con 4 servos  + Arduino UNO Lseeduino + motor shield L298N. (24-03-2015).
*/// Librerías /////////////////////////////////////////////////////////////////////////////////
#include<SoftwareSerial.h> // Carga la librería SoftwareSerial que permite la comunicación
#include <Servo.h>    // Carga la librería de los servos
//// Declaración de las variables ///////////////////////////////////////////////////////////////
SoftwareSerial blue(0,1); // Declaramos los dos pines de comunicación. Ojo que el pin 0 -> Rx conectar al pin Tx del módulo bluetooth y el pin 1 -> Tx con el pin Rx del módulo.
char caracter;            // Declaración de variable caracter
//// Declaración de constantes, las teclas de la aplicación "Bluetooth rc controller" del movil Android envian estos carácteres /////////////////////
const char TECLA_DELANTE           ='F'; // Definición de la tecla DELANTE. Cada tecla tiene un código diferente.
const char TECLA_DETRAS            ='B'; // Definición de la tecla DETRAS. Cada tecla tiene un código diferente.    
const char TECLA_IZQUIERDA         ='L';
const char TECLA_DERECHA           ='R';    
const char TECLA_DELANTE_IZQUIERDA ='G';
const char TECLA_DELANTE_DERECHA   ='I';
const char TECLA_DETRAS_IZQUIERDA  ='H';
const char TECLA_DETRAS_DERECHA    ='J';
const char TECLA_STOP              ='S';
const char TECLA_LUZ_DELANTERA     ='W';
const char TECLA_NO_LUZ_DELANTERA  ='w';
const char TECLA_LUZ_TRASERA       ='U';
const char TECLA_NO_LUZ_TRASERA    ='u';
const char TECLA_BOCINA            ='V';
const char TECLA_NO_BOCINA         ='v';
const char TECLA_TRIANGULO         ='X';
const char TECLA_NO_TRIANGULO      ='x';
const char SPEED_0                 ='0';
const char SPEED_1                 ='1';
const char SPEED_2                 ='2';
const char SPEED_3                 ='3';
const char SPEED_4                 ='4';
const char SPEED_5                 ='5';
const char SPEED_6                 ='6';
const char SPEED_7                 ='7';
const char SPEED_8                 ='8';
const char SPEED_9                 ='9';
const char SPEED_10                ='q';
const char TECLA_PARAR_TODO        ='D';
//// Declaración de las variables ///////////////////////////////////////////////////////////////
Servo servo_derecho_delantero; int calibracion_dd = 0; // Declaración de los servos y su calibración inicial.
Servo servo_izquierdo_delantero; int calibracion_id = 0;
Servo servo_derecho_trasero; int calibracion_dt = 0;
Servo servo_izquierdo_trasero; int calibracion_it = 0;
// Variables que almacenan los valores actuales de velocidad, giro tracción del robot. Valores iniciales
int v_d_a = 0;       // velocida_derecha_actual
int v_i_a = 0;      // velocida_izquierda_actual
int a_r_d_d_a = 90; // angulo_rueda_derecha_delantera_actual
int a_r_i_d_a = 90; // angulo_rueda_izquierda_delantera_actual
int a_r_d_t_a = 90; // angulo_rueda_derecha_trasera_actual
int a_r_i_t_a = 90; // angulo_rueda_izquierda_trasera_actual
int traccion_actual = 0;
//// Variables del controlador de los 4 motores ///////////////////////////////////////////////
int ENA=5;  //connected to Arduino's port 5 (output pwm)
int IN1=2;  //connected to Arduino's port 2
int IN2=8;  //connected to Arduino's port 8 (ojo que originariamente era la salida 3.
int ENB=6;  //connected to Arduino's port 6(output pwm)
int IN3=4;  //connected to Arduino's port 4
int IN4=7; //connected to Arduino's port 7
//// Configuración de Arduino ///////////////////////////////////////////////////////////////////
void setup(){
   Serial.begin(9600);             // Velocidad de conexión entre el PC y el Arduino. Se ha elegido esta velocidad por que sino crea interferencia con los servos.
   Serial.println("Serial ready"); // Se indica en el puerto serie del ordenado que todo esta bien.
   blue.begin(9600);               // Iniciamos el puerto serie a una velocidad de transmisión de 9600 Baudios.
//// Configuración de los 4 servos //////////////////////////////////////////////////////////////
   servo_derecho_delantero.attach(11,625,2360); delay(100);
   servo_izquierdo_delantero.attach(10,625,2360);delay(100);
   servo_derecho_trasero.attach(9,625,2360);delay(100);
   servo_izquierdo_trasero.attach(3,625,2360);delay(100);
   recto();
//// Configuración de los pines de la placa KEYES L298N.////////////////////////////////////////
   pinMode(ENA,OUTPUT); // Configuración de las salidas
   pinMode(ENB,OUTPUT);
   pinMode(IN1,OUTPUT);
   pinMode(IN2,OUTPUT);
   pinMode(IN3,OUTPUT);
   pinMode(IN4,OUTPUT);
   delay(500);}
//// Inicio del programa //////////////////////////////////////////////////////////////////////
void loop(){
  if (blue.available()){ // Si el bluetooth del móbil envia un valor.
    mostrarTecla();}}
//// Fin del programa //////////////////////////////////////////////////////////////////////////
//// Función que frena los motores /////////////////////////////////////////////////////////////
void frenar() {
  digitalWrite(ENA,LOW); //Para el motor A
  digitalWrite(ENB,LOW);} //Para el motor B
////Función ir recto /////////////////////////////////////////////////////
void recto(){
  desplazar(0,0,90,90,90,90,0);}
//// Función desplazamiento del robot ///////////////////////////////////////////////////////////////////////////////////
void desplazar(int velocida_derecha,int velocida_izquierda,int angulo_rueda_derecha_delantera,int angulo_rueda_izquierda_delantera,int angulo_rueda_derecha_trasera,int angulo_rueda_izquierda_trasera,int traccion) {
  boolean giro_derecho;    // Variable que define el sentido de giro de los motores
  boolean giro_izquierdo;  // Variable que define el sentido de giro de los motores
  // Variables que almacenan los valores entrantes actuales de velocidad, giro y tracción.
  v_d_a = velocida_derecha;
  v_i_a = velocida_izquierda;
  a_r_d_d_a = angulo_rueda_derecha_delantera;
  a_r_i_d_a = angulo_rueda_izquierda_delantera;
  a_r_d_t_a = angulo_rueda_derecha_trasera;
  a_r_i_t_a = angulo_rueda_izquierda_trasera;
  traccion_actual = traccion;
  // Configura el sentido de la marcha //////////////////////////////////////////////////////////////////////////7
  if (traccion == 0){ // Tracción hacia delante
    giro_derecho = HIGH;
    giro_izquierdo = LOW;}
  if (traccion == 1){ // Tracción hacia atras
    giro_derecho =  LOW;
    giro_izquierdo =  HIGH;}
  if (traccion == 2){ // Tracción hacia la derecha ROTAR
    giro_derecho = LOW;
    giro_izquierdo = LOW;}
  if (traccion == 3){ // Tracción hacia la izquierda ROTAR
    giro_derecho = HIGH;
    giro_izquierdo = HIGH;}
//// Activa el Motor A //////////////////////////////////////////////////////////////////////////////
  digitalWrite(IN1,giro_derecho); // IN1 y IN2 Configuran la dirección de giro del motor A. Se tienen que cambiar "invertir" los dos valores HIGH y LOW para invertir el giro.
  digitalWrite(IN2,!giro_derecho);
  analogWrite(ENA,velocida_derecha);   // Inicia la marcha del motor A
//// Activa el Motor B //////////////////////////////////////////////////////////////////////////////
  digitalWrite(IN3,giro_izquierdo); // IN3 y IN4 Configuran la dirección de giro del motor B. Se tienen que cambiar "invertir" los dos valores HIGH y LOW para invertir el giro.
  digitalWrite(IN4,!giro_izquierdo);
  analogWrite(ENB,velocida_izquierda);   // Inicia la marcha del motor B
//// Giro de la dirección ////////////////////////////////////////////////////////////////////
  if (velocida_izquierda != 0 || velocida_derecha != 0){
    delay(175); }// Espera a que el robot se ponga en movimiento. El coeficiente de rozamiento dinámico es inferior al coeficiente de rozamiento estàtico. Los servos consumen menos energia.
  delay(20);
  servo_derecho_delantero.write(angulo_rueda_derecha_delantera + calibracion_dd);
  //servo_derecho_delantero.writeMicroseconds(map(angulo_rueda_derecha_delantera + calibracion_dd, 0, 180,625,2370));  // Estos valores son para el servo ES 3001. Giro de la rueda derecha delantera
  delay(20); // Sirve para que los servos no se pongan en funcionamiento todos a la misma vez.
  servo_izquierdo_delantero.write(angulo_rueda_izquierda_delantera + calibracion_id);
  //servo_izquierdo_delantero.writeMicroseconds(map(angulo_rueda_izquierda_delantera + calibracion_id, 0, 180,625,2370));
  delay(20);
  servo_derecho_trasero.write(angulo_rueda_derecha_trasera + calibracion_dt);
  //servo_derecho_trasero.writeMicroseconds(map(angulo_rueda_derecha_trasera + calibracion_dt, 0, 180,625,2370));
  delay(20);
  servo_izquierdo_trasero.write(angulo_rueda_izquierda_trasera + calibracion_it);}
  //servo_izquierdo_trasero.writeMicroseconds(map(angulo_rueda_izquierda_trasera + calibracion_it, 0, 180,625,2370));}
//// Función del mando a distancia PHILIPS ////////////////////////
void mostrarTecla (){
        caracter = blue.read(); // Variable que almacena el valor entrante del Bluetooth del móbil.
        switch (caracter) {                                    // Llega el valor del  y lo compara con el "case" que corresponda. Y hace la sentencia del "case"
          case TECLA_DELANTE           :desplazar(v_d_a,v_i_a,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,0);mostra_valor();break;  // Caso para la tecla DELANTE
          case TECLA_DETRAS            :desplazar(v_d_a,v_i_a,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,1);mostra_valor();break;
          case TECLA_IZQUIERDA         :desplazar(v_d_a,v_i_a,a_r_d_d_a-4,a_r_i_d_a-4,a_r_d_t_a+4,a_r_i_t_a+4,traccion_actual);mostra_valor();break;
          case TECLA_DERECHA           :desplazar(v_d_a,v_i_a,a_r_d_d_a+4,a_r_i_d_a+4,a_r_d_t_a-4,a_r_i_t_a-4,traccion_actual);mostra_valor();break;  
          case TECLA_DELANTE_IZQUIERDA :mostra_valor();break;
          case TECLA_DELANTE_DERECHA   :mostra_valor();break;
          case TECLA_DETRAS_IZQUIERDA  :mostra_valor();break;
          case TECLA_DETRAS_DERECHA    :mostra_valor();break;
          case TECLA_STOP              :mostra_valor();break;
          case TECLA_LUZ_DELANTERA     :desplazar(0,0,90,90,90,90,0);mostra_valor();break;
          case TECLA_NO_LUZ_DELANTERA  :mostra_valor();break;
          case TECLA_LUZ_TRASERA       :mostra_valor();break;
          case TECLA_NO_LUZ_TRASERA    :mostra_valor();break;
          case TECLA_BOCINA            :recto();desplazar(155,155,0,0,0,0,0);mostra_valor();break;
          case TECLA_NO_BOCINA         :desplazar(155,155,180,180,180,180,0);mostra_valor();break;
          case TECLA_TRIANGULO         :recto();desplazar(150,150,49.5,130.5,130.5,49.5,2);mostra_valor();break;
          case TECLA_NO_TRIANGULO      :recto();desplazar(150,150,49.5,130.5,130.5,49.5,3);mostra_valor();break;
          case SPEED_0                 :desplazar(0,0,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case SPEED_1                 :desplazar(25,25,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case SPEED_2                 :desplazar(51,51,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case SPEED_3                 :desplazar(76,76,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case SPEED_4                 :desplazar(102,102,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case SPEED_5                 :desplazar(127,127,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case SPEED_6                 :desplazar(153,153,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case SPEED_7                 :desplazar(178,178,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case SPEED_8                 :desplazar(204,204,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case SPEED_9                 :desplazar(229,229,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case SPEED_10                :desplazar(255,255,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,traccion_actual);mostra_valor();break;
          case TECLA_PARAR_TODO        :mostra_valor();break; }}
///// Fin de las funciones ////////////////////////////////////////////////////////////////////////////////
//// Función que muestra el valor que envia el móvil ///////////////////////////////////////////////////////////////////////////////////
void mostra_valor() {
   Serial.print(caracter);Serial.print("\n");}

Esto es todo amigos, espero que hayan disfrutado. Nos vemos en otro tutorial.

5 comentarios :

  1. es copiar y pegar al programa?

    ResponderEliminar
  2. En teoria sí. Pero si marca algun error tendrás que verificarlo. Ya que como el IDE de Arduino lo estan actualizando continuamente a veces dar algun error.

    ResponderEliminar
  3. Este programa es valido para el robot Andromina ON ROAD solo. Si lo quieres para otro robot lo tendrás que aptar.

    ResponderEliminar
  4. Esto mismo lo puedo controlar con Bluetooht serial controller?

    ResponderEliminar
    Respuestas
    1. Si que se puede controlar con el programa "Bluetooht serial controller". No creo que haya ningún problema.

      Eliminar

Google analytics