Engineering

Outreach

Resources

Enrichment

Green Engineers

Mechatronics Studio

Contact Us

Mechatronics Learning Studio

 

Following Flames IR Robot

Erika Warren, Darik Oreskovich, Department of Mechanical Engineering, University of Ottawa

 

Introduction

The objective of our ELG3336 final project was to produce a robot that would follow a person or object. The robot we created is called Following Flames. The industrial idea for this project is for it to be used in airports where everyone has luggage needing to be transported. It would be used in the situation where a traveller has too much luggage to carry all at once, or is not capable of carrying their own luggage. The larger-scale IR Robot would be loaded with luggage and would follow a specific traveller through the airport to their destination. Since this is a smaller-scale model we decided to gear the aesthetics of the robot more towards the look of a toy rather than a more practical carrying device. The airport model would have a more stable platform to carry luggage. The IR robot incorporates an Arduino microcontroller, battery packs, an IR sensor, a servo motor, DC motors, a potentiometer, a photoresistor, and a buzzer which are explained in more detail below. When powered on, the robot searches for an object/person by using the IR sensor to scan the area 180 degrees in front of it and then turning in a circle and re-scanning until an object is found. If an object is detected directly in front of the robot, it will follow the object until it moves out of range. If an object is detected to its left or right, the robot will turn in the direction of the object, scan again, and then follow the object if it is directly in front of it. If not, the robot will continue to scan and turn until the object is directly in front of it. If the object moves out of detection range, the robot will stop and scan the area around it until an object moves into range. If the lights in the room are turned off, the robot will stop moving and the buzzer will sound until the lights go back on. The robot also features an LCD read-out on the front that shows its name as well as the action it is performing at the time whether it is following, searching, or cannot see.

Materials and Tools:

  Arduino Uno Microcontroller

  1 Servomotor

  2 DC Motors

  1 Sharp IR Sensor

  1 Potentiometer

  1 Breadboard

  1 Buzzer

  1 Switch

  1 Light Dependent Resistor

  1 1602 LCD Display

  Required Resistors

  1 Driver Board

  Heat Shrink

  Hardwood

  Spray Paint

  Various Fasteners, Nuts, Washers, and Bolts

  Epoxy

  Double-Sided Tape

  Aluminum Bars

  1 Tamiya Gearbox

  2 Rubber Wheels and 1 Castor Wheel

  Various Batteries

  Drill

  Soldering Iron, Solder, and Flux

  Dremel and Files

  Jigsaw and Saw

Design Procedure

Robot Frame/Body

The robot chassis was cut from pieces of hardwood. The flame design was drawn on to the boards and then cut out with a jigsaw and saw. It was then filed down with a dremel to produce the smooth curves of the flames. The flames were then spray painted their respective colors.

A bolt, 4 washers, and 4 nuts were used to separate the two flame-shaped boards to produce a tiered effect. This provided more space for electrical components. A drill and dremel were used to make holes in the boards.

Drive System

The drive system of the robot features a Tamiya gearbox, 2 DC motors, batteries, an aluminum rod, 2 rubber wheels, and 1 castor wheel. The gearbox was constructed to satisfy the desired speed and torque. The 2 DC motors were added to the gear box along with the aluminum rod for the axle. The 2 rubber wheels were attached to the axle with Epoxy and the entire system was stuck to the bottom of the larger flame using double-sided tape. The DC motors ran off of 4 AA batteries which were in a battery pack and also stuck to the bottom of the larger flame with double-sided tape. The castor wheel was centered on the bottom of the larger frame at the front of the robot to provide balance as well as more facilitated changing of directions.

A driver board is used in order to regulate the voltage given to each motor and to prevent over-loading or over-heating.

Electronics

The robot is controlled autonomously with an Arduino Uno microcontroller. The Arduino runs off of a 9V battery that is stuck on the bottom flame with double-sided tape. The Arduino controls all of the electronics that allow the robot to perform the desired function. The Arduino is uploaded with written code, and all electrical components are connected to it via wires. Power is supplied to components through the breadboard.

A Sharp IR sensor is used to measure object distance. It can sense an object up to 150cm in front of it by sending and receiving IR signals. Ranges may vary depending on the type of IR sensor used. The IR sensor is mounted on a servo motor. This allows the IR sensor to be rotated 180 degrees in order to search for an object. If no object is sensed, the entire robot will turn 90 degrees and the IR sensor will repeat its 180 degrees search.

When the light levels in the room are too low, the robot will stop its searching or following and a buzzer will sound. A light dependent resistor is used to sense the light levels. Its settings can be adjusted through the code uploaded on the Arduino. A 10kOhm resistor is used to connect it to the circuit. A piezo buzzer is used to make the buzzing sound.

Another feature of our robot is its LCD read-out. The LCD always shows the robots name in the first line, ie. Following Flames. The robots actions will be shown on the second line. When it is roaming and searching for an object it will read Where are you?. When it is following an object it will read Come back here!. When it is too dark to function it will read Cant see!. These settings can be changed within the code uploaded on the Arduino. A potentiometer is connected within the circuit in order to change the brightness of the LCD display.

Code

#include <Servo.h>         //includes the servo library

#include <LiquidCrystal.h>

 LiquidCrystal lcd(2, 3, 9, 10, 11 , 12);

 int motor_pin1 = 4;

int motor_pin2 = 5;

int motor_pin3 = 6;

int motor_pin4 = 7;

int servopin = 8;

int sensorpin = 0;

int dist = 0;

int leftdist = 0;

int rightdist = 0;

int object = 300;  //distance at which the robot should re trace object   

Servo myservo;

 //---Where things attach to arduino----//

void setup ()

{

  pinMode(motor_pin1,OUTPUT);

  pinMode(motor_pin2,OUTPUT);

  pinMode(motor_pin3,OUTPUT);

  pinMode(motor_pin4,OUTPUT);

  myservo.attach(servopin);

  myservo.write(90);

  delay(700);

  lcd.begin(16, 2);

  lcd.setCursor(0,0);

  lcd.write("Following Flames");

    pinMode(13, OUTPUT); // set a pin for buzzer output

  analogWrite(13,128);

  delay(500);

  digitalWrite(13, LOW);

  delay(500);

  analogWrite(13,128);

  delay(500);

  digitalWrite(13, LOW);

  delay(500);

}

 //---------------Main Loop--------------//

 void loop() // Main loop, code keeps doing this until you turn it off

{

  int sensorvalue = analogRead(A1);

    if(sensorvalue <= 900) {

    dist = analogRead(sensorpin);               //reads the sensor

 

  if(dist > object) {                         //if distance is less than 300

   lcd.setCursor(0,2);

   lcd.write("                ");

   lcd.setCursor(0,2);

   lcd.write("Come back here!");

   forward();                                  //then move forward

  }

  if(dist < object) {               //if distance is less than or equal to 300

    lcd.setCursor(0,2);

    lcd.write("                ");

    lcd.setCursor(0,2);

    lcd.write(" Where are you?");

    findroute();

  }

  }

    else {

   digitalWrite(motor_pin1,LOW);

   digitalWrite(motor_pin2,LOW);

   digitalWrite(motor_pin3,LOW);

   digitalWrite(motor_pin4,LOW);

   lcd.setCursor(0,2);

   lcd.write("                ");

   lcd.setCursor(0,2);

   lcd.write("   Can't see!");

   analogWrite(13,128);

   delay(500);

   digitalWrite(13, LOW);

   delay(2500);

  }

}

  //--------Definition of sub functions used to shorten the Main (loop) code-------//

void forward() {                            // use combination which works for you

   digitalWrite(motor_pin1,LOW);

   digitalWrite(motor_pin2,HIGH);

   digitalWrite(motor_pin3,HIGH);

   digitalWrite(motor_pin4,LOW);

   delay(1500);

   return;

 }

 //---------findroute function---------//

 

void findroute() {

  halt();                                             // stop

  //backward();     //go backwards-- ** commented out, not needed since it just needs to keep following

  lookleft();                                      //go to subroutine lookleft

  lookright();                                   //go to subroutine lookright

                                     

  if ( leftdist > rightdist && leftdist > object )

  {

    turnleft();

  }

 if ( rightdist > leftdist && rightdist > object)

 {

   turnright ();

 }

 if (leftdist < object && rightdist < object)

 {

   forward();

   halt();

   lost();

 } 

}

 

//---------backward function--------//  etc....

 void backward() {

  digitalWrite(motor_pin1,LOW);

  digitalWrite(motor_pin2,HIGH);

  digitalWrite(motor_pin3,LOW);

  digitalWrite(motor_pin4,HIGH);

  delay(500);          //these delay values are in Ms, change them to tweak how long things happen

  halt();

  return;

}

 void halt () {

  digitalWrite(motor_pin1,LOW);

  digitalWrite(motor_pin2,LOW);

  digitalWrite(motor_pin3,LOW);

  digitalWrite(motor_pin4,LOW);

  delay(500);                          //wait after stopping

  return;

}

  // if you want more precision you can make more look functions

 // ie  lookleft2(), myservo.write(x) sets the angle in degrees for servo rake

 // then make turnleft2() and have the delay(x) set to values you need to control how long

 // its turning for. Follow the same syntax, int leftdist2 at top and use ifs to check

 // which is closest(largest value). Then call the function your made to turn it to that

 // position.

 void lookleft() {

  myservo.write(150);                    // move servo to 150 degree position

  delay(700);                                //wait for the servo to get there

  leftdist = analogRead(sensorpin);

  myservo.write(90);                     //move servo back to centre

  delay(700);                                 //wait for the servo to get there

  return;

}

 void lookright () {

  myservo.write(30);

  delay(700);                           //wait for the servo to get there

  rightdist = analogRead(sensorpin);

  myservo.write(90);                                 

  delay(700);                        //wait for the servo to get there

  return;

}

 void turnleft () {

  digitalWrite(motor_pin1,LOW);       //use the combination which works for you

  digitalWrite(motor_pin2,HIGH);      //right motor rotates forward and left motor backward

  digitalWrite(motor_pin3,LOW);

  digitalWrite(motor_pin4,HIGH);

  delay(600);                     // wait for the robot to make the turn

  halt();

  delay (500);

  return;

}

 void turnright () {

  digitalWrite(motor_pin1,HIGH);       //use the combination which works for you

  digitalWrite(motor_pin2,LOW);    //left motor rotates forward and right motor backward

  digitalWrite(motor_pin3,HIGH);

  digitalWrite(motor_pin4,LOW);

  delay(600);                              // wait for the robot to make the turn

  halt();

  delay (500);

  return;

}

 void lost() {

   halt();

  turnleft();

  turnleft();

  return;

}