Cambiamos en el mando los códigos, para que cuando pulsemos los diferentes números del mando infrarrojo, el arduino realice las diferentes funciones en base al código programado.
El código es el siguiente:
#include <IRremote.h> // Librería versión 2.2.3 para el mando de infrarrojos
#include <Servo.h> // Librería para el servomotor
Servo myservo; // Declara variable para el servo
int minAngle = 700;
int maxAngle = 2400;
typedef unsigned char u8;
#define F 16736925 // Marcha hacia adelante
#define B 16754775 // Marcha atrás
#define L 16720605 // Izquierda
#define R 16761405 // Derecha
#define S 16712445 // Parada
#define UNKNOWN_F 5316027 // Marcha hacia adelante relacionada con F
#define UNKNOWN_B 2747854299 // Marcha atrás relacionada con B
#define UNKNOWN_L 1386468383 // Izquierda relacionada con L
#define UNKNOWN_R 553536955 // Derecha relacionada con R
#define UNKNOWN_S 3622325019 // Parada relacionada con S
#define KEY1 16738455 // Código para tecla 1
#define KEY2 16750695 // Código para tecla 2
#define KEY3 16756815 // Código para tecla 3
#define KEY4 16724175 // Código para tecla 4
En esta primera parte del código importamos las librerías para el mando infrarrojo y el servomotor. Definimos las variables constantes de tipo numérico y las de cada tecla del mando con su código correspondiente.
#define KEY5 16718055 // Código para tecla 5
#define KEY6 16743045 // Código para tecla 6
#define KEY7 16716015 // Código para tecla 7
#define KEY8 16726215 // Código para tecla 8
#define KEY9 16734885 // Código para tecla 9
#define KEY0 16730805 // Código para tecla 0
#define KEY_STAR 16728765 // Código para tecla Asterisco
#define KEY_HASH 16732845 // Código para tecla Almohadilla
#define RECV_PIN 12 // Recibe información en el pin 12
/*define los pines activos de salida*/
#define ENA 5 // Velocidad Rueda izquierda por ciclos
#define ENB 6 // Velocidad Rueda derecha por ciclos
/*define los pines lógicos de salida*/
#define IN1 7 // Rueda izquierda hacia delante
#define IN2 8 // Rueda izquierda hacia atrás
#define IN3 9 // Rueda derecha hacia atrás
#define IN4 11 // Rueda derecha hacia delante
#define carSpeed 250 // Velocidad inicial del coche de 0 a 255
Continuamos con los pines activos y lógicos de salida e indicamos la velocidad inicial del coche.
/*Instrucciones para el recibimiento de los pintes a través del infrarrojo*/
IRrecv irrecv(RECV_PIN); // Pin que recibe el infrarrojo
decode_results results; // Decodificación de los resultados obtenidos
unsigned long val; // Variable larga no asignada para los posteriores resultados
unsigned long preMillis; // Variable larga no asignada de medición de tiempo
Declaramos las instrucciones de recepción y decodificación de los resultados con un intervalo de tiempo, y el código realiza la medición.
void forward(){ // Función marcha delante
digitalWrite(ENA,HIGH); // Pin ENA activo
digitalWrite(ENB,HIGH); // Pin ENB activo
digitalWrite(IN1,HIGH); // Rueda izquierda hacia delante activa
digitalWrite(IN2,LOW); // Rueda izquierda hacia atrás inactiva
digitalWrite(IN3,LOW); // Rueda derecha hacia atrás inactiva
digitalWrite(IN4,HIGH); // Rueda derecha hacia delante activa
Serial.println("go forward!"); // Imprime por monitor serie
}
void back(){ // Función marcha atrás
digitalWrite(ENA,HIGH); // Pin ENA activo
digitalWrite(ENB,HIGH); // Pin ENB activo
digitalWrite(IN1,LOW); // Rueda izquierda hacia delante activa
digitalWrite(IN2,HIGH); // Rueda izquierda hacia atrás activa
digitalWrite(IN3,HIGH); // Rueda derecha hacia atrás activa
digitalWrite(IN4,LOW); // Rueda derecha hacia atrás inactiva
Serial.println("go back!"); // Imprime por pantalla
}
void left(){ // Igual que arriba
analogWrite(ENA,carSpeed); // Variable carSpeed para dar velocidad al giro
analogWrite(ENB,carSpeed);
digitalWrite(IN1,LOW);
A partir de aquí, indicamos las funciones que el coche tiene que realizar como marcha hacia delante definimos los pines activos y le indicamos que rueda con high y low tiene que estar activa o inactiva.
digitalWrite(IN2,HIGH);
digitalWrite(IN3,LOW);
digitalWrite(IN4,HIGH);
Serial.println("go left!");
}
void right(){ //Igual que arriba pero derecha
analogWrite(ENA,carSpeed); // Variable carSpeed para dar velocidad al giro
analogWrite(ENB,carSpeed);
digitalWrite(IN1,HIGH);
digitalWrite(IN2,LOW);
digitalWrite(IN3,HIGH);
digitalWrite(IN4,LOW);
Serial.println("go right!");
}
void stop(){ // Función para llamar a la parada del coche
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
Serial.println("STOP!");
}
También, introducimos la variable carSpeed para darle velocidad al giro del coche, y la variable Stop para llamar a la parada del coche.
void forward(u8 car_speed) // Mismas funciones que las anterior pero con variables distintas para agregar una velocidad distinta a la definida
{
analogWrite(ENA, car_speed);
analogWrite(ENB, car_speed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void back(u8 velocidad)
{
analogWrite(ENA, 100);
analogWrite(ENB, 100);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
void left(u8 velocidad)
{
analogWrite(ENA, 250);
analogWrite(ENB, 250);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
}
void right(u8 velocidad)
{
analogWrite(ENA, 250);
analogWrite(ENB, 250);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
}
Usamos las mismas funciones anteriores pero con distintas variables para agregar una velocidad distinta, en este caso más lenta, a la definida del coche.
void setup() { // Primera función que hace la placa al inciar
Serial.begin(9600); // Velocidad de transmisión de 9600 baudios para conectar con el bluetooth e infrarrojos
pinMode(IN1,OUTPUT); // Declara los pines output de salida y los input de entrada
pinMode(IN2,OUTPUT); // Los ouput están en la tarjeta de expansión y los input en la propia placa
pinMode(IN3,OUTPUT);
pinMode(IN4,OUTPUT);
pinMode(ENA,OUTPUT);
pinMode(ENB,OUTPUT);
pinMode(10,INPUT);
pinMode(4,INPUT);
pinMode(2,INPUT);
stop(); // Llamada para parar el proceso
irrecv.enableIRIn(); // Activa el recibimiento de infrarrojos
myservo.attach(3,700,2400); // Pin 3 se ocupa de mover el servo entre los dos valores de ancho de pulso
myservo.write(90); // Define al servo en 90º
}
void loop() { // Función de repetición
if(irrecv.decode(&results)){ // Función de decodificación de resultados
preMillis = millis(); // Variable de tiempo
val = results.value; // Almacena los datos en variable val
Indicamos la velocidad de transmisión de 9600 baudios para conectar el infrarrojos, declaramos los pines output de salida en la tarjeta de expansión y los input de entrada en la propia placa.El pin 3 se ocupará de mover el servo entre los valores de ancho de pulso y definir el servo en 90 grados.
Serial.println(val); // Imprime los resultados en pantalla
irrecv.resume(); // Resumen los códigos
switch(val){ // Función en relación a la variable val
case KEY_STAR: // En caso de tecla asterisco mueve el servo en 3 ángulos
myservo.write(10);
delay (500);
myservo.write(90);
delay (500);
myservo.write(180);
delay (500);
myservo.write(90);
delay (500);break; // Rompe la función con un break tras un delay
case F: // En caso de F avanza
case UNKNOWN_F: forward();
delay (1000);break; // Rompe la función
case B: // En caso de B avanza hacia atrás
case UNKNOWN_B: back();
delay (1000);break; // Rompe la función tras realizar el movimiento
case L: // En caso de L gira a la izquierda
case UNKNOWN_L: left();
delay (1000);break; // Rompre la función
Con Serial.println
imprimimos los resultados por pantalla. La tecla del mando infrarrojo * (asterisco) mueve el servo en tres ángulos, el valor de case aplica valores como el de avanzar, retroceder, girar hacia la derecha, hacia la izquierda.
case R: // En caso de R gira a la derecha
case UNKNOWN_R: right();
delay (1000);break; // Rompre la función
case S: // En caso de S para el moviento
case UNKNOWN_S: stop();
delay (1000);break; // Tras la parada rompe la función
case KEY_HASH: // En caso de tecla almohadilla
forward(); //Hace forma de L
delay(2000);
left();
delay(450);
forward(); //Fin forma de L
delay(2000);
stop(); //Llama a la parada
delay(1000);break; //Rompe la función
case KEY3: //En caso de tecla 3 hace forma de K
left();
delay(450);
forward();
delay(2000);
back();
delay(1000);
En esta parte le indicamos que haga forma de L y de K.
El Delay es una función que hace que el procesador espere, esta función tiene un parámetro de entrada del tipo entero, que es la espera en milisegundos.
case R: // En caso de R gira a la derecha
case UNKNOWN_R: right();
delay (1000);break; // Rompre la función
case S: // En caso de S para el moviento
case UNKNOWN_S: stop();
delay (1000);break; // Tras la parada rompe la función
case KEY_HASH: // En caso de tecla almohadilla
forward(); //Hace forma de L
delay(2000);
left();
delay(450);
forward(); //Fin forma de L
delay(2000);
stop(); //Llama a la parada
delay(1000);break; //Rompe la función
case KEY3: //En caso de tecla 3 hace forma de K
left();
delay(450);
forward();
delay(2000);
back();
delay(1000);
Con esta última parte, llamamos a la parada de fin de las letras con break. En caso de la tecla 4 con el loop giramos el coche a la derecha y con la tecla 5 hacia la izquierda.
else{ //Si no mide el tiempo en espera de llamada
if(millis() - preMillis > 500){
stop();
preMillis = millis();
}
}
}
Video de demostración: Infrarrojos 1 e infrarrojos 2
Este proyecto ha sido realizado basándose en el código por defecto de Smart Robot Car Kit 3.0 Plus.
Realizado por: Kevin Maldonado Pico y Laura Tovar Pérez