Mechatronics Learning Studio
Line Follower
Tanner Wharton, Brandon Lowe, Department of
Mechanical Engineering, University of Ottawa
Overview
The Line Follower was designed to follow lines
and to stop when a sufficient amount of light is applied to the
front photocell. This system was realized by using two infrared
sensors to detect the line, a photocell to detect the light in
front of the vehicle, an Arduino board as a microcontroller, and
two DC motors as actuators, along with other various electronic
components. Also, the frame for the vehicle was designed on
Solidworks, and then 3D printed.
Introduction
The task of designing and implementing a
mechatronics system was given for the class ELG 3336. For our
project, it was decided that building a line following robot
would be a feasible goal, and, time permitting, modifications
could be made to the design to further enhance the system. This
project would not only develop our knowledge of electronics, but
also expand our understanding of the designing and
implementation processes that accompany such a venture. The
fundamental goal to accomplish was to build small vehicle that
would follow a black line on a sufficiently contrasting surface.
Once that goal was realized, the illuminated stopping capability
became the next goal to accomplish. The entirety of the project
can be separated into 4 steps: purchasing the materials,
designing and printing the frame, creating the circuit and
coding the Arduino. Each step will be discussed in the following
subsections.
Materials
Most
of the components were purchased from online sources or from
hobby shops. The materials needed for the project are:
-
Arduino Uno
-
Wire Snips and
Strippers
-
Breadboard
-
9V Battery
-
One Photocell
-
2-IR Emitter/Sensor
-
100, 220, 279, and
5.6k ohm resistors
-
Yellow and Red LED’s
-
2 Wheels and One Ball
Caster
-
2 DC Motors
-
NPN Transistors
-
Diodes
Frame
As previously mentioned, the frame was 3D
printed. This has many advantages, such as having custom holes
to fit the components with accurate dimensions, the ability to
convert one’s design into reality along with simplification of
the building process. The original design for the frame was made
on Solidworks, a computer aided drafting software. By taking
measurements of all the components needed for the line follower,
fitted holes could be added to the draft on the computer. Once
the draft was deemed sufficient for implementation, the file was
given away for printing. The frame turned out great, although a
few modifications had to be made. As it happens, when a 3D
printer creates an object, the final dimensions of the object
are never the same as the original ones. This lack of accuracy
is due to shrinkage in the plastic after the printing process.
But, with the help of a grinder, the component holes could be
enlarged and the project could continue.
Circuit
The
circuit of this project has seven main components that make up
the system.
1.
A
Arduino Board
A
programmable microcontroller that reads and transmits signals to
and from various components (the code can be found below).
2.
Breadboard
A
solderless circuit framework, that allows the connection of
electrical components in a neat and organized fashion with
minimal use of wires.
3.
Infrared
Sensors/Transmitters
This
electronic component can receive and send light from the
infrared spectrum, which has a slightly longer wavelength than
that of the visible spectrum so it cannot be seen by human eyes.
The
infrared sensor is used in this circuit to differentiate between
black and white surfaces. It differentiates by using a built in
transistor that is sensitive to the amount of infrared light
reflected or absorbed by the surface being subjected to infrared
light (circled in red).
4. Photocell
The
photocell is a light based resistor that changes resistance
based on the amount of light is subjected to
the
photo cell is used in this circuit to detect if a bright light
(traffic light) is present and enable or disable the DC motors
based on the readings.
5. DC
Motors
The DC
motors are used to drive the car in this project, these specific
motors have had their speed reduced in a small gear box in order
to increase the torque. Using the Arduino the IR sensors are
used to keep a black line between two IR sensors, and when the
line is detected the motors react accordingly.
6.
LEDs (Light Emitting Diodes)
The
LED’s are programmed to react when an IR sensor detects a line;
these LED’s are located on the breadboard. There are also LED’s
programmed to react to the stimulation of the photocell by a
bright light in which case they are illuminated and the DC
motors are disabled.
7.
Transistors
The
transistors are used as switches in order to control the
magnitude of the signal and therefore the speed of the DC
motors. The only downfall of this setup is that the motors
cannot run in reverse. See the following pictures where
transistors are circled with gree.
Code
//
Sensors (Into Arduino)
const
int RIGHT_IR = A0;
const
int PHOTO = A3;
const
int LEFT_IR = A5;
//
Signals (Out of Arduino)
const
int LEFT_MOTOR = 11;
const
int RIGHT_MOTOR = 3;
const
int LEFT_LED = 4;
const
int RIGHT_LED = 10;
const
int BRAKE_LIGHTS = 7;
//
Other Variables
int
motor_high_right = 105;
int
motor_high_left = 105;
int
motor_mid_right = 55;
int
motor_mid_left = 55;
int
motor_off = 0;
int
right_ir_mid = 950;
int
left_ir_mid = 950;
int
photo_mid = 150;
// MAIN
FUNCTIONS
void
setup()
{
pinMode(RIGHT_MOTOR, OUTPUT);
pinMode(LEFT_MOTOR, OUTPUT);
pinMode(LEFT_LED, OUTPUT);
pinMode(RIGHT_LED, OUTPUT);
pinMode(BRAKE_LIGHTS, OUTPUT);
//right_ir_mid = calibrate(RIGHT_IR, RIGHT_LED);
//left_ir_mid = calibrate(LEFT_IR, LEFT_LED);
//photo_mid = calibrate(PHOTO, BRAKE_LIGHTS);
}
void
loop()
{
boolean right_sensor = value_higher_than_mid(RIGHT_IR,
right_ir_mid, RIGHT_LED);
boolean left_sensor = value_higher_than_mid(LEFT_IR,
left_ir_mid, LEFT_LED);
boolean photo_sensor = value_higher_than_mid(PHOTO, photo_mid,
BRAKE_LIGHTS);
move_car(right_sensor, left_sensor, photo_sensor);
}
//
MOVEMENT FUNCTIONS
void
move_car(boolean sense_right, boolean sense_left, boolean
sense_photo)
{
if(sense_photo == true)
{
brake();
}
else
if((sense_right == true)&&(sense_left == false)&&(sense_photo ==
false))
{
turn_right();
delay(2000);
move_straight();
}
else
if((sense_right == false)&&(sense_left == true)&&(sense_photo ==
false))
{
turn_left();
delay(2000);
move_straight();
}
else
if ((sense_right == false)&&(sense_left == false)&&(sense_photo
== false))
{
move_straight();
}
}
void
move_straight()
{
analogWrite(RIGHT_MOTOR, motor_high_right);
analogWrite(LEFT_MOTOR, motor_high_left);
}
void
turn_left()
{
analogWrite(RIGHT_MOTOR, motor_mid_right);
analogWrite(LEFT_MOTOR, motor_off);
}
void
turn_right()
{
analogWrite(LEFT_MOTOR, motor_mid_left);
analogWrite(RIGHT_MOTOR, motor_off);
}
void
brake()
{
analogWrite(LEFT_MOTOR, motor_off);
analogWrite(RIGHT_MOTOR, motor_off);
}
//SENSOR FUNCTIONS
boolean
value_lower_than_mid(int SENSOR_PIN,int SENSOR_MID, int
SENSOR_INDICATOR)
{
boolean lower_than_mid = false;
digitalWrite(SENSOR_INDICATOR, LOW);
int
sensor_value = analogRead(SENSOR_PIN);
if(sensor_value < SENSOR_MID)
{
digitalWrite(SENSOR_INDICATOR, HIGH);
lower_than_mid = true;
}
return lower_than_mid;
}
boolean
value_higher_than_mid(int SENSOR_PIN,int SENSOR_MID, int
SENSOR_INDICATOR)
{
boolean higher_than_mid = false;
digitalWrite(SENSOR_INDICATOR, LOW);
int
sensor_value = analogRead(SENSOR_PIN);
if(sensor_value > SENSOR_MID)
{
digitalWrite(SENSOR_INDICATOR, HIGH);
higher_than_mid = true;
}
return higher_than_mid;
}