En esta entrada muestro el Andromina robot controlado a través de un mando a distancia de una televisión PHILIPS. El robot tiene la configuración básica, una placa Arduino UNO con una "shield" modificada por nosotros con un regulador de voltaje a 5v, una placa de motor y un receptor de IR. El programa que controla el robot ya es un poco más complejo y podríamos añadir un sin fin de maniobras (ver programa más abajo).
En este montaje hemos usado 6 pilas de 1,2v que nos proporcionan un voltaje de 7.2v. El robot funciona correctamente, pero se nota que estas pilas son un poco justas para este robot e incrementan el peso del robot. Se ha substituido la bateria por una de 12,6v y 9800mAh.de Ion Litio, que esta más acorde a esta aplicación. El robot funciona a la perfección y ha aumentado su velocidad máxima al trabajar ahora 12v.
/* Programa para Andromina Robot 4x4 con 4 ruedas direccionales con 4 servos + Arduino Uno + una "proshield" KEYES 5.1 + motor shield KEYES L298N. (17-04-2013).
Vídeo que muestra algunos movimientos del robot Andromina OFF ROAD.
En el programa hemos configurado botones predefinidos con una maniobra o botones por ejemplo para acelerar o girar el robot.Andromina robot v1.2. y el mando a distancia. |
Disposición de las pilas. |
Programa para probar el movimiento del Andromina robot y el mando a distancia PHILIPS. El programa funciona BIEN.
Los servo del robot tiene unos pulsos diferentes que los servos estandares.
Autor: Jordi T. C.
Para que no haya interferencias "Ruido" se tiene que poner un condensador cerámico (0,1uf 50v) soldado en los dos bornes de cada motor.
Para que los motores arranque mejor también es bueno colocar un gran codensador electrolitico (16V) en la entrada de la placa del motor.
*/// Librerías /////////////////////////////////////////////////////////////////////////////////
#include <Servo.h> // Carga la libreria de los servos
#include <IRremote.h> // Carga la libreria del mando a distancia
//// Declaración de constantes, teclas del mando a distancia Philips /////////////////////
#define TECLA_ON_1 0XC // Definición de la tecla ON. Cada tecla tiene dos códigos diferentes.
#define TECLA_ON_2 0X80C //
#define TECLA_ROJA_1 0X4B995E59
#define TECLA_ROJA_2 0X1C102884
#define TECLA_VERDE_1 0XE050BDE6
#define TECLA_VERDE_2 0XEF4EDF53
#define TECLA_AMARILLA_1 0XDF50BC53
#define TECLA_AMARILLA_2 0XF04EE0E6
#define TECLA_GRIS_1 0X8533B77
#define TECLA_GRIS_2 0X5F564B6A
#define TECLA_MUSICA_1 0X14
#define TECLA_MUSICA_2 0X814
#define TECLA_RADIO_1 0XA4E66026
#define TECLA_RADIO_2 0X9CEDF1F
#define TECLA_PANTALLA_1 0X15
#define TECLA_PANTALLA_2 0X815
#define TECLA_i_1 0XF
#define TECLA_i_2 0X80F
#define TECLA_AUGMENTAR_1 0X2B
#define TECLA_AUGMENTAR_2 0X82
#define TECLA_REDUCIR_1 0X29
#define TECLA_REDUCIR_2 0X829
#define TECLA_PREGUNTA_1 0X2C
#define TECLA_PREGUNTA_2 0X82C
#define TECLA_MENU_1 0XD9F9700B
#define TECLA_MENU_2 0XBFB8F2FE
#define TECLA_RALLAS_1 0X3C
#define TECLA_RALLAS_2 0X83C
#define TECLA_ARRIBA_1 0XE5139CA7
#define TECLA_ARRIBA_2 0XAC516266
#define TECLA_ABAJO_1 0XE4139B12
#define TECLA_ABAJO_2 0XAD5163FB
#define TECLA_IZQUIERDA_1 0XDB9D3097
#define TECLA_IZQUIERDA_2 0XBE15326E
#define TECLA_DERECHA_1 0X9FA96F
#define TECLA_DERECHA_2 0X9912B99A
#define TECLA_VOL_MENOS_1 0X11
#define TECLA_VOL_MENOS_2 0X811
#define TECLA_VOL_MAS_1 0X10
#define TECLA_VOL_MAS_2 0X810
#define TECLA_P_MENOS_1 0X21
#define TECLA_P_MENOS_2 0X821
#define TECLA_P_MAS_1 0X20
#define TECLA_P_MAS_2 0X820
#define TECLA_UNO_1 0X1
#define TECLA_UNO_2 0X801
#define TECLA_DOS_1 0X2
#define TECLA_DOS_2 0X802
#define TECLA_TRES_1 0X3
#define TECLA_TRES_2 0X803
#define TECLA_CUATRO_1 0X4
#define TECLA_CUATRO_2 0X804
#define TECLA_CINCO_1 0X5
#define TECLA_CINCO_2 0X805
#define TECLA_SEIS_1 0X6
#define TECLA_SEIS_2 0X806
#define TECLA_SIETE_1 0X7
#define TECLA_SIETE_2 0X807
#define TECLA_OCHO_1 0X8
#define TECLA_OCHO_2 0X808
#define TECLA_NUEVE_1 0X9
#define TECLA_NUEVE_2 0X809
#define TECLA_CERO_1 0X0
#define TECLA_CERO_2 0X800
const int receptorPin_12 = 12; // Declaración del pin donde se va a recibir la señal del mando a distancia, PIN Nº12
IRrecv irrecv(receptorPin_12); // Crea un objeto para el mando a distancia llamado IRRECV
decode_results results; // Declara una variable que almacena los resultados del receptor del mando a distancia
//// Declaración de las variables ///////////////////////////////////////////////////////////////
Servo servo_derecho_delantero; int calibracion_dd = -1; // Declaración de los servos y su calibración inicial.
Servo servo_izquierdo_delantero; int calibracion_id = -3;
Servo servo_derecho_trasero; int calibracion_dt = -2;
Servo servo_izquierdo_trasero; int calibracion_it = 2;
// Variables que almacenan los valores actuales de velocidad, giro tracción del robot. Valores iniciales
int v_d_a = 0; // velocidad_derecha_actual
int v_i_a = 0; // velocidad_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(115200); // Velocidad de conexión entre el PC y el Arduino
irrecv.enableIRIn(); // Inicializa el receptor del mando a distancia
//// Configuración de los 4 servos //////////////////////////////////////////////////////////////
servo_derecho_delantero.attach(11); delay(100);
servo_izquierdo_delantero.attach(10);delay(100);
servo_derecho_trasero.attach(9);delay(100);
servo_izquierdo_trasero.attach(3);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 (irrecv.decode(&results)) {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 //////////////////////////////////////////////////////////////////////////
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 ////////////////////////////////////////////////////////////////////
delay(150); // 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.
servo_derecho_delantero.writeMicroseconds(map(angulo_rueda_derecha_delantera + calibracion_dd,-5, 185,455,2144)); // (0,180,500,2100) // Giro de la rueda derecha delantera
delay(50); // Sirve para que los servos no se pongan en funcionamiento todos a la misma vez.
servo_izquierdo_delantero.writeMicroseconds(map(angulo_rueda_izquierda_delantera + calibracion_id,-5, 185,455,2144));
delay(50);
servo_derecho_trasero.writeMicroseconds(map(angulo_rueda_derecha_trasera + calibracion_dt,-5, 185,455,2144));
delay(50);
servo_izquierdo_trasero.writeMicroseconds(map(angulo_rueda_izquierda_trasera + calibracion_it,-5, 185,455,2144));}
//// Función del mando a distancia PHILIPS ////////////////////////
void mostrarTecla (){
switch (results.value) { // Llega el valor del mando de infrarrojos y lo compara con el "case" que corresponda. Y hace la sentencia del "case"
case TECLA_ON_1: desplazar(0,0,90,90,90,90,0);break; // Caso para la tecla ON
case TECLA_ON_2 : desplazar(0,0,90,90,90,90,0);break;
case TECLA_ROJA_1: desplazar(v_d_a,v_i_a,a_r_d_d_a-2,a_r_i_d_a-2,a_r_d_t_a-2,a_r_i_t_a-2,traccion_actual); break;
case TECLA_ROJA_2: desplazar(v_d_a,v_i_a,a_r_d_d_a-2,a_r_i_d_a-2,a_r_d_t_a-2,a_r_i_t_a-2,traccion_actual); break;
case TECLA_VERDE_1 : desplazar(v_d_a,v_i_a,a_r_d_d_a-2,a_r_i_d_a 2,a_r_d_t_a+2,a_r_i_t_a+2,traccion_actual); break;
case TECLA_VERDE_2 : desplazar(v_d_a,v_i_a,a_r_d_d_a-2,a_r_i_d_a-2,a_r_d_t_a+2,a_r_i_t_a+2,traccion_actual); break;
case TECLA_AMARILLA_1 : desplazar(v_d_a,v_i_a,a_r_d_d_a+2,a_r_i_d_a+2,a_r_d_t_a-2,a_r_i_t_a-2,traccion_actual); break;
case TECLA_AMARILLA_2 : desplazar(v_d_a,v_i_a,a_r_d_d_a+2,a_r_i_d_a+2,a_r_d_t_a-2,a_r_i_t_a-2,traccion_actual); break;
case TECLA_GRIS_1 : desplazar(v_d_a,v_i_a,a_r_d_d_a+2,a_r_i_d_a+2,a_r_d_t_a+2,a_r_i_t_a+2,traccion_actual); break;
case TECLA_GRIS_2 : desplazar(v_d_a,v_i_a,a_r_d_d_a+2,a_r_i_d_a+2,a_r_d_t_a+2,a_r_i_t_a+2,traccion_actual); break;
case TECLA_i_1 : desplazar(255,255,90,90,90,90,2);break;
case TECLA_i_2 : desplazar(255,255,90,90,90,90,2);break;
case TECLA_AUGMENTAR_1 : desplazar(155,155,45,45,45,45,0);break;
case TECLA_AUGMENTAR_2 : desplazar(155,155,45,45,45,45,0);break;
case TECLA_REDUCIR_1 : desplazar(155,155,135,135,135,135,0);break;
case TECLA_REDUCIR_2 : desplazar(155,155,135,135,135,135,0);break;
case TECLA_PREGUNTA_1 : desplazar(255,255,90,90,90,90,3);break;
case TECLA_PREGUNTA_2 : desplazar(255,255,90,90,90,90,3);break;
case TECLA_MUSICA_1 : desplazar(v_d_a,v_i_a,3,0,3,16,0);break;
case TECLA_MUSICA_2 : desplazar(v_d_a,v_i_a,3,0,3,16,0);break;
case TECLA_RADIO_1 : desplazar(v_d_a,v_i_a,90,90,90,90,0);break;
case TECLA_RADIO_2 : desplazar(v_d_a,v_i_a,90,90,90,90,0);break;
case TECLA_PANTALLA_1 : desplazar(v_d_a,v_i_a,200,200,174,160,0);break;
case TECLA_PANTALLA_2 : desplazar(v_d_a,v_i_a,200,200,174,160,0);break;
case TECLA_MENU_1 : desplazar(v_d_a,v_i_a,a_r_d_d_a-5,a_r_i_d_a-5,a_r_d_t_a,a_r_i_t_a,traccion_actual); break;
case TECLA_MENU_2 : desplazar(v_d_a,v_i_a,a_r_d_d_a-5,a_r_i_d_a-5,a_r_d_t_a,a_r_i_t_a,traccion_actual); break;
case TECLA_RALLAS_1 : desplazar(v_d_a,v_i_a,a_r_d_d_a+5,a_r_i_d_a+5,a_r_d_t_a,a_r_i_t_a,traccion_actual); break;
case TECLA_RALLAS_2 : desplazar(v_d_a,v_i_a,a_r_d_d_a+5,a_r_i_d_a+5,a_r_d_t_a,a_r_i_t_a,traccion_actual); break;
case TECLA_ARRIBA_1 : desplazar(155,155,90,90,90,90,0); break;
case TECLA_ARRIBA_2 : desplazar(155,155,90,90,90,90,0); break;
case TECLA_ABAJO_1 : desplazar(155,155,90,90,90,90,1); break;
case TECLA_ABAJO_2 : desplazar(155,155,90,90,90,90,1); break;
case TECLA_IZQUIERDA_1 : desplazar(155,155,0,0,0,0,0); break;
case TECLA_IZQUIERDA_2 : desplazar(155,155,0,0,0,0,0); break;
case TECLA_DERECHA_1 : desplazar(155,155,180,180,180,180,0); break;
case TECLA_DERECHA_2 : desplazar(155,155,180,180,180,180,0); break;
case TECLA_VOL_MENOS_1 : desplazar(v_d_a-10,v_i_a-10,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,0); break;
case TECLA_VOL_MENOS_2 : desplazar(v_d_a-10,v_i_a-10,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,0); break;
case TECLA_VOL_MAS_1 : desplazar(v_d_a+10,v_i_a+10,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,0); break;
case TECLA_VOL_MAS_2 : desplazar(v_d_a+10,v_i_a+10,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,0); break;
case TECLA_P_MENOS_1 : desplazar(v_d_a-10,v_i_a-10,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,1); break;
case TECLA_P_MENOS_2 : desplazar(v_d_a-10,v_i_a-10,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,1); break;
case TECLA_P_MAS_1 : desplazar(v_d_a+10,v_i_a+10,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,1); break;
case TECLA_P_MAS_2 : desplazar(v_d_a+10,v_i_a+10,a_r_d_d_a,a_r_i_d_a,a_r_d_t_a,a_r_i_t_a,1); break;
case TECLA_UNO_1 : desplazar(68,150,124,105,56,75,0);break;
case TECLA_UNO_2 : desplazar(68,150,124,105,56,75,0);break;
case TECLA_DOS_1 : desplazar(150,68,75,56,105,124,0);break;
case TECLA_DOS_2 : desplazar(150,68,75,56,105,124,0);break;
case TECLA_TRES_1 : desplazar(68,150,147.5,109,32.5,71.2,0);break;
case TECLA_TRES_2 : desplazar(68,150,147.5,109,32.5,71.2,0);break;
case TECLA_CUATRO_1 : desplazar(150,68,71.2,32.5,109,147.5,0);break;
case TECLA_CUATRO_2 : desplazar(150,68,71.2,32.5,109,147.5,0);break;
case TECLA_CINCO_1 : Serial.print("TECLA CINCO_1 = ");Serial.println(TECLA_CINCO_1,HEX); break;
case TECLA_CINCO_2 : Serial.print("TECLA CINCO_2 = ");Serial.println(TECLA_CINCO_2,HEX); break;
case TECLA_SEIS_1 : Serial.print("TECLA SEIS_1 = ");Serial.println(TECLA_SEIS_1,HEX); break;
case TECLA_SEIS_2 : Serial.print("TECLA SEIS_2 = ");Serial.println(TECLA_SEIS_2,HEX); break;
case TECLA_SIETE_1 : Serial.print("TECLA SIETE_1 = ");Serial.println(TECLA_SIETE_1,HEX); break;
case TECLA_SIETE_2 : Serial.print("TECLA SIETE_2 = ");Serial.println(TECLA_SIETE_2,HEX); break;
case TECLA_OCHO_1 : Serial.print("TECLA OCHO_1 = ");Serial.println(TECLA_OCHO_1,HEX); break;
case TECLA_OCHO_2 : Serial.print("TECLA 0CHO_2 = ");Serial.println(TECLA_OCHO_2,HEX); break;
case TECLA_NUEVE_1:
case TECLA_NUEVE_2:
case TECLA_CERO_1:
case TECLA_CERO_2:
default : Serial.print("TECLA SENAL ERRONEA = ");Serial.println(results.value,HEX);break;} // Si no entiende la señal da señal erronea.
irrecv.resume();} // Inicializa la función para recivir el siguiente valor del mando a distancia.
///// Fin de las funciones ////////////////////////////////////////////////////////////////////////////////
Hola,
ResponderEliminarCambia esta linea que esta equivocada:
En este montaje hemos usado 12 pilas de 1,2v que nos proporcionan un voltaje de 7.2v.
Son 6 pilas en de 12 :-)
Saludos