Robot Arduino controlado por un mando a distancia de infrarrojos
| Actualizado:
Comentarios: 0
El objetivo de este proyecto es controlar el movimiento de un robot Arduino con un mando, a través de una señal de infrarrojo.
Utilizaremos cinco de los botones del mando para el control del robot, uno para avanzar, otro para retroceder, otro para que gire hacia la derecha, otro para girar a la izquierda y, por último, uno para parar.
El primer paso será hacer que se mueva el robot al recibir la señal del mando, le añadiremos unos LEDs para indicar si gira hacia la derecha o hacia la izquierda y, también, le pondremos un buzzer para indicarnos si hay obstáculos cerca. Para ello, utilizaremos un sensor de ultrasonidos (HC-SR04) que moveremos utilizando dos servos, creando un brazo móvil que nos hará un barrido de 180º de la zona frontal y que nos indicará si hay un obstáculo.
Contenido
Inicio del proyecto
Material necesario para el proyecto:
- Placa Arduino
- Controlador de motor L298N
- Shield V5.0 para Arduino
- Mando
- Chasis robot 2WD (normalmente viene con los dos motores, rueda loca y accesorios para montarlo)
- 2 motores reductores de velocidad TT de doble
- 2 ruedas
- Rueda loca
- Cables Dupont
- Módulo KY-022, receptor infrarrojo
- Interruptor
- Protoboard
- Tornillos y tuercas
En la primera parte del proyecto armamos el robot y conseguiremos que se mueva con la señal de infrarrojo que reciba. Lo primero es conocer las señales que emite el mando y otorgar un botón para cada movimiento. Para ello montamos el esquema N.º 1 que tenemos un poco más abajo.
¿Cómo podemos identificar el código de los botones del mando?
Utilizando el siguiente código veremos, a través del monitor serial, la señal de cada botón:
// libreria version 4.x
#include "IRremote.h"
#define IR_RECEIVE_PIN 2
void setup() {
Serial.begin(9600);
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // Iniciar
}
void loop() {
if (IrReceiver.decode()) {
uint16_t command = IrReceiver.decodedIRData.command;
Serial.println(command);
IrReceiver.resume(); // preparar para recibir el siguiente valor
}
}
Es importante fijarse en la versión de la librería IRremote.h instalada porque dependiendo de la versión, el código cambia. Fíjate en la siguiente imagen:
En la primera línea del código incluimos la librería e indicamos que el pin digital 2 es el que conectamos al pin de señal del módulo infrarrojo KY-022. En la función setup() inicializamos el infrarrojo y la función void() imprime la señal por monitor serial cuando la reciba.
Por el monitor serial podemos ver el resultado
Por lo tanto, la asignación de botones es:
- Botón 2: avanzar -> 24
- Botón 8: retroceder -> 74
- Botón 4: izquierda -> 8
- Botón 6: derecha -> 90
- Botón 9: parar -> 74
Esquema N.º 1: conexiones de Arduino con los motores, el controlador de motor L298N y el infrarrojo. En este caso el controlador lo alimentamos con una batería lipo, y la placa Arduino con una pila de 9V.
Como podemos ver en la imagen las conexiones entre el controlador L298N y Arduino son:
- ENA –> Pin 6. Debemos recordar que los pines ENA y ENB son los que controlan la velocidad de giro por lo tanto deben ir a un pin PWM, son los que permiten enviar valores entre 0 y 255.
- ENB –> Pin 5
- IN1 –> Pin 7
- IN2 –> Pin 8
- IN3 –> Pin 4
- IN4 –> Pin 3
Para el módulo de infrarrojo KY-022, el pin de señal irá al pin digital 2 de Arduino, el pin GND al correspondiente en el shield V5.0 y el del voltaje al suyo.
Los motores los conectamos al controlador L298N. El controlador lo alimentamos aparte de la placa Arduino y utilizamos un interruptor para poder desconectarlo independientemente de que Arduino esté funcionando. Tened en cuenta las conexiones GND, el controlador va conectado al cable negativo de la pila y al pin GND del Shield V5.0
Comenzamos con la programación:
// Motor A
int ENA = 6;
int IN1 = 7;
int IN2 = 8;
// Motor B
int ENB = 5;
int IN3 = 4;
int IN4 = 3;
int velocidad = 100;
String sentido = "p";
Indicamos las conexiones del controlador con la placa, creamos una variable "velocidad" de tipo entero con la que indicamos la velocidad que tendrá el robot, recordad que puede ser de 0 a 255. Tendremos una segunda variable "sentido" de tipo string para indicarnos el sentido del movimiento.
#include "IRremote.h" // libreria version 4.x
#define IR_RECEIVE_PIN 2 // el infrarrojo va al pin 2
Agregamos la biblioteca IRremote, versión 4.2 que es la que estamos utilizando, e indicamos el pin al que está conectado el infrarrojo
void setup() {
Serial.begin(9600);
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // iniciar infrarrojo
// motores
pinMode (ENA, OUTPUT);
pinMode (ENB, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (IN3, OUTPUT);
pinMode (IN4, OUTPUT);
}
En la función setup() iniciamos el infrarrojo e indicamos que los pines los vamos a utilizar como salida.
void loop() {
if (IrReceiver.decode()) {
uint16_t command = IrReceiver.decodedIRData.command;
switch (command) {
case 24:
Serial.println("avanzar");
sentido = 'a';
break;
case 8:
Serial.println("izquierda");
sentido = 'i';
break;
case 90:
Serial.println("derecha");
sentido = 'd';
break;
case 82:
Serial.println("retroceder");
sentido = 'r';
break;
case 74:
Serial.println("parar");
sentido = 'p';
break;
default:
Serial.println("indefinido");
}
IrReceiver.resume();
}
}
En el bucle loop(), comprobaremos si hemos presionado algun botón del mando y si es algún botón de los que utilizamos para que se mueva el robot. Tenemos un if que nos comprueba si llega alguna señal, si es así guardamos el dato en la variable "command", y seguidamente con un switch comprobamos, según su valor, lo que tiene que hacer, y nos lo mostrará por el monitor serial:
A continuación, creamos las funciones que van hacer que se mueva: avanzar(), derecha(), izquierda(), retroceder() y parar().
void avanzar (){
//Dirección motor A
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite (ENB, velocidad); //Velocidad motor B
}
void izquierda (){
//Dirección motor A
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
analogWrite (ENB, velocidad); //Velocidad motor B
}
void derecha (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, HIGH);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite (ENB, velocidad); //Velocidad motor B
}
void retroceder (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, HIGH);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
analogWrite (ENB, velocidad); //Velocidad motor B
}
void parar (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, LOW);
analogWrite (ENA, 0); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, LOW);
analogWrite (ENB, 0); //Velocidad motor B
}
El siguiente paso es crear la función que controlará hacia dónde se moverá el robot, la función mover() recibe una variable "sentido", que indica hacia dónde avanzará.
void mover(String sentido){
if(sentido == "a"){
Serial.println("avanzar");
avanzar();
}
if(sentido == "i"){
Serial.println("izquierda");
izquierda();
}
if(sentido == "d"){
Serial.println("derecha");
derecha();
}
if(sentido == "r"){
Serial.println("retroceder");
retroceder();
}
if(sentido == "p"){
Serial.println("parar");
parar();
}
}
Ya solo queda colocar la llamada a la función mover(), esta llamada se hace después de presionar un botón en el mando de infrarrojo, por lo tanto, irá dentro de la función loop() y al final del switch que comprueba qué botón hemos presionado:
mover(sentido);
Código completo:
// Motor A
int ENA = 6;
int IN1 = 7;
int IN2 = 8;
// Motor B
int ENB = 5;
int IN3 = 4;
int IN4 = 3;
int velocidad = 100;
String sentido = "p"; // inicialmente parado
#include "IRremote.h" // libreria version 4.x
#define IR_RECEIVE_PIN 2 // el infrarrojo va al pin 2
void setup() {
Serial.begin(9600);
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // iniciar infrarrojo
// motores
pinMode (ENA, OUTPUT);
pinMode (ENB, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (IN3, OUTPUT);
pinMode (IN4, OUTPUT);
}
void loop() {
if (IrReceiver.decode()) {
uint16_t command = IrReceiver.decodedIRData.command;
switch (command) {
case 24:
Serial.println("avanzar");
sentido = 'a';
break;
case 8:
Serial.println("izquierda");
sentido = 'i';
break;
case 90:
Serial.println("derecha");
sentido = 'd';
break;
case 82:
Serial.println("retroceder");
sentido = 'r';
break;
case 74:
Serial.println("parar");
sentido = 'p';
break;
default:
Serial.println("indefinido");
}
mover(sentido);
IrReceiver.resume();
}
}
void mover(String sentido){
if(sentido == "a"){
Serial.println("avanzar");
avanzar();
}
if(sentido == "i"){
Serial.println("izquierda");
izquierda();
}
if(sentido == "d"){
Serial.println("derecha");
derecha();
}
if(sentido == "r"){
Serial.println("retroceder");
retroceder();
}
if(sentido == "p"){
Serial.println("parar");
parar();
}
}
void avanzar (){
//Dirección motor A
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite (ENB, velocidad); //Velocidad motor B
}
void izquierda (){
//Dirección motor A
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
analogWrite (ENB, velocidad); //Velocidad motor B
}
void derecha (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, HIGH);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite (ENB, velocidad); //Velocidad motor B
}
void retroceder (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, HIGH);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
analogWrite (ENB, velocidad); //Velocidad motor B
}
void parar (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, LOW);
analogWrite (ENA, 0); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, LOW);
analogWrite (ENB, 0); //Velocidad motor B
}
Añadimos LEDs para indicar los giros
Una vez que el robot está funcionando perfectamente indicaremos con un LED rojo cuando gire hacia la izquierda y con un LED verde cuando gire a la derecha.
Material que necesitamos para añadir:
- 2 LEDs, uno rojo y otro verde
- 2 resistencias de 220 Ohm
- Cables Dupont
Nos fijamos en la siguiente imagen para conectar los LEDs:
Utilizamos una resistencia para cada LED, el LED rojo lo alimentamos a través del pin analógico A5 y el LED verde lo conectamos al pin analógico A4.
Para la programación tendremos en cuenta que los pines analógicos A4 y A5 los vamos a utilizar como salida, por lo tanto en la función setup() añadimos:
pinMode(A5, OUTPUT);
pinMode(A4, OUTPUT);
Falta indicar en qué momento estarán encendidos: cuando gira a la derecha, en la función derecha() indicamos que el LED verde debe estar encendido(HIGH) y el LED rojo apagado (LOW)
digitalWrite(A5, LOW);
digitalWrite(A4, HIGH);
Mientras que en la función izquierda() indicamos en HIGH el pin A5 y LOW el pin A4
digitalWrite(A5, HIGH);
digitalWrite(A4, LOW);
Para las funciones avanzar(), retroceder() y parar(), deben de estar apagados:
digitalWrite(A5, LOW);
digitalWrite(A4, HIGH);
Código completo con los LEDs incluidos, nos quedaría de la siguiente manera:
// Motor A
int ENA = 6;
int IN1 = 7;
int IN2 = 8;
// Motor B
int ENB = 5;
int IN3 = 4;
int IN4 = 3;
int velocidad = 100;
String sentido = "p"; // inicialmente parado
#include "IRremote.h" // libreria version 4.x
#define IR_RECEIVE_PIN 2 // el infrarrojo va al pin 2
void setup() {
Serial.begin(9600);
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // iniciar infrarrojo
// motores
pinMode (ENA, OUTPUT);
pinMode (ENB, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (IN3, OUTPUT);
pinMode (IN4, OUTPUT);
// LED
pinMode(A5, OUTPUT);
pinMode(A4, OUTPUT);
}
void loop() {
if (IrReceiver.decode()) {
uint16_t command = IrReceiver.decodedIRData.command;
switch (command) {
case 24:
Serial.println("avanzar");
sentido = 'a';
break;
case 8:
Serial.println("izquierda");
sentido = 'i';
break;
case 90:
Serial.println("derecha");
sentido = 'd';
break;
case 82:
Serial.println("retroceder");
sentido = 'r';
break;
case 74:
Serial.println("parar");
sentido = 'p';
break;
default:
Serial.println("indefinido");
}
mover(sentido);
IrReceiver.resume();
}
}
void mover(String sentido){
if(sentido == "a"){
Serial.println("avanzar");
avanzar();
}
if(sentido == "i"){
Serial.println("izquierda");
izquierda();
}
if(sentido == "d"){
Serial.println("derecha");
derecha();
}
if(sentido == "r"){
Serial.println("retroceder");
retroceder();
}
if(sentido == "p"){
Serial.println("parar");
parar();
}
}
void avanzar (){
//Dirección motor A
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite (ENB, velocidad); //Velocidad motor B
// LUCES - apagadas
digitalWrite(A5, LOW);
digitalWrite(A4, LOW);
}
void izquierda (){
//Dirección motor A
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
analogWrite (ENB, velocidad); //Velocidad motor B
// LUCES - rojo
digitalWrite(A5, HIGH);
digitalWrite(A4, LOW);
}
void derecha (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, HIGH);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite (ENB, velocidad); //Velocidad motor B
// LUCES - verde
digitalWrite(A5, LOW);
digitalWrite(A4, HIGH);
}
void retroceder (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, HIGH);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
analogWrite (ENB, velocidad); //Velocidad motor B
// LUCES - apagadas
digitalWrite(A5, LOW);
digitalWrite(A4, LOW);
}
void parar (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, LOW);
analogWrite (ENA, 0); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, LOW);
analogWrite (ENB, 0); //Velocidad motor B
// LUCES - apagadas
digitalWrite(A5, LOW);
digitalWrite(A4, LOW);
}
Indicar con un aviso sonoro objetos cercanos
Lo siguiente será avisar si tenemos un objeto cercano al robot, para ello, tenemos que añadir un módulo de ultrasonidos HC-SR04 y utilizaremos una plataforma móvil que constará de dos servos, para poder hacer un barrido frontal conforme avanza el robot.
Material nuevo a añadir:
- Módulo HC-SR04
- Buzzer pasivo (en este caso estoy utilizando el módulo KY-006)
- 2 servos
- Cables Dupont
- Plataforma móvil
- Tornillos y tuercas para sujetar la plataforma
Montamos el módulo de ultrasonidos y el buzzer según el siguiente esquema:
Los servos los vamos a conectar a los pines 11 y 12. El del pin 11 va a ser el que se mueva horizontalmente (eje x) y el del pin 12, el del eje vertical (eje y). Tened en cuenta que para la programación utilizaremos la biblioteca "Servo.h" la cual desactiva los pines digitales 9 y 10 de la placa y la alimentación de estos va a ser a partir del controlador de motor L298N, si lo hacemos a través de Arduino provocará interferencias con el infrarrojo. El Buzzer, lo conectamos al pin analógico A3, utilizándolo como salida, y el módulo de ultrasonidos lo conectamos al pin analógico A1, para alimentarlo también utilizamos el controlador L298N.
Procedemos a programar. Primero vamos a hacer que los servos coloquen de frente el módulo de ultrasonidos, para ello incluimos la librería servo.h, comprobamos su versión:
y creamos dos objetos servos
#include "Servo.h" // librería para poder controlar el servo version 1.2.1
Servo servo1; // eje x
Servo servo2; // eje y
En la función setup() indicamos a qué pin están conectados y posicionamos, intentando que nos quede horizontal y mire hacia delante:
servo1.attach(11); // pin 11
servo1.write(100); // colocación inicial del servo 1 - eje horizontal
servo2.attach(12);
servo2.write(100); // aproximadamente 100º, no tiene porque coincidir con los que he utilizado
Lo probamos a ver si funciona, a continuación queremos que nos compruebe si tenemos un objeto a menos de 30 cm. Incluimos la librería NewPing.h, indicamos el pin conectado al Trigger, el pin conectado al Echo e indicamos la distancia máxima, 200 cm. Creamos el objeto sonar, una variable entera "pingSpeed", será la frecuencia con la que enviaremos una señal y otra variable para medir el tiempo transcurrido, "pingTimer"
#include "NewPing.h" // versión 1.9.7
#define PIN_TRIG A1 // Pin del Arduino conectado al pin Trigger del sensor de ultrasonidos
#define PIN_ECHO A0 // Pin del Arduino conectado al pin Echo del sensor de ultrasonidos
#define MAX_DISTANCIA 200 // Distancia máxima a detectar en cm.
NewPing sonar(PIN_TRIG, PIN_ECHO, MAX_DISTANCIA);
unsigned int pingSpeed = 50; // Frecuencia con la que se enviara un ping
unsigned long pingTimer; // variable para el tiempo transcurrido
Indicamos en la función setup() que el pin analógico A3 funcionará como salida, es el pin que va al zumbador
pinMode(A3, OUTPUT);
Procedemos a medir la distancia, dentro de la función loop(). Al principio comprobamos el tiempo que ha transcurrido desde el último pulso, calculamos la distancia en cm y lo mostramos por el monitor serial
// medir la distancia
if (millis() >= pingTimer) { // Milisegundos transcurridos desde el ultimo ping
pingTimer += pingSpeed;
int tiempo = sonar.ping_median();
int distancia = tiempo / US_ROUNDTRIP_CM;
// Imprimir la distancia medida en la consola
Serial.print("Distancia: ");
Serial.print(distancia);
Serial.println(" cm");
}
Podemos probarlo y comprobar el resultado:
Seguidamente, creamos una función que nos hará sonar el buzzer durante cierto tiempo
void alarma(){
for (int i = 0; i < 80; i++) {
digitalWrite(A3, HIGH);
delay(1);
digitalWrite(A3, LOW);
delay(1);
}
}
Y realizaremos una llamada a esta función cuando la distancia sea menor de 30 cm.
...
if (millis() >= pingTimer) { // Milisegundos transcurridos desde el ultimo ping
pingTimer += pingSpeed;
int tiempo = sonar.ping_median();
int distancia = tiempo / US_ROUNDTRIP_CM;
// Imprimir la distancia medida en la consola
Serial.print("Distancia: ");
Serial.print(distancia);
Serial.println(" cm");
if(distancia < 30){
alarma();
}
}
...
Subimos el código a la placa Arduino y comprobamos su funcionamiento.
Falta hacer que la plataforma móvil se mueva en el eje x. Vamos a necesitar una variable i que nos indique la posición del servo, y otra variable angulo que nos indicará hacia dónde se tiene que mover, 0 si se debe mover hacia la izquierda y 1 cuando deba moverse hacia la derecha. Declaramos las variables:
...
// servos
Servo servo1; // eje x
Servo servo2; // eje y
int i = 0;
int angulo = 0;
...
Y en la función loop() dentro de la medida de distancia, después del if que comprueba si tenemos un objeto a menos de 30 cm, vamos a ver hacia dónde se tiene que mover
...
// movimiento del servo
if(angulo == 0){
if (i < 180){
i = i+10;
if(i>179){angulo = 1;}
}
}
if(angulo == 1){
if (i > 0){
i = i-10;
if(i==0){angulo = 0;}
}
}
servo1.write(i);
...
El código completo sería:
#include "NewPing.h" // versión 1.9.7
#define PIN_TRIG A1 // Pin del Arduino conectado al pin Trigger del sensor de ultrasonidos
#define PIN_ECHO A0 // Pin del Arduino conectado al pin Echo del sensor de ultrasonidos
#define MAX_DISTANCIA 200 // Distancia máxima a detectar en cm.
NewPing sonar(PIN_TRIG, PIN_ECHO, MAX_DISTANCIA);
unsigned int pingSpeed = 50; // Frecuencia con la que se enviara un ping
unsigned long pingTimer; // variable para el tiempo transcurrido
#include "Servo.h" // librería para poder controlar el servo version 1.2.1
// servos
Servo servo1; // eje x
Servo servo2; // eje y
int i = 0;
int angulo = 0;
// Motor A
int ENA = 6;
int IN1 = 7;
int IN2 = 8;
// Motor B
int ENB = 5;
int IN3 = 4;
int IN4 = 3;
int velocidad = 100;
String sentido = "p"; // inicialmente parado
#include "IRremote.h" // libreria version 4.x
#define IR_RECEIVE_PIN 2 // el infrarrojo va al pin 2
void setup() {
Serial.begin(9600);
servo1.attach(11); // pin 11
servo1.write(100); // colocación inicial del servo 1 - eje horizontal
servo2.attach(12);
servo2.write(100); // aproximadamente 100º
IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK); // iniciar infrarrojo
// motores
pinMode (ENA, OUTPUT);
pinMode (ENB, OUTPUT);
pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (IN3, OUTPUT);
pinMode (IN4, OUTPUT);
// LED
pinMode(A5, OUTPUT);
pinMode(A4, OUTPUT);
//zumbador
pinMode(A3, OUTPUT);
}
void loop() {
// medir la distancia
if (millis() >= pingTimer) { // Milisegundos transcurridos desde el ultimo ping
pingTimer += pingSpeed;
int tiempo = sonar.ping_median();
int distancia = tiempo / US_ROUNDTRIP_CM;
// Imprimir la distancia medida en la consola
Serial.print("Distancia: ");
Serial.print(distancia);
Serial.println(" cm");
if(distancia < 30){
alarma();
}
// movimiento del servo
if(angulo == 0){
if (i < 180){
i = i+10;
if(i>179){angulo = 1;}
}
}
if(angulo == 1){
if (i > 0){
i = i-10;
if(i==0){angulo = 0;}
}
}
servo1.write(i);
}
if (IrReceiver.decode()) {
uint16_t command = IrReceiver.decodedIRData.command;
switch (command) {
case 24:
Serial.println("avanzar");
sentido = 'a';
break;
case 8:
Serial.println("izquierda");
sentido = 'i';
break;
case 90:
Serial.println("derecha");
sentido = 'd';
break;
case 82:
Serial.println("retroceder");
sentido = 'r';
break;
case 74:
Serial.println("parar");
sentido = 'p';
break;
default:
Serial.println("indefinido");
}
mover(sentido);
IrReceiver.resume();
}
}
void mover(String sentido){
if(sentido == "a"){
Serial.println("avanzar");
avanzar();
}
if(sentido == "i"){
Serial.println("izquierda");
izquierda();
}
if(sentido == "d"){
Serial.println("derecha");
derecha();
}
if(sentido == "r"){
Serial.println("retroceder");
retroceder();
}
if(sentido == "p"){
Serial.println("parar");
parar();
}
}
void avanzar (){
//Dirección motor A
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite (ENB, velocidad); //Velocidad motor B
// LUCES - apagadas
digitalWrite(A5, LOW);
digitalWrite(A4, LOW);
}
void izquierda (){
//Dirección motor A
digitalWrite (IN1, HIGH);
digitalWrite (IN2, LOW);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
analogWrite (ENB, velocidad); //Velocidad motor B
// LUCES - rojo
digitalWrite(A5, HIGH);
digitalWrite(A4, LOW);
}
void derecha (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, HIGH);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, HIGH);
digitalWrite (IN4, LOW);
analogWrite (ENB, velocidad); //Velocidad motor B
// LUCES - verde
digitalWrite(A5, LOW);
digitalWrite(A4, HIGH);
}
void retroceder (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, HIGH);
analogWrite (ENA, velocidad); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, HIGH);
analogWrite (ENB, velocidad); //Velocidad motor B
// LUCES - apagadas
digitalWrite(A5, LOW);
digitalWrite(A4, LOW);
}
void parar (){
//Dirección motor A
digitalWrite (IN1, LOW);
digitalWrite (IN2, LOW);
analogWrite (ENA, 0); //Velocidad motor A
//Dirección motor B
digitalWrite (IN3, LOW);
digitalWrite (IN4, LOW);
analogWrite (ENB, 0); //Velocidad motor B
// LUCES - apagadas
digitalWrite(A5, LOW);
digitalWrite(A4, LOW);
}
void alarma(){
for (int i = 0; i < 80; i++) {
digitalWrite(A3, HIGH);
delay(1);
digitalWrite(A3, LOW);
delay(1);
}
}
Posibles mejoras que le podemos añadir, por ejemplo, que disminuya la velocidad si detecta un objeto cerca.