Problem with a robot

Good evening. We’re a university robotics team. We’re competing in a line following competition with arduino uno. Below is the robot we’ve created. We’re using a QTR sensor, but we’re experiencing some problems. The robot was functioning normally, following the line in line following. Through the calibrate that was done we got results from the serial monitor but there everything seems to be fine. As of yesterday it does not respond to the line. Below is the code we’re using. Could you help me identify the problem?

#include <QTRSensors.h>

QTRSensors qtr;
const uint8_t SensorCount = 8;
uint16_t sensorValues[SensorCount];

float Kp = 0.08;
float Ki = 0.01;
float Kd = 0.03; 


float kdPrev=Kd; 
float kpPrev=Kp;
//int button_pin = 12;


uint8_t maxSpeed = 255;
uint8_t preSpeed = maxSpeed;
const uint8_t minSpeed = 0;

int ENA = 5; // The pins that control the speed and direction of motors
int IN1 = 8;
int IN2 = 9;
int IN3 = 7;
int IN4 = 6;
int ENB = 10;

float eprev = 0;
unsigned long prevT;
float eintegral = 0;

bool robotMoving = false; // Flag to indicate if the robot should be moving

void setup() {
  Serial.begin(9600);
  delay(500);
  pinMode(ENA,OUTPUT);
  pinMode(IN1,OUTPUT);
  pinMode(IN2,OUTPUT);
  pinMode(ENB,OUTPUT);
  pinMode(IN3,OUTPUT);
  pinMode(IN4,OUTPUT);
  pinMode(ENA,OUTPUT);
  pinMode(19,INPUT);
  pinMode(18,INPUT);
  pinMode(17,INPUT);
  pinMode(16,INPUT);
  pinMode(15,INPUT);
  pinMode(14,INPUT);
  pinMode(3 ,INPUT);
  pinMode(4 ,INPUT);

  // Initialize sensors
  qtr.setTypeRC();
  qtr.setSensorPins((const uint8_t[]){19, 18,17, 16, 15, 14, 3,4}, SensorCount);
//14, 15, 16, 17, 18, 19, 20, 21
//  pinMode(button_pin, INPUT_PULLUP); // Use internal pull-up resistor
  pinMode(LED_BUILTIN, OUTPUT);

  calibration();
  Forward(0, 0);
  delay(500);

  prevT = millis(); // Initialize prevT here
}

void loop() {
    setSpeed(eprev, prevT, eintegral);

}

void calibration() {
  digitalWrite(LED_BUILTIN, HIGH);
  for (uint16_t i = 0; i < 400; i++) {
    qtr.calibrate();
    delay(20); // Add a small delay to allow calibration to proceed smoothly
    Serial.println("wait");
  }
  digitalWrite(LED_BUILTIN, LOW);
}

void setSpeed(float& eprev, unsigned long& prevT, float& eintegral) { 
  // Time difference
  unsigned long currT = millis();
  float deltaT = ((float)(currT - prevT)) / 1000.0;

  uint16_t position = qtr.readLineBlack(sensorValues); // Read the current position
  // Error
  int e = 3500- position; // 3500 is the ideal position (the center)
//   Serial.println(position);
  // Derivative
  float dedt = (e - eprev)/ deltaT;
  //float dedt = (e - eprev);

  // Integral with windup guarding
  eintegral += e * deltaT;
  eintegral = constrain(eintegral, -1000.0, 1000.0); // Limit the integral term to prevent windup

  
  if(position == 7000 || position == 0){float kdPrev=Kd; float kpPrev=Kp; int preSpeed = maxSpeed;  maxSpeed = 150; Kp=0.08; Kd=0.03
  
  ;}
 

// Control signal
  float u = Kp * e + Kd * dedt + Ki * eintegral;

  int rightSpeed = maxSpeed + u;
  int leftSpeed = maxSpeed - u-40;
  if(position == 7000 || position == 0){Kd=kdPrev; Kp=kpPrev; maxSpeed=preSpeed;}
  
  // Constrain the motor speeds
  rightSpeed = constrain(rightSpeed, minSpeed, maxSpeed);
  leftSpeed = constrain(leftSpeed, minSpeed, maxSpeed);
//if(abs(e-eprev)<3000){
  Forward(leftSpeed, rightSpeed); // Use the Forward function to set motor speeds
//}
  //Serial.print(leftSpeed);
  //Serial.print(" ");
  //Serial.print(rightSpeed);
    //Serial.print(" ");
  Serial.println(position);

  eprev = e;
  prevT = currT;}
//}

void Forward(int speedA, int speedB) {
  analogWrite(ENA, speedB);
  digitalWrite(IN2, LOW);
  digitalWrite(IN1, HIGH);
  analogWrite(ENB, speedA);
  digitalWrite(IN4, HIGH);
  digitalWrite(IN3, LOW);}

I can’t really look at your code and point to an obvious bug but maybe there are things you can do to help debug the issue?

  • Maybe start by putting your current code aside and use one of the examples that Pololu includes with the QTRSensors Library and make sure that you have the QTR sensor wired up correctly before adding in the PID loop code.
  • How are you calibrating the sensor? When the calibration() routine is running, do you move your robot left and right across the black line so that each sensor performs white and black readings during the calibration process? You could also modify the calibration() routine to simultaneously rotate the robot 90 degrees to the left and then 90 degrees to the right while calling qtr.calibrate() so that each sensor will see the black line and the white background during the calibration process.
  • Are you sure that you have specified the correct array for the pins in the qtr.setSensorPins() call? The reason I ask is that the pin order in your array seems kind of random.
  • If you had working code at one point in time and then made a change that later broke it then I recommend learning how to use a source control system like git so that you can keep snapshots of your code around to roll back to when things stop working and look at the differences to narrow in on the cause.
1 Like