I am making a Line following robot using PID.
Hardware: L298N motor driver, arduino uno, 8 IR sensor array and two motors.
Problem: Bot is not working. I unable to know whether my code is right or wrong. Please help...
// PID constants
float Kp = 0.2; // Proportional gain
float Ki = 0.0; // Integral gain
float Kd = 1.0; // Derivative gain
int baseSpeed = 150; // Base speed for motors
int maxSpeed = 255; // Max motor speed
QTRSensors qtr; // Use QTRSensors with the latest QTR library
const uint8_t SensorCount = 8;
const uint8_t SensorPins[] = {10, 11, 12, A0, A1, A2, A4, A5}; // Define pins connected to each sensor
uint16_t sensorValues[SensorCount];
const int ENA = 5; // PWM for left motor
const int ENB = 6; // PWM for right motor
const int leftMotorForward = 3;
const int leftMotorBackward = 9;
const int rightMotorForward = 8;
const int rightMotorBackward = 7;
int lastError = 0;
float integral = 0;
void setup() {
Serial.begin(9600);
// Initialize QTRSensors
qtr.setTypeRC();
qtr.setSensorPins(SensorPins, SensorCount);
qtr.setTimeout(2500);
// Motor pins
pinMode(leftMotorForward, OUTPUT);
pinMode(leftMotorBackward, OUTPUT);
pinMode(rightMotorForward, OUTPUT);
pinMode(rightMotorBackward, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
// Set PWM to 0 initially
analogWrite(ENA, 0);
analogWrite(ENB, 0);
}
void loop() {
// Read sensor values
qtr.read(sensorValues);
// Calculate weighted position of the line
int position = calculateLinePosition(sensorValues);
int error = position - 3500; // Calculate error (3500 is center)
integral += error; // Accumulate the integral
int derivative = error - lastError; // Calculate the derivative
int controlSignal = (Kp * error) + (Ki * integral) + (Kd * derivative); // PID formula
// Calculate motor speeds
int leftSpeed = baseSpeed + controlSignal;
int rightSpeed = baseSpeed - controlSignal;
// Constrain speeds
leftSpeed = constrain(leftSpeed, 0, maxSpeed);
rightSpeed = constrain(rightSpeed, 0, maxSpeed);
// Move motors
moveMotors(leftSpeed, rightSpeed);
lastError = error; // Update lastError
delay(10); // Small delay for stability
}
int calculateLinePosition(uint16_t *sensorValues) {
int position = 0;
int totalValue = 0;
for (int i = 0; i < SensorCount; i++) {
position += sensorValues[i] * i * 1000; // Weighted position
totalValue += sensorValues[i];
}
if (totalValue > 0) {
position /= totalValue; // Normalize
} else {
position = 3500; // Default to center if no line is detected
}
return position;
}
void moveMotors(int leftSpeed, int rightSpeed) {
if (leftSpeed > 0) {
digitalWrite(leftMotorForward, HIGH);
digitalWrite(leftMotorBackward, LOW);
} else {
leftSpeed = abs(leftSpeed);
digitalWrite(leftMotorForward, LOW);
digitalWrite(leftMotorBackward, HIGH);
}
if (rightSpeed > 0) {
digitalWrite(rightMotorForward, HIGH);
digitalWrite(rightMotorBackward, LOW);
} else {
rightSpeed = abs(rightSpeed);
digitalWrite(rightMotorForward, LOW);
digitalWrite(rightMotorBackward, HIGH);
}
analogWrite(ENA, leftSpeed);
analogWrite(ENB, rightSpeed);
}
In the likely event that you did not write this code, please post a link to where you found it.
The question posted by @DaveX above is a very strong hint: the function probably won't work on an Arduino Uno due to integer overflow of the variables named position and totalValue.
That is a great start! You should be able to recognize the stupid mistakes made by ChatGPT.
All you have to do now is learn about the special functions used with Arduino, and the theory of robot navigation. Line following is one of the simplest approaches.
Well, wrap it in a test script and see if the results look sane. If it gives garbage then everything downstream is garbage-in-garbage-out until it is fixed.