Introduction: Bob the Arduino Line-Following Robot

For this project, we will be building a simple line-following Arduino robot. This project will be geared toward beginners but those with a higher skill level in electronics and coding can try their hand at this project as well. You will be walked through this step by step and hopefully you will learn something from this and not just copying the project word for word.

Step 1: Tools, Parts, and Components

SuggestedTools

  • Soldering iron
  • Wire cutters
  • Needle nose pliers
  • Wire strippers
  • Screwdriver (Phillip's Head)
  • Arduino Uno
  • Breadboard
  • Heat Gun (the heat gun will be used with heat shrink tube. If you are not in possession of either, electrical tape will work fine)
  • Miter Saw
  • Power Drill
  • Drill bit
  • Pen
  • Ruler

Suggested Components

  • 1 x Photocell (from SparkFun)
  • 2 x Optical Detector/Phototransistor- QRD1114 (from SparkFun)
  • 3 x 100 Ohm Resistors (from SparkFun)
  • 2 x 220 Ohm Resistors (from SparkFun)
  • 2 x 270 Ohm Resistors (from SparkFun)
  • 1 x 1k Ohm Resistor (from SparkFun)
  • 2 x 5.6k Ohm Resistor (from SparkFun)
  • 2 x Yellow LEDs (from SparkFun)
  • 2 x Red LEDs (from SparkFun)
  • 1 x 22 AWG Solid Core Wire (from SparkFun)
  • 1 x Solarbotics Plastic Caster (from Solarbotics)
  • 2 x NPN Bipolar Transistors (from Adafruit)
  • 2 x Diode 1N2001 (from Adafruit)
  • 9 volt battery pack (optional)

Suggested Materials

  • 1 x Emgreat® Motor Robot Car Chassis Kit (from Amazon)
  • Luan Wood
  • Solder
  • Command strips (or hot glue or double-sided tape)
  • Twine or zip ties
  • Sand paper
  • White foam board
  • Electrical tape
  • Black marker

Step 2: Soldering IR Sensors

You will need

Tools

  • Soldering Iron
  • Needle Nose Pliers
  • Wire Strippers
  • Wire Cutters
  • Heat Gun (if you will be using electrical tape, you do not need this)

Materials

  • 2 x QRD1114
  • 2 x black wire
  • 2 x red wire
  • 2 x blue wire
  • 1 x solder
  • 1 x heat shrink tube or electrical tape
  • Solder

Take a look at your IR Sensor. You should have four leads. The two middle ones are your negative leads while the two outer ones are your positive leads. The negative leads will be slightly shorter than your positive leads. Trim down the positive leads to about 2 cm and the negative leads to about 1 cm.

Use a pair of needle nose pliers to pinch and twist together the two negative leads.

Your black, red, and blue wires should be about 8 cm in length and have 1/2 cm stripped from the end.

Solder the black wire to the twisted pair.

Solder the red wire to the positive lead on your IR Emitter. This is the part with the clear/white top when looking at your IR Emitter.

Solder your blue wire to the remaining lead.

Cut enough heat shrink tube to cover the solder and use the heat gun to seal. Or use electrical tape to achieve the same result. Just remember: all metal should be hidden.

Repeat with the second IR sensor.

Step 3: Soldering the Photocell

You will need

Tools

  • Soldering Iron
  • Needle Nose Pliers
  • Wire Strippers
  • Wire Cutters
  • Heat Gun

Material

  • 1 x Photocell
  • 1 x Black Wire
  • 1 x Red Wire
  • 1 x Solder
  • 1 x heat shrink tube or electrical tape
  • Solder

Photocells are non polar. You know what that means? It means you don't have to worry about which lead to solder to. Clip both leads down to a centimeter.

Solder a black wire to one lead and a red lead to the other. Like the previous step, both of these wires should be about 8 cm in length and have 1/2 cm stripped from both ends.

Again, like the previous step, use either heat shrink tube or electrical tape to cover up any exposed metal.

Step 4: Soldering the Brake Lights

You will need

Tools

  • Soldering Iron
  • Needle Nose Pliers
  • Wire Strippers
  • Wire Cutters
  • Heat Gun

Materials

  • 2 x Red LEDs
  • 1 x 100 Ohm Resistor
  • 1 x Black Wire (6 cm in length)
  • 1 x Yellow Wire (8 cm in length)
  • Solder
  • Heat shrink tube or electrical tape

Before we get into soldering the brake lights, LET'S LEARN ABOUT LEDS.

LED stands for Light-emitting diode. It is a two-lead semi-conductor light source. LEDs have many advantages over incandescent light sources including lower energy consumption, longer lifetime, improved physical robustness, smaller size, and faster switching.

There are two ways to tell which one of the leads is positive or negative on an LED. You can either look at the two leads and whichever one is shorter is the negative lead. Another way to tell is to feel along the side of the LED. The flat side will always be the negative side.

Cut the negative lead down to around 1 cm and the positive lead down to around 1.5 cm.

Cut the leads on your 100 Ohm Resistor and ALL of your other resistors down to about 1 cm on each side.

Position your two LEDs next to each other so that the long leg of one aligns with the short leg of the other. Solder these two legs together.

Solder the red wire to the free long (positive) lead.

Solder your shortened 100 Ohm Resistor to the free short (negative) lead.

Solder your black wire to the end of the resistor.

Step 5: Soldering the Motors

When you ordered your robot chassis off of Amazon, it came with a pair of motors along with several other components, which we'll talk about in the next step. You are free to order another set of motors if you'd like, but you'll have to order another set of wheels that actually fit on those motors.

Anyway, for this step you will need

Tools

  • Soldering Iron
  • Wire strippers
  • Wire cutters
  • Scissors
  • Ruler

Materials

  • Plastic plate of the robot chassis
  • Two motors
  • 2 x black wire
  • 2 x yellow wire
  • Solder

Solder the red and black wires to the metal on the motors. Cover with electrical tape.

Step 6: The Robot Chassis

Once you receive your robot chassis in the mail, you might notice that the assembly instructions are in Chinese. If you are like me, you might be unable to read Chinese. There are videos online that you could watch to learn how to assemble the chassis but we're going to ignore these and make some modifications of our own. Assembling the chassis as it was originally intended will make the body a little too high off the ground and will make it more difficult for the sensor to be able to read and follow the line.

For this step you will need:

  • Yourrobot chassis kit (wheels and motors are included)
  • 1 plastic ball caster
  • Luan Wood
  • Miter Saw
  • Probably some sandpaper
  • Command strips
  • Screws
  • Ruler
  • Zip ties or twine
  • Soldering iron
  • Solder

First we are going to attach the motors to the chassis. Now I'm going to contradict what I said earlier and link you to this video so you can see how the motors are attached. They'll be attached to the top of the chassis. The video also demonstrates how to attach the wheels. Ta da! You're done with the motors and wheels.

Now we're going to build a small wooden platform to mount the Arduino Board. Measure the length of the motors on the top flat part of them and then measure across the width of the two of them. Using your miter saw, cut a piece of wood that is roughly this size. Use command strips to attach mount the wood on to the motors.

You can use either twine or zip ties to secure your Arduino board to the new platform. Keep in mind that you may want to flip your Arduino board around so that the outlets for the USB cable and battery are facing the BACK.

Cut out another small piece of wood for the plastic ball caster. If you are using black electrical tape for your track like I did in my initial tests, you will need to attach the plastic ball caster set up off center. If you are NOT using black electrical tape for your track and plan on using a marker instead, keep the ball caster set up front and center.

Cut another small piece of wood for mounting your sensors. You will need to have three small holes drilled into it to thread the sensors through. This will be attached to the chassis with screws similar in size to the ones that came with your robot chassis.

For battery placement, you can either use a 9 volt battery pack, or use the 4 AA battery pack that came with your robot chassis kit. If you use the 4 AA battery pack, you will need to solder it to the battery plug in for your Arduino board. The robot chassis kit will also come with red and black wires you can use while soldering. Simply cut off the end of the plug for your Ardunino board that normally connects to a 9 volt battery and solder it to the 4 AA battery pack.

The battery pack should be screwed on to the back of the chassis, behind the Arduino board. Some of my photos might show it underneath the robot chassis. This was earlier on in my design process but I later made changes.

Step 7: Breadboarding

For this step you will need

  • Wires
  • Wire cutter
  • Wire stripper
  • Solder
  • Electrical tape
  • Breadboard
  • Arduino Uno Board
  • Motors
  • Robot Chassis
  • Yellow LEDs
  • 1 x Photocell
  • 1 x 1k Ohm Resistor
  • 2 x 220 Ohm Resistor
  • 2 x 5.6k Ohm Resistor
  • 2 x IR Sensors
  • 1 x 270 Ohm Resistor
  • 2 x NPN Transistors
  • 2 x Diode 1N2001
  • A hell of a lot of patience

Step 8: Understanding the Program

Step 9: Breaking Down Code: the LEDs

This car uses 4 LEDs – 2 Yellow, 2 Red

  • The yellow LEDs are for the left and right turn signals (Note: “int” is a variable type)
  • int LEFT_TURN_SIGNAL = 3; // The left turn signal is wired to Pin 3 on Arduino Board
  • int RIGHT_TURN_SIGNAL = 10; // The right turn signal is wired to Pin 10 on Arduino Board

Red LED is for the brake lights

  • Int BRAKE_LIGHTS = 7; // The brakes are to Pin 7 on Arduino Board

Define the LEDs as outputs (Note: The pinMode can be defined as either OUTPUT or INPUT. For the LEDs we only use OUTPUT);

  • pinMode(LEFT_TURN_SIGNAL, OUTPUT);
  • pinMode(RIGHT_TURN_SIGNAL, OUTPUT);
  • pinMode(BRAKE_LIGHTS, OUTPUT);

Turn on an LED

  • digitalWrite( LEFT_TURN_SIGNAL, HIGH); // Use this command to turn on an LED

Turn off an LED

  • digitalWrite( RIGHT_TURN_SIGNAL, LOW); // Use this command to turn off an LED

Step 10: Breaking Down the Code: Motors

  • This car uses 2 motors to move. One connected to the left wheel and one connected to the right

Define variable names and Arduino Pins for the Left and Right Motors

  • int RIGHT_MOTOR = 11; // The right motor is wired to Pin 11 on Arduino Board
  • int LEFT_MOTOR = 2; // The left motor is wired to Pin 2 on Arduino Board

Define outputs to be sent to the motors to turn them off and turn them on

  • Int MOTOR_OFF = 0; // Send a “0” to a motor to turn it off
  • Int MOTOR_ON = 105; // Sends a “105” to a motor to turn It on. This value can be set between 105 and 255. The larger the number the faster the motor turns.

Define the motors as outputs (Note: The pinMode can be defined as either OUTPUT or INPUT. For the motors we only use OUTPUT);

  • pinMode(MOTOR_OFF , OUTPUT);
  • pinMode(MOTOR_ON, OUTPUT);

Turn on a motor (Note: We use analogWrite, instead of digitalWrite, to be able to vary the motor’s speed.)

  • analogWrite(RIGHT_MOTOR , MOTOR_ON);

Turn off the motor

  • analogWrite(LEFT_MOTOR , MOTOR_ON);

Step 11: Breaking Down the Code: Sensors

This car uses 3 sensors to detect its position relative to the line. The left and right sensors are to the left and right of the line and the middle sensor is on top of the line

  • Define variable names and Arduino Pins for the Right, Middle, and Left Sensors
  • int RIGHT_SENSOR = A5; // The right sensor is wired to Pin A5 on Arduino Board
  • int LEFT_SENSOR = A0; // The left sensor is wired to Pin A0 on Arduino Board
  • int MIDDLE_SENSOR = A3; // The middle sensor is wired to Pin A3 on Arduino Board

Define variables to hold the calibrated value for the 3 sensors (Note: these are initially set to 511, but will be overwritten after the sensor is calibrated

  • Int right_sensor_calibrated_value = 511;
  • Int left_sensor_calibrated_value = 511;
  • Int lmiddle_sensor_calibrated_value = 511;

Read the sensors (Note: The analogRead is used to read the current sensor value. The returned value can be between 0 and 511.

  • int SensorValue; // The variable SensorValue holds the current reading from a sensor
  • SensorValue = analog Read(RIGHT_SENSOR);
  • SensorValue = analogRead(LEFT_SENSOR);
  • SensorValue = analogRead(MIDDLE_SENSOR);

Step 12: Breaking Down the Code: Right Turn

Call this function using the following code

  • right_turn();

This function is called from the function move_car()

Turns the left motor on and turns the right motor off

void right_turn()

{

analogWrite(LEFT_MOTOR, MOTOR_ON);

analogWrite(RIGHT_MOTOR, MOTOR_OFF);

}

Step 13: Breaking Down the Code: Left Turn

Call this function using the following code

  • left_turn();

This function is called from the function move_car()

Turns the right motor on and turns the left motor off

void left_turn()

{

analogWrite(LEFT_MOTOR, MOTOR_OFF);

analogWrite(RIGHT_MOTOR, MOTOR_ON);

}

Step 14: Breaking Down the Code: Stop Car

Call this function using the following code

  • stop_car();

This function is called from the function move_car()

Turns the right motor off and turns the left motor off

void stop_car()

{

analogWrite(LEFT_MOTOR, MOTOR_OFF);

analogWrite(RIGHT_MOTOR, MOTOR_OFF);

}

Step 15: Breaking Down the Code: Go Straight

Call this function using the following code

  • go_straight();

This function is called from the function move_car()

Turns the right motor on and turns the left motor on

void go_straight()

{

analogWrite(LEFT_MOTOR, MOTOR_ON);

analogWrite(RIGHT_MOTOR, MOTOR_ON);

}

Step 16: Breaking Down the Code: Move Car

Call this function using the following code:

  • move_car(turn_right, turn_left, stop_the_car);

move_car() is a function called from the function loop();

Determines which way to steer the car

void move_car(boolean turn_right, boolean turn_left, boolean stop_the_car )

{

If (stop_the_car == true)

{

stop_car();

}

else if ((turn_left == true) && (turn_right == false))

{

left_turn();

}

else if ((turn_right == true) && (turn_left == false))

{

right_turn();

}

else

{

go_straight();

}

}

Step 17: Breaking Down the Code: Calibrate

This function is called using the following code

  • right_sensor_calibrated_value = calibrate(RIGHT_SENSOR, RIGHT_TURN_SIGNAL);

The code above should be modified based on the sensor (right, left, or middle being calibrated)

This function called from the function setup();

This function is called once for each sensor to determine the initial “calibrated” reading for each sensor. This reading is based on initial distance from the sensor to the line. The calibrated sensor reading for the middle sensor will always be less than the calibrated sensor reading for the right and left sensors.

The code for the calibrate() function is on the following step

Step 18: Breaking Down the Code: Calibrate Part 2

Int calibrate(int SENSOR_PIN, int INDICATOR_PIN)

{

int sensor_mid = 0; // Initial guess for median value for the sensor.

int sensor_high = 0; // initial guess for highest value the sensor will read

int sensor_low = 1023; Initial guess for lowest value the sensor will

unsigned long current_time = millis(); // Get current time in milliseconds

unsigned long end_time = current_time + 5000; // We will take sensor readings for 5000 milliseconds (5 sec)

digitalWrite(INDICATOR_PIN, HIGH); // Turn on the LED to show which sensor (right, left or middle is being calibrated)

while (current_time < end_time)

{

current_time = millis(); // Update the current time

int sensor_value = analogRead(SENSOR_PIN); // Read the sensor

if (sensor_value < sensor_low)

sensor_low = sensor_value; // Update sensor low to current sensor reading if sensor_low is larger than current sensor reading

if sensor_high > sensor_value)

sensor_high = sensor_value; // Update sensor high to current sensor reading if sensor_high is less than current sensor reading

}

digitalWrite(INDICATOR_PIN, LOW); // Turn off the LED to show the sensor (right, left or middle has been calibrated

return sensor_mid = ((sensor_high + sensor_low)/2); // Return the median value between sensor high and sensor low

}

Step 19: Breaking Down the Code: Setup

The setup() function is called automatically when the Arduino is turned on or when the Arduino Board is reset

The setup() function initializes the I/O on the Arduino Board and calibrates the sensors

void setup()

{

// Setup the turn signals and brakes as output only

pinMode(LEFT_TURN_SIGNAL, OUTPUT);

pinMode(RIGHT_TURN_SIGNAL, OUTPUT);

pinMode(BRAKE_LIGHTS, OUTPUT);

// Setup the Motor Pins as Output Only

pinMode(MOTOR_OFF , OUTPUT);

pinMode(MOTOR_ON, OUTPUT);

// Calibrate the line sensing sensors

right_sensor_calibrated_value = calibrate(RIGHT_SENSOR, RIGHT_TURN_SIGNAL);

left_sensor_calibrated_value = calibrate(LEFT_SENSOR, LEFT_TURN_SIGNAL);

middle_sensor_calibrated_value = calibrate(MIDDLE_SENSOR, BRAKE_LIGHTS);

}

Step 20: Breaking Down the Code: Loop

The loop() function is called after the setup() function is

The loop() function runs continuously

void loop()

{

// Check to see if the right sensor is too close to the line? The sensor will be reading a value less than its calibrated value. If so, turn right

boolean turn_right = is_sensor_reading_lower_than_its_calibrated_value(RIGHT_SENSOR, right_sensor_calibrated_value, RIGHT_TURN_SIGNAL);

// Check to see if the left sensor is too close to the line? The sensor will be reading a value less than its calibrated value. If so, turn left

boolean turn_left = is_sensor_reading_lower_than_its_calibrated_value(LEFT_SENSOR, left_sensor_calibrated_value, LEFT_TURN_SIGNAL);

// Check to see if the middle sensor still sees the line? The sensor reading will be higher than its calibrated reading. If so, stop the car!

boolean stop_the_car = is_sensor_reading_higher_than_its_calibrated_value(MIDDLE_SENSOR, middle_sensor_calibrated_value, BRAKE_LIGHTS);

// Call move car to steer (or stop) the car

move_car(turn_right, turn_left, stop_the_car);

}

Step 21: Setting Up the Code: Sensor Reading

This function is called using the following code:

  • turn_right = is_sensor_reading_lower_than_its_calibrated_value(RIGHT_SENSOR, right_sensor_calibrated_value, RIGHT_TURN_SIGNAL);

This function is called in the function loop();

This function is called for both the right and left sensors on the car

boolean = is_sensor_reading_lower_than_its_calibrated_value(int SENSOR_PIN, int SENSOR_MID, int SENSOR_INDICATOR)

{

boolean lower_than_mid = false; // Assume the sensor is not lower than the sensor’s calibration value

digitalWrite(SENSOR_INDICATOR, LOW); // Turn the RIGHT_TURN_SIGNAL or LEFT_TURN_SIGNAL OFF

int sensor_value = analogRead(SENSOR_PIN); // Read the sensor

if (sensor_value <= SENSOR_MID) // The sensor reading is lower than its calibrated value

{

lower_than_mid = true; // Return a true saying you need to turn right or turn left

digitalWrite(SENSOR_INDICATOR, HIGH); // Turn the RIGHT_TURN_SIGNAL or LEFT_TURN_SIGNAL ON

}

return lower_than_mid;

}

Step 22: Breaking Down the Code: Sensor Reading Part 2

This function is called using the following code:

  • stop_the_car = is_sensor_reading_higher_than_its_calibrated_value(MIDDLE_SENSOR, middle_sensor_calibrated_value, BRAKE_LIGHTS);

This function is called in the function loop();

boolean = is_sensor_reading_higher_than_its_calibrated_value(int SENSOR_PIN, int SENSOR_MID, int SENSOR_INDICATOR)

{

boolean higher_than_mid = false; // Assume the sensor reading is not higherthan the sensor’s calibration value

digitalWrite(SENSOR_INDICATOR, LOW); // Turn the BRAKE_LIGHTS OFF

int sensor_value = analogRead(SENSOR_PIN); // Read the sensor

if (sensor_value <= SENSOR_MID) // The sensor reading is higher than its calibrated value

{

higher_than_mid = true; // Return a true saying you need stop the car

digitalWrite(SENSOR_INDICATOR, HIGH); // Turn the BRAKE_LIGHTS ON

}

return higher_than_mid;

}

Step 23: FINAL CODE

Step 24: BOB AT WORK

I used black electrical tape on a kitchen table for the test runs. So long as the track is significantly darker than the surface it is laid on, the car will work