PID LINE FOLLOWER ROBOT USING ARDUINO NANO
by EDISON SCIENCE CORNER in Circuits > Arduino
17892 Views, 53 Favorites, 0 Comments
PID LINE FOLLOWER ROBOT USING ARDUINO NANO
Hello there
Most mechatronics or robotics lovers may be started their robotics building journey by making a line follower robot. Because line follower robots are very easy to make and fascinating. I started making line follower robots from my high school. I tried different designs to improve speed and stability. Later I realized and learned speed and stability not only depends on the design it depends also on the algorithm. Here I am going to show you how I designed and made my first line follower robot with the PID algorithm. So let's get started.
Supplies
Arduino Nano
QTR 8 RC
DRV8835
https://www.pololu.com/product/2135
N20 motors and clamp *2
AMS 1117 5.0 regulator*1
button switch*2
0805 SMD led*2
0805 1k resistor *2
0805 10k resistor *2
7.4volt battery
castor wheel
What Is PID Algorithm
While a line-following robot may not be the newest project idea but stability and speed matter here. Line following robots is one of the most simplistic types of robots that performs a simple task: tracking a black or a white line on a white, respectively on a black surface. To get a good speed and stability let's use PID Algorithm. Thanks to PID control feedback instead of the more traditional bang-bang control you see in low-end robots.
If the idea of PID is new to you, the acronym stands for proportional, integral, and derivative. To determine the output at any given time, you look at where you are compared to where you want to be (the present value vs the set point). Then you compute a proportional error. lets talk about this in later
Designing the Circuit and PCB Printing
As always everything started from designing the circuit I used easyeda to design circuit. Here I used Arduino nano, DRV 8835 motor driver, and QTR 8RC IR sensor array. Then I designed PCB with that circuit and at that time I decided to use the PCB also as the chase of the robot so I made PCB just like a chase.
After that, I downloaded the Gerber file and uploaded it to JLCPCB to print PCB. I choose JLCPCB because they offer only 2$ for 5 PCBs. After uploading I customised the PCB and placed the order.
download Gerber file from here
Assembling the PCB
After 1 week I received the pack. PCB looks awesome and the quality is also perfect. Now it's time to solder all components. I started with SMD components. After completing that I placed through-hole components and soldered them. Then I used female header pins to connect the modules. To control the bot I am using Arduino nano to drive the motors here I am using Pololu drv8835 motor drive. To sense the line I am using qtr 8rc IR reflective array. Then I placed every module on its sockets.
Finishing the Line Follower Robot
After that, I took the n20 motor and with the help of motor clamps I fixed motors into PCB also connected its wires to corresponding sockets. Then I attached small rubber tyres to the motor. To avoid grip and to give the necessary gap between ground and sensor I placed a castor wheel in front of the robot.
Programming the Arduino Line Follower Robot
As i said earlier I am using the QTR sensor and PID algorithm. so in the program first I included the qtr8rc library of Pololu.
#include <QTRSensors.h>
Then with the help of the QTR library functions, i defined the sensors and other parameters
QTRSensors qtr;
const uint8_t SensorCount = 8;
uint16_t sensorValues[SensorCount];
Then I defined the ki, kp, kd constants. We should find the values of the constants by the trial and error method.
float Kp = 0;
float Ki = 0;
float Kd = 0;
int P;
int I;
int D;
int lastError = 0;
boolean onoff = false;
Next, I defined constant for defining the maximum and minimum speed of the robot. Also, I defined the pins for the motor driver and button
int mode = 8;
int aphase = 9;
int aenbl = 6;
int bphase = 5;
int benbl = 3;
int buttoncalibrate = 17
int buttonstart = 2;
In the setup section, I defined the pin modes and added the calibration programme
Serial.begin(9600);
qtr.setTypeRC();
qtr.setSensorPins((const uint8_t[]){10, 11, 12, 14, 15, 16, 18, 19}, SensorCount);
qtr.setEmitterPin(7);
pinMode(mode, OUTPUT);
pinMode(aphase, OUTPUT);
pinMode(aenbl, OUTPUT);
pinMode(bphase, OUTPUT);
pinMode(benbl, OUTPUT);
digitalWrite(mode, HIGH);
delay(500);
pinMode(LED_BUILTIN, OUTPUT);
boolean Ok = false;
while (Ok == false) {
if(digitalRead(buttoncalibrate) == HIGH)
{
calibration();
Ok = true;
}
}
forward_brake(0, 0);
}
void calibration() {
digitalWrite(LED_BUILTIN, HIGH);
for (uint16_t i = 0; i < 400; i++)
{
qtr.calibrate();
}
digitalWrite(LED_BUILTIN, LOW);
}
Finally in the loop section
I read the values of the qtr 8rc sensor and driver motors according to the readings of the qtr sensors.
if(digitalRead(buttonstart) == HIGH) {
onoff =! onoff;
if(onoff = true) {
delay(1000);
}
else {
delay(50);
}
}
if (onoff == true) {
PID_control();
}
else {
forward_brake(0,0);
}
}
void forward_brake(int posa, int posb) {
digitalWrite(aphase, LOW);
digitalWrite(bphase, HIGH);
analogWrite(aenbl, posa);
analogWrite(benbl, posb);
}
void PID_control() {
uint16_t position = qtr.readLineBlack(sensorValues);
int error = 3500 - position;
P = error;
I = I + error;
D = error - lastError;
lastError = error;
int motorspeed = P*Kp + I*Ki + D*Kd;
int motorspeeda = basespeeda + motorspeed;
int motorspeedb = basespeedb - motorspeed;
if (motorspeeda > maxspeeda) {
motorspeeda = maxspeeda;
}
if (motorspeeda < 0) {
motorspeeda = 0;
}
if (motorspeedb < 0) {
motorspeedb = 0;
}
forward_brake(motorspeeda, motorspeedb);
}