You are on page 1of 19

Building a Line Follower Robot

CPP Robotics Club

Following the Line


A Line Follower Robot uses a series of sensors (whether it is light reflection, color detection, etc.) to detect a line drawn on a surface. This particular Line Follower uses two sensors that send two separate signals to the Arduino Microcontroller, which is the brain of the robot, and then the Arduino reads these signals and computes what to do next. The code depends on the user, 1

whether to tell the Arduino to slow down one motor or speed up the motor, or simultaneously slow down one and speed up the other.

List of Parts
Pololu Chassis RRC01A Pololu Dual Chassis Completion Kit for RRC01A (this can make 2 running robots, but you need to buy a second chassis separately in addition of the first one to make both; for now we only need one gearbox, one caster and 2 wheels from the kit for 1 robot) AP1084T33L Voltage Regulator 2x TIP102 NPN Transistor 6x Header Pins 2.1mm Inner Diameter DC plug connector (male) Arduino (with PWM signals and works off a 9Volt battery) PCB Breadboard 9 volt battery snap 9 volt battery Wire

Tools
Pliers Soldering iron Solder Screwdriver Wire strippers

Program
Arduino programmer (www.arduino.cc)

Step 1: Build Base


The platform that the robot is going to be built on is a premade chassis body with a gearbox, ball caster (to allow steering), and tires. It will be easy to put together and the gearbox will only be the hardest part to put together (at least for the chassis only). Chassis: We are going to be using a premade chassis with precut holes for mounting various pieces of hardware. For now, we will be using the mounting holes that will hold the gear box and the set of 4 holes for the ball caster. The circled areas are where we are going to be mounting:

http://www.pololu.com/catalog/product/256 Wheels

NOTE: The picture shown here is the prototype, the one you will be making will differ for some parts.

Gearbox Ball Caster, sensors (front end)

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; add the spacer to give it enough height so that the platform stays level with the ground (or you can leave it out as long as the sensors that will be mounted are not too close to the ground). Then add the ball caster and use the bolts and nuts to mount it to the chassis. There is an instructions manual to put the ball caster together that came in the box. 3

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. 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 3 holes (2 of them labeled A and B) towards the front of the gearbox housing and the one lone hole near the motors 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)

The hole that doesnt go all the way through (for outside pieces)

Hole C is where the axel will go for the wheels to properly fit onto the chassis. 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, 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 7

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, 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) 8

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 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: 9

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.

10

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: 11

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)

12

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"); 13

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; }

14

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 15

{ 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 16

#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 17

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 18

} //--------------------------------------------------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 } }

19

You might also like