Arduino: Servo and IR sensor

Autonomous robots usually use sensors to learn their surroundings, and in order not to hit an object while rolling, it is very wise to add a distance sensor. One of the very well common range sensors are the infra red(IR) distance sensor, also known as ‘Sharp sensors’ referring to the company that makes them.

This Sharp sensor has 3 wires: Black for ground, Red for 5volts, and Yellow for data.
Since we have data wire, we need a microcontroller unit to analyze that certain input from the sensor, in this case we’ll be using the Arduino(uno):

IR sensor attached to Arduino. Notice that the data input from the yellow wire is connected to the analog input of the Arduino(pin 0).

But having an IR sensor on its own is not that helpful, once you detected an object in-front of the robot, you need to know which direction to head for that is clear of obstacles, therefore, a stationary IR sensor does not provide that help, we need to rotate it using a servo motor:

The servo has a yellow data wire, but instead of connecting it to the analog pin, we connect it to a digital pin.

The Arduino comes with a library for controlling a servo with pretty straightforward examples to make it easy to learn.

Now that we have both the servo and the IR sensor, go ahead and mount the sensor on the servo so it will rotate it and give us a precise information about the surroundings.

The task that the servo should perform is:

  1. If an object got in the way, rotate the IR sensor to the right(or left).
  2. If there still an object, rotate the IR sensor the the other direction
  3. bring the IR sensor to the middle
#include <Servo.h> 

Servo myservo;
int sensorPin0 = 0;
int sensorPin1 = 1;
int ledPin = 13;
float sensorRightValue;
float sensorLeftValue;
boolean range; // true if there is a close object, false if there is no object infront of robot
void setup()
{
  Serial.begin(9600);
  pinMode(sensorPin0,INPUT);
  pinMode(sensorPin1,INPUT);
  pinMode(13,OUTPUT);
  myservo.attach(9);
  myservo.write(0);
}
void loop()
{

  sensorRightValue = analogRead(sensorPin0);
  sensorLeftValue = analogRead(sensorPin1);
  range = distance(sensorRightValue,  sensorLeftValue);

  Serial.print("sensor 1 = ");
  Serial.print( sensorRightValue);
  Serial.print( ", sensor2 = " );
  Serial.print(sensorLeftValue);
  Serial.println();

  if(range)
  {
    turnRight();
    sensorRightValue = analogRead(sensorPin0);
    sensorLeftValue = analogRead(sensorPin1);
    range = distance(sensorRightValue,  sensorLeftValue);
    if(range) 
    {
      turnLeft();
      sensorRightValue = analogRead(sensorPin0);
      sensorLeftValue = analogRead(sensorPin1);
      range = distance(sensorRightValue,  sensorLeftValue);
      if(range)
      {
        Serial.println("Manual");
        turnToMiddle('L');
      }
      else
      {
        blinkLED();
        // move robot to the left
        Serial.println("move to the left");
        //return servo to middle position
        turnToMiddle('L');
      }
    }
    else
    {
      blinkLED();
      // move robot to the right
      Serial.println("move to the right");
      //return to middle potition
      turnToMiddle('R');
    }
  }
  else blinkLED();

}

// return true if the ir sensors show close range, else, if the 
// object is still far, return false.
boolean distance(float sensorRightValue, float sensorLeftValue)
{
  if(sensorRightValue>=400 && sensorRightValue<700 || sensorLeftValue>=400 && sensorLeftValue <700)
  {
    return true;
  }
  else return false;
}

void turnRight()
{
  int pos=0;
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
  delay(500);
}
void turnLeft()
{
  int pos = 0;
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
    delay(500);
}

void turnToMiddle(char currentDirection)
{
  if(currentDirection == 'L')
  {
    int pos=0;
    for(pos = 1; pos < 90; pos += 1)  // goes from 0 degrees to 90 degrees 
    {                                  // in steps of 1 degree 
      myservo.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(15);                       // waits 15ms for the servo to reach the position 
    } 
    delay(500);
  }
  else if(currentDirection == 'R')
  {
    int pos = 0;
    for(pos = 179; pos>=90; pos-=1)     // goes from 180 degrees to 90 degrees 
    {                                
      myservo.write(pos);              // tell servo to go to position in variable 'pos' 
      delay(15);                       // waits 15ms for the servo to reach the position 
    } 
      delay(500);
  }
}

void blinkLED()
{
    digitalWrite(13,HIGH);
    delay(400);
    digitalWrite(13,LOW);
    digitalWrite(13,HIGH);
    delay(400);
    digitalWrite(13,LOW);

}

2 thoughts on “Arduino: Servo and IR sensor

  1. This is a nice code.but can you use normal IR-sensor-transmitter couple instead of the sharp sensor…Sharp sensor cost 2.5 $ but the normal one cost 20 cents..for one who makes a lot of robots, that makes a difference…but how far the same code will function on a pair of IR transistor and receiver??

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: