Line Follower Robot

Line Follower Robot (LFR) is a simple robot concept that is autonomously guided to follow a line, that is drawn over white surface as dark lines or over a considerably dark surface as white lines. These lines are detected via the Reflectance Sensor Module on the robot. The code uses a PID algorithm in order to actuate motors, deciding whether turn left or right. The robot smoothly follows the line with these decisions of slight turns.

We used an Arduino board on the robot as the microcontroller for running the SMD Arduino Library codes.

Here is the Arduino codes of the project:

#include <Acrome-SMD.h>

#define BAUDRATE    115200


Red redLeft(1, Serial, BAUDRATE);
Red redRight(0, Serial, BAUDRATE); 

uint8_t Sensor[1]={iQTR_1};
int16_t X[3];
int Error,DeltaError,IterationP,IterationD,PrevError,PD;

float kp=0.13;
float kd=0.38;
short MainSpeed=100;


void setup() {
  redLeft.begin();
  redRight.begin();
  redLeft.setOperationMode(PWMControl);
  redRight.setOperationMode(PWMControl);
  redLeft.torqueEnable(1);
  redRight.torqueEnable(1);
  redRight.setConnectedModules(Sensor, 1);
}


void loop() {
  LinePos();
  PD2PWM();
}


void LinePos() {
  QTRValues qtrValues = redRight.getQTR(1);

  uint32_t WeightedSum=0,SensorSum=0;
  float PosValue=0;

  WeightedSum=(int32_t)(qtrValues.MiddleValue)*1000+(int32_t)(qtrValues.RightValue)*2000;
  SensorSum= qtrValues.LeftValue+qtrValues.MiddleValue+qtrValues.RightValue;
  PosValue=(float)(WeightedSum)/(float)(SensorSum);

  fPD(PosValue);
}


void fPD(int32_t PosValue) {
  Error= PosValue-1000;

  DeltaError=Error-PrevError;

  IterationP=kp*Error;
  IterationD=kd*DeltaError;

  PD=IterationP+IterationD;

  PrevError=Error;
}


void PD2PWM() {
  float RightPWM=(PD<0)?MainSpeed+PD:MainSpeed;
  float LeftPWM=(PD<0)?MainSpeed:MainSpeed-PD;
  
  RightPWM=(RightPWM>100)?100:RightPWM; RightPWM=(RightPWM<-MainSpeed)?-MainSpeed:RightPWM;
  LeftPWM=(LeftPWM>100)?100:LeftPWM; LeftPWM=(LeftPWM<-MainSpeed)?-MainSpeed:LeftPWM;
  
  redRight.setpoint(0,RightPWM);
  redLeft.setpoint(0,(-1)*LeftPWM);
}

Last updated