You are on page 1of 17

Building a Line Follower Robot

CPP Robotics Club


Wheels
Ball Caster: This will be the front-turning wheel that will allow the robot to swivel one way or
the other without scraping the chassis. The ball caster is easy to mount;
spacer to give it
NOTE:add
Thethe
picture
enough height so that the platform stays level with the ground (or you can leave it out as long as
shown here is the
the sensors that will be mounted are not too close to the ground). Then add the ball caster and use
prototype,
onethe
youball caster
the bolts and nuts to mount it to the chassis. There is an instructions
manual the
to put
will be making will
together that came in the box.
differ for some parts.
Gearbox and wheels: This gearbox has 2 different speed settings and we will be using the
slowest speed (the higher number ratio). There are four large gears and one very small whitegrey gear that we will be using to get the slow speed. There is a diagram that came with the
gearbox that shows how to mount the gears in what order.
Gearbox
NOTE: There are 3 possible wholes that the axel can go through shown in the diagram. The one
that will be used in this project is the center hole (C) between the set
of Caster,
3 holessensors
(2 of them
Ball
labeled A and B) towards the front of the gearbox housing and the one lone hole near the motors
(front end)
that does not go through the outside pieces (the center main piece of the housing has the hole
going through each side).
Set of 3 holes towards
the front of the robot (2
are A and B)

1
Hole C is where the axel will go for
the wheels to properly fit onto the
chassis.

The hole that doesnt go


all the way through (for
outside pieces)

When mounting the axel to drive the wheel, instead of using one long rod to spin the
wheels, use 2 short rods so that each motor assembly spins independent of each other.
Once the gearbox is put together, mount the wheels by sliding them on the end of each
axel (make sure they are all the way on the axel or they will not fit through the wheel holes in the
chassis).

Step 2: Understanding the Electronics

http://www.pololu.com/catalog/product/958
The sensors are an Infrared (IR) LED and phototransistor pair that work together to determine
the reflectance of a surface. The theory is that the sensors will shine light to a surface and,
2

depending on the type of surface and the color, the reflected light will be determined by the
phototransistor and return a certain value to the microcontroller. Infrared light cannot be seen by
the human eye, but almost all digital cameras can (even phone cameras).

http://www.sparkfun.com/commerce/product_info.php?
products_id=9950
The Arduino is already pre-built out of the box; that will be used later when we finally build the
program and test out the robot. This is the brain of the robot; this will hold the code that will
allow the robot to follow the line and this will have most of the signal connections plugged in
from the motor control board and sensors.
Wiring:
Figure 1 is a diagram of how the electronics will be wired (theoretically). Figure 2 will show the
actual wiring; meaning which actual pin of each component is wired to another.

Figure 1: Diagram of circuit


AP1084 Voltage Regulator

TIP102

Arduino
Positive
(+)

Arduino
negative (-)

Figure 2: Layout of circuit

The silver bar on the black


transistors is the heatsink (the
silver metal tab on the actual
transistor).

For the Vin, the Arduino will also be connected to it since the microcontroller can
operate between 9-12V. Be careful when putting together the plug for it, because the Arduino
will not work with the Negative wire connecting to the Positive wire; it has to be Positive to

Positive and Negative to Negative (in general terms, connect red to red wire and black
to black wire).
Figure 3. Plug to Arduino

Fugire 4. Sensor wiring

Step 3: Soldering parts


Transistors:
To solder all the components, start with the Transistors (the ones with the screw hole and
metal tab) to the PCB board. There are 2 different types of transistors that will be used; a TIP 102
NPN Transistor and an AP1084T33L Voltage Regulator. The Voltage regulator will have a
thicker metal tab than the 102s so make sure to tell the difference. Leave enough room for the
signal and motor wires as well as jumper wires (in Figure 2, if your board has more holes than
the picture, leave one space in between transistors to ensure you have enough holes for wiring).
Bend the legs so that the transistors dont slide out in the process of soldering. While soldering,
5

use your pliers and clamp on the leg that is being solder. If you have self clamping pliers, use
those.
NOTE: Reason for clamping the leg is to keep the transistor from overheating, which can make
the component useless if it gets too hot and melts the insides.
DC Barrel Jack (plug) and 9 volt connector:
To set up the plug for the Arduino, first unscrew the plastic cover off. You will see 2 tabs
(one longer than the other) sticking out the rear of the main plug section. The smaller tab in the
middle is the Positive (+) tab; that will be connected to the Arduino+ rail in the board
diagram (refer to Figures 1, 2, and 3). Solder a wire (usually red is the default color for power,
but any color will do) to the tab but do not solder the other end yet. Then solder another wire to
the longer tab (Negative (-)) but do not solder the other end yet; this will later be soldered to
the - rail on the motor control board (refer to Figures 1, 2, and 3). After both wires are soldered
to the plug, feed the free ends through the plastic screw cap and screw it back on the plug. Then
solder the other ends to the correct rails on the motor control board.
Solder the positive wire (usually red) of the 9 volt battery snap to the 9 volt rail and
solder the black negative wire to the Negative terminal (refer to Figure 2).
Wiring Jumper Wires:
The only jumper wires you will need on the motor control board are connecting the
power supply to the transistors (refer to Figure 2). Make sure to clamp to the leg of the transistor
to keep them from overheating!
Wiring Transistors:
After all the Transistors are soldered add and solder wires to the signal rail of the
2 TIP102 transistors (refer to Figure 2 and solder where the blue dots indicate on the PCB
board). Look on the diagram (Figure 2) and find the 2 signal wires from the TIP102 transistors;
solder a separate header to each of them.
Wiring Sensor Wires:
Then solder 3 separate wires to the sensors, but be careful because these can easily melt
due to their size; make sure to only hold the soldering iron for a short period of time! On the
sensors, take the wires connected to VIN on each sensor and solder both to 1 header pin. Take
the 2 GND wires and do the same. For the OUT wires, solder a separate header to both, do
not solder both wires to one header. Then mount the sensors to the open holes on the ball caster
bracket as long as they are close (at least a penny thick) but not touching the ground (you can hot
glue them on).
Wiring Motor Wires:
On the motors there will be 2 tabs that stick out of the back end. Solder a wire to each;
theoretically, we need to have both motors spin in opposite directions of each other because of
the orientation of the gearbox. The top wire (closest to the chassis when the gearbox is mounted)
on each motor we will consider to be the positive wire and those will be connected to the motor
controller. The bottom terminal (closest to the ground) of each motor will be soldered to the
6

ground (or negative) rail on the motor control board (refer to Figure 2). Then place the chassis
with the mounted gearbox on a surface with the motor tabs facing you. Imagining that your
driving it, take the left wire of the positive motor tab and solder it to the motor controller (refer to
Figure 2). Then do the same to the right positive motor wire.
BIG NOTE: Before applying power to the boards, check to make sure that none of the wiring or
soldering is crossing over to the wrong component. This will possibly damage either the motor
controller or the Arduino or both. So always double check to make sure nothing is crossing over!
Connect the 9V battery and check to see if any of the components are starting to get really hot. If
just one gets hot, disconnect the 9V battery immediately and look for any shorts.
Connecting Electroncis to Arduino:
Now that everything is wired and ready to work, the wires will need to be plugged into
the Arduino. For the sensor wires, the VIN wire will go into the 5V pin on the Arduino located
near the analog pins. The GND wire from the sensors will go into the GND pin next to the
5V pin. Depending which sensor is on what side, take the right sensors signal wire and plug it
into analog pin 2. Take the left sensors signal wire and plug it into analog pin 0. Locate the
transistor signal wires and determine which one is the right motor and which is the left motor
(refer to Figure 2 and look for the 2 blue wires; those are the signal wires to vary the speed of the
motors). Take the left motor signal wire and plug it into digital pin 3 on the Arduino. Then take
the right motor signal wire and plug it into digital pin 6.

Step 4: Build Programming


The Arduino is based around the C/C++ language in the computer world. Most of the coding
is predefined and does not need to be made from scratch (which will make this build a lot easier).
Here is a list of commands that we will be using:
-

#define
int
void setup()
void loop()
pinMode()
analogRead()
analogWrite()
delay()
if()
else
//, /* */

Each of the commands has their own functions and can be used in a number of combinations.
#define:

The #define command allows you to set a certain digital pin to a specific name (the analog
pins do not need to be), such as #define LED 13. This will set the LED to be used on digital
pin 13 of the Arduino.
Int:
int is used to hold a variable (whole numbers for this particular command) and will be used
to hold our sensor readings and move the robot around. Such as:
-

int i = 0

voids:
void setup and void loop are the main sections of the code that are required to run the
Arduino program. The setup predefines what each pin is going to be used as (for digital pins
only). Such as pinMode (LED, OUTPUT) will mean that it will apply 5V to digital pin 13
defined earlier. It can also be set as INPUT to read a sensor that returns a 0 or 1 value.
void loop is the main function of the code that will run what you write. In this case, we want it
to read the sensors and then turn on the motors and either speed up or slow down the motors
accordingly.
Analogs:
analogRead is used for reading the inputs from the analog pins on the Arduino (we will be
using 2 of these pins for the robot). The value that will be returned will range from 0-1023, since
the Arduino use a 10 bit analog to digital converter. analogWrite is used to write a Pulse Width
Modulation signal (PWM) to the specified digital pin. A PWM signal ranges from 0 to 255 and
can be used to vary the speed of the motor to that pin. To write one of these analog commands
you do the following:
-

analogRead(0)

The 0 means that it will read from pin 0 of the analog inputs.
-

analogWrite(LED,255)

This will write a PWM signal of 255 (which is the highest value) to pin 3 of the digital pins. This
also means that the power output from digital pin 3 will be a full 5V.
NOTE: There are only certain pins that are PWM and are labeled on the Arduino board face.
Pulse Width Modulation (PWM):
How a PWM signal works is a square wave is generated with one high point and one low
point (0v=low and 5v=high). This acts as a throttle for the motor controllers to change the speed;
for the Arduino, the values that are used for the PWM signal is from 0-255. Here is a problem,
we have a sensor that can read a value up to 1023, but we can only write a signal at a max of
255. To compensate for the huge range, we divide the sensor signal by 4 to closely get the 255
PWM value we need.

Delay:
The delay( ) command pauses the code for a certain amount of time before continuing.
This is based in milliseconds, so to stop the code for 1 second, we write:
-

delay(1000);

ifs and elses:


if and else statements are comparison commands. The if statement checks to see if a
certain range or behavior has been met. Such as:
-

int i=0
if (i==0)
{
Then do this
}

There is a BIG difference between = and ==. The single = means that the particular
int will equal that number. The double == means that the int must equal to the number
specified in the if () statement.
The else statement means that if the if statement is not satisfied, then you do this other
command. Such as:
-

int i=1
if (i==0)
{
Then do this
}
else
{
Do this instead
}

The { } are needed when you want to only do this set of commands at one time (this
particularly deals with multiple actions or a for loop (this will not used in the code covered)).
Commenting (or leaving out):
To have certain parts of a code not work (but you dont want to delete it yet), you use two
different forms of commenting. One is //; this will comment out a part of one line so that the
Arduino knows to skip that part of a code.
NOTE: This comment form can be used in two ways; 1) you can comment a whole entire line
out so it will not be used or 2) you can comment a section of the line out but still use the other
that was not commented out.
Ex:
9

1) //pinMode(LED,OUTPUT);
a. This will comment the whole line out and will not be used
2) pinMode(LED,OUTPUT); // This will set LED pin as output
a. This form will compute the pinMode action but will skip over the comment
section to the right of the backslashes
// form only comments out anything to the right of the backslashes.
The second commenting form is /**/ where is the code sectioned out. This form
only comments out the code in between the /* and the */. Such as:
-

pinMode(/*LED,OUTPUT*/);

This will comment out the section so that the Arduino skips over the code within the
parentheses and moves on to the rest of the code. This method can be used to comment out entire
sections of code.
Layout order of code:
Now here is how to organize the code to work properly:
-

#define ___
int ___;
void setup( )
{
pinMode( , );
}
void loop( )
{
Commands;
}

The semicolons are needed for anything that does not do some type of specific or main function.
Such as int, pinMode, etc. This will be explained in the workshop or can be understood more
at arduino.cc.
Uploading the code to the Microcontroller:
After making your code, go to Tools > Boards and select which microcontroller you
have. Then under Tools > Serial choose which port your microcontroller is set to (you may
have to keep selecting and uploading until the correct one is selected if there is more than one
selected). Along the toolbar, the button with the arrow pointing right towards 2 sets of vertical
dotted lines is the Upload button; this will transfer the code you made to the microcontrollers
memory. If all goes well, it will indicate that the code has been uploaded successfully; otherwise
it will give an error and a small description on what the error is.
EXTRA: Serial Connection (reading sensors feedback)

10

The following line of code can be added to look at the numbers being returned from the
sensors. The communication used is called Serial. There are 2 parts that have to be used in order
to see the numbers being fed from the sensors to the Arduino.
First is in the void setup(). Somewhere in the {}, write out Serial.begin(9600);. This
will let the Arduino know that data will be sent back to the computer (in this case, numbers will
be sent from the sensors, travel through the serial of the Arduino and be displayed on the
computer screen).
Second is in the void loop(). In the {}, near the end before the delay, there are 2
command lines that have to be used to properly see the numbers. One is Serial.print() and
the other is Serial.println (). The difference between the two codes is that println will start
a new line after it prints the line of code in between (). print will just keep printing until
the code specifies to start a new line.
To set up the serial monitor to view the numbers, first we need to code lines that will
allow to print on the computer screen. To start off, we will use a variable from the code below
for now, we will use the L_sens variable. Type out Serial.print(LM); this will print out the
words LM because the quotations mean it will print out text (space also counts as text). Next,
type Serial.print(L_sens); without the quotations, the code will now search for that exact
variable from the rest of the code to see if there is a number associated with it. If so, the number
will be printed out. Now to create a tab as if you pressed tab in Microsoft Word, type
Serial.print(\t); this will create a space similar to a tab space. Continue to add printing
codes until you are ready to print on another line (Serial.pring();).
To see any of the text or values after you upload the code, you need to open the Serial
Monitor built into the Arduino program. In the main Arduino window, along the top there is a
tool bar, select the icon that looks like a box hanging on a string and pulley. This is the Serial
Monitor that will allow you to see the numbers the sensors are returning.
Here is the extra code that is not necessary, but can be helpful to determine a better value
for the code to work off of:
void setup()
{
Serial.begin (9600);
}
void loop()
{
Serial.print("LM");
Serial.print(L_sens);
Serial.print("\t");
Serial.print("RM");
Serial.print(R_sens);
Serial.print("\t");
11

Serial.println("");
delay(100);
}
The delay(100) is just a slower speed to see the values better on the monitor when they print out,
or else the printing is going so fast that the numbers are not readable.
The code:
Here is the code for the Hammerhead style to be used in the robot:
#define Left_mot 3 // Left motor PWM
#define Right_mot 6 // Right motor PWM
int L_sens; // Left Sensor
int R_sens; // Right Sensor
int state, prev_state; //which state the robot is in (turning left, turning right, straight)
void setup(){ // Will apply 5V to each of these pins when needed
pinMode (Left_mot, OUTPUT);
pinMode (Right_mot, OUTPUT);
}
void loop() // start of main function and will keep repeating
{
state = 1; //state will equal 1 and bot will go straight
//----------------------------------------------------------------------------------while (state ==1) //state will make robot go straight or continue with the last state it was in
{
if (state == 1)
{
analogWrite(Left_mot,70);
analogWrite(Right_mot,70);
L_sens = analogRead(0)/4; // Reads the left sensor
R_sens = analogRead(2)/4; // Reads the right sensor
if (R_sens < 120) // Compares the right sensor to a certain range
{
state = 2;
}

12

else if (L_sens < 120) // Compares the left sensor to a certain range
{
state = 3;
}
}
else if (prev_state == 2) //looks at previous state before change of surface
{
analogWrite(Right_mot,15); // Writes a PWM signal to the Right motor pin
analogWrite(Left_mot,100); // Writes a PWM signal to the Left motor pin
if (R_sens < 120) // Compares the right sensor to a certain range
{
state = 2;
}
}
else if (prev_state == 3) //looks at previous state before change of surface
{
analogWrite(Right_mot,100); // Writes a PWM signal to the Right motor pin
analogWrite(Left_mot,15); // Writes a PWM signal to the Left motor pin
if (L_sens < 120) // Compares the left sensor to a certain range
{
state = 3;
}
}
delay(50); // pauses the code for a certain time
}
//----------------------------------------------------------------------------------while (state == 2) // state where robot is turning right
{
L_sens = analogRead(0)/4; // Reads the left sensor
R_sens = analogRead(2)/4; // Reads the right sensor
analogWrite(Right_mot,15); // Writes a PWM signal to the Left motor pin
analogWrite(Left_mot,100); // Writes a PWM signal to the Right motor pin
if (L_sens < 120) // Compares the right sensor to a certain range
13

{
prev_state = state;
state = 3;
}
else if (R_sens < 120 && L_sens < 120)
{
prev_state = state;
state = 1;
}
delay(50); // pauses the code for a certain time
}
//--------------------------------------------------while (state == 3) // state where robot is turning left
{
L_sens = analogRead(0)/4; // Reads the left sensor
R_sens = analogRead(2)/4; // Reads the right sensor
analogWrite(Right_mot,100); // Writes a PWM signal to the Right motor pin
analogWrite(Left_mot,15); // Writes a PWM signal to the Left motor pin
if (R_sens < 120) // Compares the right sensor to a certain range
{
state = 2;
}
else if (R_sens < 120 && L_sens < 120)
{
prev_state = state;
state = 1;
}
delay(50); // pauses the code for a certain time
}
}
Here is the code for the Inverse style to be used in the robot:
#define Left_mot 3 // Left motor PWM
14

#define Right_mot 6 // Right motor PWM


int L_sens; // Left Sensor
int R_sens; // Right Sensor
int state, prev_state; //which state the robot is in (turning left, turning right, straight)
void setup(){ // Will apply 5V to each of these pins when needed
pinMode (Left_mot, OUTPUT);
pinMode (Right_mot, OUTPUT);
}
void loop() // start of main function and will keep repeating
{
state = 1; //state will equal 1 and bot will go straight
prev_state = 0;
//----------------------------------------------------------------------------------while (state ==1) //state will make robot go straight or continue with the last state it was in
{
if (state == 1 && prev_state == 0)
{
analogWrite(Left_mot,70);
analogWrite(Right_mot,70);
L_sens = analogRead(0)/4; // Reads the left sensor
R_sens = analogRead(2)/4; // Reads the right sensor
if (R_sens > 120) // Compares the right sensor to a certain range
{
state = 3; // goes to while loop state == 3 below
}
else if (L_sens > 120) // Compares the left sensor to a certain range
{
state = 2; // goes to while loop state == 2 below
}
}
else if (prev_state == 2) //looks at previous state before change of surface
{
analogWrite(Right_mot,15); // Writes a PWM signal to the Right motor pin
analogWrite(Left_mot,100); // Writes a PWM signal to the Left motor pin
15

if (L_sens < 120) // Compares the left sensor to a certain range


{
prev_state = 0; // goes to while loop state ==1 && prev_state == 0 above
}
}
else if (prev_state == 3) //looks at previous state before change of surface
{
analogWrite(Right_mot,100); // Writes a PWM signal to the Right motor pin
analogWrite(Left_mot,15); // Writes a PWM signal to the Left motor pin
if (R_sens < 120) // Compares the right sensor to a certain range
{
prev_state = 0; // goes to while loop state ==1 && prev_state == 0 above
}
}
delay(50); // pauses the code for a certain time
}
//----------------------------------------------------------------------------------while (state == 2) // state where robot is turning right
{
L_sens = analogRead(0)/4; // Reads the left sensor
R_sens = analogRead(2)/4; // Reads the right sensor
analogWrite(Right_mot,15); // Writes a PWM signal to the Left motor pin
analogWrite(Left_mot,100); // Writes a PWM signal to the Right motor pin
if (R_sens > 120) // Compares the right sensor to a certain range
{
prev_state = state;
state = 3;
}
else if (R_sens > 120 && L_sens > 120 || R_sens < 120 && L_sens < 120)
{
prev_state = state;
state = 1;
}
delay(50); // pauses the code for a certain time
16

}
//--------------------------------------------------while (state == 3) // state where robot is turning left
{
L_sens = analogRead(0)/4; // Reads the left sensor
R_sens = analogRead(2)/4; // Reads the right sensor
analogWrite(Right_mot,100); // Writes a PWM signal to the Right motor pin
analogWrite(Left_mot,15); // Writes a PWM signal to the Left motor pin
if (R_sens < 120 && L_sens < 120 || R_sens > 120 && L_sens > 120)
{
prev_state = state;
state = 1;
}
delay(50); // pauses the code for a certain time
}
}

17

You might also like