Line Following robot
In school we had a project of building a robot which main task should be to follow a line on the floor. We built it in LEGO and merged LEGO motors with our own wires to make it easier to control speed and steering.
The whole 'car' is designed from scratch by myself. It is a basic car with four sides and two motors, each to control a wheel. We tried with a four wheel design but it failed at turning fast and elegant. We ended up with a third wheel at the back which is not controlled by anything and can spin 360 degrees.
As you can see the third wheel turns nice and smooth without any problems.
To follow the line we used 2x OPB 702 reflective sensors. The idea with this sensor is that it send a beam of light down on the floor and then measure the light reflected back.
The idea for the robot is to make it follow a simple or advanced line. To find out what we needed we created a flow chart with our idea.
A bit more complex task was to create the right circuit so we did not burn any of the components of. Our power source was 2x 9V batteries. The LEGO motors runs on 9V but the rest of our circuit only need 5V. So we added a transformer to get the right voltage output. Here is an image of the circuit. It is bad quality and not commented in anyway but i cant find the original file so you have to do with this.
#pragma config =0x3fdf //MCLRE =off
#pragma config &=0x3ff7 //wdt =off
#pragma config &=0x3ffc //intrc-osc-clkout off
#include "int16CXX.h"
bit rc4 @PORTC.4; //We define PORTC.4 to be rc4
bit rc6 @PORTC.6; //We define PORTC.6 to be rc6
void stop();
void koerFrem(); // Move forward
void koerBag(); // Move backwards
void drejLV(); // Turn Left
void drejLH(); // Turn Right
void main() {
//porte initialiseres
TRISC.0 = 0; //Outgoing Ports
TRISC.1 = 0;
TRISC.2 = 0;
TRISC.3 = 0;
TRISC.4 = 1; //Incoming Ports
TRISC.6 = 1;
ANSEL=0; //port A digital
ANSELH=0;
//Main loop
while(1) {
PORTC.0 = 0; //We start by turning off all the ports
PORTC.1 = 0; //Our PORTC.0-3 is basically '+' and '-' on motor 1 and motor 2.
PORTC.2 = 0;
PORTC.3 = 0;
if(!rc4 && rc6){ // If the right sensor is outside the line and the left sensor is inside the line, then we are turning right
drejLH();
}
if(rc4 && !rc6) { // If the left sensor is outside the line and the right sensor is inside the line, then we are turning left
drejLV();
}
if(!rc4 && !rc6) { // If both sensors is outside the line, then we are moving forward
koerFrem();
}
if(rc4 && rc6) { //If both sensors is inside the line, then we are moving forward
koerFrem();
}
}
}
// erklæring af metoden
void stop() { //If we are at a stop, no ports should be open.
PORTC.0=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=0;
}
void koerFrem() { //If we want to move forward then we need to have one port on each motor open.
PORTC.0=1;
PORTC.1=0;
PORTC.2=1;
PORTC.3=0;
}
void koerBag() { //If we want to move backwards then we need the opposite ports to be open.
PORTC.0=0;
PORTC.1=1;
PORTC.2=0;
PORTC.3=1;
}
void drejLV() { //Then we are turning we need to have one port open on motor 1 and the opposite port open on motor 2. We could also have just one port open but it would be a slow turn.
PORTC.0=0;
PORTC.1=1;
PORTC.2=1;
PORTC.3=0;
}
void drejLH() { //The opposite of void drejLV
PORTC.0=1;
PORTC.1=0;
PORTC.2=0;
PORTC.3=1;
}
#pragma config &=0x3ff7 //wdt =off
#pragma config &=0x3ffc //intrc-osc-clkout off
#include "int16CXX.h"
bit rc4 @PORTC.4; //We define PORTC.4 to be rc4
bit rc6 @PORTC.6; //We define PORTC.6 to be rc6
void stop();
void koerFrem(); // Move forward
void koerBag(); // Move backwards
void drejLV(); // Turn Left
void drejLH(); // Turn Right
void main() {
//porte initialiseres
TRISC.0 = 0; //Outgoing Ports
TRISC.1 = 0;
TRISC.2 = 0;
TRISC.3 = 0;
TRISC.4 = 1; //Incoming Ports
TRISC.6 = 1;
ANSEL=0; //port A digital
ANSELH=0;
//Main loop
while(1) {
PORTC.0 = 0; //We start by turning off all the ports
PORTC.1 = 0; //Our PORTC.0-3 is basically '+' and '-' on motor 1 and motor 2.
PORTC.2 = 0;
PORTC.3 = 0;
if(!rc4 && rc6){ // If the right sensor is outside the line and the left sensor is inside the line, then we are turning right
drejLH();
}
if(rc4 && !rc6) { // If the left sensor is outside the line and the right sensor is inside the line, then we are turning left
drejLV();
}
if(!rc4 && !rc6) { // If both sensors is outside the line, then we are moving forward
koerFrem();
}
if(rc4 && rc6) { //If both sensors is inside the line, then we are moving forward
koerFrem();
}
}
}
// erklæring af metoden
void stop() { //If we are at a stop, no ports should be open.
PORTC.0=0;
PORTC.1=0;
PORTC.2=0;
PORTC.3=0;
}
void koerFrem() { //If we want to move forward then we need to have one port on each motor open.
PORTC.0=1;
PORTC.1=0;
PORTC.2=1;
PORTC.3=0;
}
void koerBag() { //If we want to move backwards then we need the opposite ports to be open.
PORTC.0=0;
PORTC.1=1;
PORTC.2=0;
PORTC.3=1;
}
void drejLV() { //Then we are turning we need to have one port open on motor 1 and the opposite port open on motor 2. We could also have just one port open but it would be a slow turn.
PORTC.0=0;
PORTC.1=1;
PORTC.2=1;
PORTC.3=0;
}
void drejLH() { //The opposite of void drejLV
PORTC.0=1;
PORTC.1=0;
PORTC.2=0;
PORTC.3=1;
}
This is a really basic program and anyone who have done a small amount of C knows all we have done here. The PORTC, TRISC and ANSEL are all values that out PICKit 2.0 16F690 can understand. It is a very primitive computer that we use to the program.
It took us a lot of time to debug it. First the program which we though had something wrong because the sensors wasn't working probably and then the circuits on our board. When we where completely sure it was all without any bugs we added two adjustable resistors. By turning on them we can adjust the distance from the sensor, the robot, to the floor, the line and that way we don't have to move the sensors when we change the surface we are driving on. Each surface have a different degree of reflection and therefore we need to adjust the sensors when changing surface.
The last thing we did was adding a switch so we didn't have to remove our batteries all the time.

This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.