Changes
Page history
Update Line Follower Code
authored
Jan 22, 2026
by
Emílio Manuel Dias Mateus
Show whitespace changes
Inline
Side-by-side
Line-Follower-Code.md
View page @
55109f17
[
main.cpp
](
uploads/ac3c66ce1deb109bfa5b4e25dd73e31e/main.cpp
)
\ No newline at end of file
````
#include:<Arduino.h>
#include <Wire.h>
#include <VL53L0X.h>
// Line Sensor Pins
const int PIN_IR_1 = 2;
const int PIN_IR_2 = 3;
const int PIN_IR_3 = 4;
const int PIN_IR_4 = 5;
const int PIN_IR_5 = 6;
// Motor Sensor Pins
const int PIN_MOTOR_L_IN1 = 10;
const int PIN_MOTOR_L_IN2 = 11;
const int PIN_MOTOR_R_IN1 = 13;
const int PIN_MOTOR_R_IN2 = 12;
// ToF Sensor Pins
const int PIN_SCL = 17;
const int PIN_SDA = 16;
// Velocity Settings
const int VEL_NORMAL = 75;
const int VEL_SEARCH = 62;
const int VEL_SLOW = 40;
const int VEL_FAST = 144;
const int VEL_REVERSE = -54;
// Time Settings for Obstacle Avoidance
const int TIME_LEFT = 700;
const int TIME_FORWARD = 1700;
const int TIME_RIGHT = 1500;
// Maximum Distance to Detect Obstacle
const int MAX_DISTANCE = 160;
// Objects and States
VL53L0X sensor;
bool robot_running = false;
int last_direction = 0;
// Function to Control Motor Speed and by PWM Values
void controlMotor(int pinIn1, int pinIn2, int pwm_val) {
pwm_val = constrain(pwm_val, -255, 255);
if (pwm_val > 0) {
analogWrite(pinIn1, pwm_val);
analogWrite(pinIn2, 0);
} else if (pwm_val < 0) {
analogWrite(pinIn1, 0);
analogWrite(pinIn2, -pwm_val);
} else {
analogWrite(pinIn1, 0);
analogWrite(pinIn2, 0);
}
}
// Function to Stop the Robot Motors
void stopRobot() {
controlMotor(PIN_MOTOR_L_IN1, PIN_MOTOR_L_IN2, 0);
controlMotor(PIN_MOTOR_R_IN1, PIN_MOTOR_R_IN2, 0);
}
// Function to Avoid Obstacle Detected by ToF Sensor
void avoidObstacle() {
stopRobot();
delay(250);
// Rotate Left
controlMotor(PIN_MOTOR_L_IN1, PIN_MOTOR_L_IN2, VEL_REVERSE);
controlMotor(PIN_MOTOR_R_IN1, PIN_MOTOR_R_IN2, VEL_NORMAL);
delay(TIME_LEFT);
// Go Forward
controlMotor(PIN_MOTOR_L_IN1, PIN_MOTOR_L_IN2, VEL_NORMAL);
controlMotor(PIN_MOTOR_R_IN1, PIN_MOTOR_R_IN2, VEL_NORMAL);
delay(TIME_FORWARD);
// Rotate Right
controlMotor(PIN_MOTOR_L_IN1, PIN_MOTOR_L_IN2, VEL_NORMAL);
controlMotor(PIN_MOTOR_R_IN1, PIN_MOTOR_R_IN2, VEL_REVERSE);
delay(TIME_RIGHT);
// Move Backward until Line is Found
bool lineFound = false;
while (!lineFound) {
controlMotor(PIN_MOTOR_L_IN1, PIN_MOTOR_L_IN2, VEL_NORMAL);
controlMotor(PIN_MOTOR_R_IN1, PIN_MOTOR_R_IN2, VEL_NORMAL);
// Check Line Sensors to Detect Line
if (!digitalRead(PIN_IR_2) || !digitalRead(PIN_IR_3) || !digitalRead(PIN_IR_4)) {
lineFound = true;
}
}
stopRobot();
delay(100);
}
// Robot Setup
void setup() {
Serial.begin(115200);
// I2C Setup
Wire.setSDA(PIN_SDA);
Wire.setSCL(PIN_SCL);
Wire.begin();
// Motor Pins Setup
pinMode(PIN_MOTOR_L_IN1, OUTPUT);
pinMode(PIN_MOTOR_L_IN2, OUTPUT);
pinMode(PIN_MOTOR_R_IN1, OUTPUT);
pinMode(PIN_MOTOR_R_IN2, OUTPUT);
// Line Sensor Pins Setup
pinMode(PIN_IR_1, INPUT);
pinMode(PIN_IR_2, INPUT);
pinMode(PIN_IR_3, INPUT);
pinMode(PIN_IR_4, INPUT);
pinMode(PIN_IR_5, INPUT);
// ToF Sensor Setup
sensor.init();
sensor.setTimeout(500);
sensor.startContinuous();
pinMode(LED_BUILTIN, OUTPUT);
delay(1000);
}
// Loop Function
void loop() {
// Toggle Robot State with BOOTSEL Button
if (BOOTSEL) {
robot_running = !robot_running;
digitalWrite(LED_BUILTIN, robot_running ? HIGH : LOW);
if (!robot_running) stopRobot();
delay(500);
}
if(!robot_running) return;
// Obstacle Detection and Avoidance
uint16_t distance = sensor.readRangeContinuousMillimeters();
if (distance > 0 && distance < MAX_DISTANCE) avoidObstacle();
// Line Following Logic
// Read Line Sensors Values
int s1 = !digitalRead(PIN_IR_1);
int s2 = !digitalRead(PIN_IR_2);
int s3 = !digitalRead(PIN_IR_3);
int s4 = !digitalRead(PIN_IR_4);
int s5 = !digitalRead(PIN_IR_5);
int motorL = 0;
int motorR = 0;
// Determine Motor Speeds Based on Sensor Readings
if (s3 && !s2 && !s4) {
motorL = VEL_NORMAL;
motorR = VEL_NORMAL;
last_direction = 0;
} else if (s3 && s2) {
motorR = VEL_SLOW;
motorL = VEL_NORMAL + 10;
last_direction = 1;
} else if (s3 && s4) {
motorR = VEL_NORMAL + 10;
motorL = VEL_SLOW;
last_direction = 2;
} else if (s2) {
motorR = 30;
motorL = VEL_NORMAL;
last_direction = 1;
} else if (s4) {
motorR = VEL_NORMAL;
motorL = 30;
last_direction = 2;
} else if (s1) {
motorR = VEL_REVERSE;
motorL = VEL_FAST;
last_direction = 1;
} else if (s5) {
motorR = VEL_FAST;
motorL = VEL_REVERSE;
last_direction = 2;
} else {
// In the case of No Line Detected, continue based on Last Direction
if(last_direction == 0){
motorL = VEL_SEARCH;
motorR = VEL_SEARCH;
} else if (last_direction == 1){
motorR = VEL_REVERSE;
motorL = VEL_NORMAL;
} else if (last_direction == 2){
motorR = VEL_NORMAL;
motorL = VEL_REVERSE;
}
}
// Set Motor Speeds
controlMotor(PIN_MOTOR_L_IN1, PIN_MOTOR_L_IN2, motorL);
controlMotor(PIN_MOTOR_R_IN1, PIN_MOTOR_R_IN2, motorR);
}```
````
\ No newline at end of file