1. El Octavo Bit
  2. / Arduino
  3. / Proyectos para Arduino
  4. / Robot Arduino controlado por un mando a distancia de infrarrojos

Robot Arduino controlado por un mando a distancia de infrarrojos

| Actualizado:
Comentarios: 0

Robot Arduino controlado por un mando a distancia de infrarrojos
Robot Arduino dirigido con un mando infrarrojo

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.

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.

Robot Arduino controlado por infrarrojo

¿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:

Versión de la librería IRremote.h que estamos utilizando

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

Resultados obtenidos por el monitor serial

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:

Resultado que nos muestra 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.

Robot Arduino con Leds para indicar el giro

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.

Robot arduino controlado por infrarrojo, con sensor de distancia

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:

Comprobar la versión de la librería

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:

Mostrar la distancia por el monitor serial

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.

Artículos que te pueden interesar

Salidas digitales y ejemplos en Arduino
Salidas digitales y ejemplos en Arduino. Efecto coche fantástico.

Salidas digitales y ejemplos en Arduino. Efecto coche fantástico.

| Actualizado:
Comentarios: 0

Siguiendo con los tutoriales de Arduino vamos a programar el efecto de las luces del coche fantástico. Para ello primero veremos cómo encender y apagar un LED, a continuación haremos el efecto con 3 LEDS conectados en paralelo, con 7…

Radio FM con Arduino y el módulo TEA5767
Hacer una radio FM con Arduino y el módulo TEA5767

Hacer una radio FM con Arduino y el módulo TEA5767

| Actualizado:
Comentarios: 1

En este artículo haremos una radio FM con el módulo TEA5767 para Arduino y utilizaremos una pantalla LCD para mostrar la frecuencia que estamos escuchando. Para el cambio de frecuencia, vamos a utilizar un potenciómetro lineal que después cambiaremos por…

Joystick analógico y Arduino
¿Cómo utilizar un joystick analógico con Arduino?

¿Cómo utilizar un joystick analógico con Arduino?

| Actualizado:
Comentarios: 0

En este post veremos la conexión de un joystick a la placa Arduino. Primero se comprobara hacia donde se mueve sacando los datos por el serial monitor y en un segundo proyecto, según el movimiento del joystick encenderá un led.…

Medir la temperatura con Arduino
Medir la temperatura con el sensor LM35 y Arduino

Medir la temperatura con el sensor LM35 y Arduino

| Actualizado:
Comentarios: 5

Veremos cómo medir la temperatura con el sensor analógico LM35 y mostrar el valor de la temperatura en el monitor serial de Arduino o en un display de 4 dígitos y 7 segmentos. El LM35 es uno de los sensores…

Comentarios - 0

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *