How to Make a Remote Controlled Robot | Arduino

featured-remote-control

In this post, I’ll show you how to make a remote controlled robot using Arduino and a Sony Universal Remote Control.

Shout out to the late Gordon McComb for this project idea. He is the author of an excellent book that I recommend buying if you’re getting started with robotics: How to Make a Robot.

Requirements

Here are the requirements:

  • Control a wheeled robot using a Sony Universal Remote Control.

You Will Need

The following components are used in this project. You will need:

Directions

First, get the infrared sensor. Bend the metal lead 0.25 inches below the base of the square sensor so that it makes a 90-degree angle.

remote-control-robot-1

Cut the lead 3/8 inches below the point of the bend. The dome of the sensor should face the opposite direction of the 90-degree bend.

remote-control-robot-2

Insert the infrared sensor into the Arduino board so that the pins are inside analog pins 0, 1, and 2. The dome of the infrared sensor should face upwards.

remote-control-robot-4
remote-control-robot-3

Insert batteries into the Sony Universal remote control.

Set up the remote control so that it can operate a Sony television. The instructions for how to setup the remote control should be included inside the package that it came with.

Add the IRremote library to the Arduino IDE. Go to Sketch -> Include Library -> Manage Libraries and look for “IRremote.” Add it, and then restart the IDE.

Upload the IRtest sketch to the Arduino (see code below). This sketch will be used to test the remote control, whose buttons do the following:

  • 1: Left Turn (Forward)
  • 2: Forward
  • 3: Right Turn (Forward)
  • 4: Spin Left
  • 5: Stop
  • 6: Spin Right
  • 7: Left Turn (Reverse)
  • 8: Backwards
  • 9: Right Turn (Reverse)

Open the Serial Monitor, and press any number from 1 to 9. You should see that number show up in the Serial Monitor.

#include <IRremote.h>      

/**
 * This code tests the Sony Universal Remote Control
 * 
 * Credit: Gordon McComb, How to Make a Robot.
 * Book available here: https://amzn.to/2Q303ed
 * 
 * Code was modified by Addison Sears-Collins
 */

#define  show_code  false   // Test mode
                            // false means match to # buttons
                            // true means display raw code

const int RECV_PIN = A0;     // Receiver input on Analog 0
IRrecv irrecv(RECV_PIN);     // Define IR recever object
decode_results results;

/*   
 *  This setup code is run only once, when 
 *  Arudino is supplied with power.
 */
void setup() {
  pinMode(A1, OUTPUT);       // IR power, ground pins
  pinMode(A2, OUTPUT);
  digitalWrite(A1, LOW);     // The ground for the IR
  digitalWrite(A2, HIGH);    // Power to the IR
  irrecv.enableIRIn();       // Initiate the receiver
  Serial.begin(9600);        // Set the baud rate
}

void loop() {

  if (irrecv.decode(&results)) {  // If valid value was received
    if(show_code) {                // If show_code=true 
      Serial.print("0x");
      Serial.println(results.value, HEX);  // Display raw hex
    } else {                      // else show_code=false
      switch (results.value) {    // Match button to Sony codes
        case 0x10:
          Serial.println("1");
          break;
        case 0x810:
          Serial.println("2");
          break;
        case 0x410:
          Serial.println("3");
          break;
        case 0xC10:
          Serial.println("4");
          break;
        case 0x210:
          Serial.println("5");
          break;
        case 0xA10:
          Serial.println("6");
          break;
       case 0x610:
          Serial.println("7"); 
          break;
        case 0xE10:
          Serial.println("8");
          break;
        case 0x110:
          Serial.println("9");
          break;
      }        
    }
    irrecv.resume();    // Receive the next value
    delay(10);          // Pause for 10 milliseconds
  }

}

Now, upload the code below to the Arduino. Remove the USB cord. Place the robot on the floor. Turn on the servos. Insert the 9V battery jack into the Arduino, and drive the robot around the room!

#include <Servo.h> 

/**
 * This code runs the remote controlled robot
 * 
 * 
 * @author Addison Sears-Collins
 * @version 1.0 2019-05-14
 */
 
Servo left_servo;              // Define left servo
Servo right_servo;             // Define right servo

#include <IRremote.h>
int RECV_PIN = A0;
IRrecv irrecv(RECV_PIN);
decode_results results;
volatile int active_left = LOW;
volatile int active_right = LOW;
boolean started = false;

void setup() {
  // Set pin modes for switches
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  pinMode(4, OUTPUT);
  digitalWrite(2, HIGH);
  digitalWrite(3, HIGH);
  digitalWrite(4, LOW);     // Serves as ground connection
  
  pinMode(A1, OUTPUT);       // IR power, ground pins
  pinMode(A2, OUTPUT);
  digitalWrite(A1, LOW);     // IR ground
  digitalWrite(A2, HIGH);    // IR power

  right_servo.attach(9);    // Set right servo to digital pin 9  
  left_servo.attach(10);    // Set left servo to digital pin 10
  irrecv.enableIRIn();     // Start the receiver
  
  Serial.begin(9600);
    
  // Set up interrupts
  attachInterrupt(0, bump_right, FALLING);
  attachInterrupt(1, bump_left, FALLING);
  
  started = true;
}

void loop() {
  
  if (active_left == HIGH) {           // If left bumper hit
    go_backwards();
    delay(500); 
    spin_right();
    delay(1000);
    go_forward();
    active_left = LOW;
    Serial.println("active_left");
  }
  
  if (active_right == HIGH) {          // If right bumper hit
    go_backwards();
    delay(500); 
    spin_left();
    delay(1000);
    go_forward();
    active_right = LOW;
    Serial.println("active_right");  
  }
  
  if (irrecv.decode(&results)) {
    switch (results.value) {
      case 0x10:
        Serial.println("1");     // Turn left forward
        left_turn_fwd();
        break;
      case 0x810:
        Serial.println("2");     // Forward
        go_forward();
        break;
      case 0x410:
        Serial.println("3");     // Turn right forward
        right_turn_fwd();
        break;
      case 0xC10:
        Serial.println("4");    // Spin left
        spin_left();
        break;
      case 0x210:
        Serial.println("5");    // Stop
        stop_all();
        break;
      case 0xA10:
        Serial.println("6");    // Spin right
        spin_right();
        break;
     case 0x610:
        Serial.println("7");    // Turn left reverse
        left_turn_backwards();
        break;
      case 0xE10:
        Serial.println("8");    // Reverse
        go_backwards();
        break;
      case 0x110:
        Serial.println("9");    // Turn right reverse
        turn_right_backwards();
        break;
    }        
    irrecv.resume(); // Receive the next value
    delay(2);
  }
}

// Routines for forward, reverse, turns, and stop
void go_forward() {
  left_servo.write(180);
  right_servo.write(0);
}
void go_backwards() {
  left_servo.write(0);
  right_servo.write(180);
}
void spin_right() {
  left_servo.write(180);
  right_servo.write(180);
}
void spin_left() {
  left_servo.write(0);
  right_servo.write(0);
}
void right_turn_fwd() {
  left_servo.write(180);
  right_servo.write(90);
}
void left_turn_fwd() {
  left_servo.write(90);
  right_servo.write(0);
}
void left_turn_backwards() {
  left_servo.write(90);
  right_servo.write(180);
}
void turn_right_backwards() {
  left_servo.write(0);
  right_servo.write(90);
}
void stop_all() {
  left_servo.write(90);
  right_servo.write(90);
}

// Interrupt service routines
void bump_left() {
  if (started)
    active_left = HIGH;
}
void bump_right() {
  if (started) 
    active_right = HIGH;
}

Video