Skip to content

It Can See; Giving Your Bot Sight!

by on April 9, 2014

robot_eyesPreviously we unveiled our love for the Arduino and the Zumo Shield that gives us a massive head start to building our own robot army.  The basic shield has a Zumo reflectance sensor array for primarily line following, and an LSM303DLHC accelerometer & magnometer (magnet-o-meter) for navigation.  But a lot of the remaining Arduino pins are not used, so this gives us the capability to add more tech or sensors so our robot can react to the world around it.

I had a spare HC-SR04 ultrasonic sensor in my kit, so I decided to give my bot some eyes!  Other sensors such as Infra-Red Distance Sensors (Adafruit:IR distance sensor includes cable (10cm-80cm), can also be used.  Adafruit has a variety of sensors available (https://www.adafruit.com/search?q=distance+sensor), but the HC-SR04 can be found on Amazon(http://www.amazon.co.uk/s/ref=nb_sb_noss_1?url=search-alias%3Daps&field-keywords=HC-SR04) for approximately 1 GBP!

I used a quarter size breadboard (or Tiny breadboard) and stuck it down (with its included sticky back adhesive tape).  The solder-less breadboard gives me the option of swappable sensors (incase I want to swap out the ultrasonic sensor for an IR one).  The Ultrasonic Sensor has 4 pins:

  • VCC (5v)
  • GND
  • Trig
  • Echo

I used an example Zumo motor demo from https://github.com/pololu/zumo-shield ,  and added code for the ultrasonic sensor – I place the Trig on Pin 2 and Echo on Pin 11 (their right next to each other, and also next to GND, and VCC behind the cowcatcher.  The HC-SR04 is already supported by the Arduino IDE, so I could natively call:

pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);

So its very easy to communicate with this sensor, though some additional math is needed to calculate distance in ether cm’s or inches (see the sample code below).

For those that don’t know the Asimov’s laws of robotics.  They are:

  1. A robot may not injure a human being or, through inaction, allow a human being to come to harm.
  2. A robot must obey the orders given to it by human beings, except where such orders would conflict with the First Law.
  3. A robot may not injure its own kind and defend its own kind unless it is interfering with the first or second rule.

Being, that this robot is a baby, with no real intelligent code; I decided to program the bot with a simple avoid and run-away, thus avoiding danger (unless its on a table/cliff, which case it will fall off, as no border/line-dection is currently in place).  So basically if the robot is on the floor and detects an object within 8cm, it rotates to the left and carries on moving.

My Simple example program using the ultrasonic sensor:

#include <ZumoMotors.h>
#include <Pushbutton.h> 
/*
 * This example uses the ZumoMotors library to drive each motor on the Zumo
 * forward, then backward. The yellow user LED is on when a motor should be
 * running forward and off when a motor should be running backward. If a
 * motor on your Zumo has been flipped, you can correct its direction by
 * uncommenting the call to flipLeftMotor() or flipRightMotor() in the setup()
 * function.
 */

#define LED_PIN 13
#define FORWARD_SPEED     200
const int trigPin = 2;
const int echoPin = 11;
Pushbutton button(ZUMO_BUTTON);   

ZumoMotors motors;

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  Serial.begin(9600);
  // uncomment one or both of the following lines if your motors' directions need to be flipped
  //motors.flipLeftMotor(true);
  //motors.flipRightMotor(true);
   button.waitForButton();
}

void loop()
{
  
  long duration, inches, cm;
  digitalWrite(LED_PIN, HIGH);
  motors.setSpeeds(FORWARD_SPEED, FORWARD_SPEED);
 
  // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  pinMode(trigPin, OUTPUT);
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
 
  // Read the signal from the sensor: a HIGH pulse whose
  // duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(echoPin, INPUT);
  duration = pulseIn(echoPin, HIGH);
 
  // convert the time into a distance
  inches = microsecondsToInches(duration);
  cm = microsecondsToCentimeters(duration);
  
  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  
  //delay(100);
  
  if(cm < 8){      // run backwards and spin      digitalWrite(LED_PIN, LOW);   motors.setSpeeds(-FORWARD_SPEED, -FORWARD_SPEED);   delay(100);   for (int speed = 0; speed >= -400; speed--)
  {
    motors.setLeftSpeed(speed);
    motors.setRightSpeed(-speed);
    delay(2);
  }
  
/*  for (int speed = -400; speed <= 0; speed++)
  {
    motors.setLeftSpeed(speed);
    delay(2);
  }*/
  }

}

long microsecondsToInches(long microseconds)
{
  // According to Parallax's datasheet for the PING))), there are
  // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
  // second).  This gives the distance travelled by the ping, outbound
  // and return, so we divide by 2 to get the distance of the obstacle.
  // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
  return microseconds / 74 / 2;
}
 
long microsecondsToCentimeters(long microseconds)
{
  // The speed of sound is 340 m/s or 29 microseconds per centimeter.
  // The ping travels out and back, so to find the distance of the
  // object we take half of the distance travelled.
  return microseconds / 29 / 2;
}
Leave a Comment

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: