Line following pololu QTR-8

Hi,

I'm using the pololu QTR-8 sensor to follow a line. This is my code:

#include <QTRSensors.h>

int motorRechtsSpeed = 6;
int motorlinksSpeed = 8;
int moterRechts = 7;
int moterLinks = 9;

int maxspeedrechts = 100;
int maxspeedlinks = 100;
int defaultspeedrechts = 50;
int defaultspeedlinks = 50;

// Change the values below to suit your robot's motors, weight, wheel type, etc.
#define KP .2
#define KD 5
//#define M1_DEFAULT_SPEED 50
//#define M2_DEFAULT_SPEED 50
//#define M1_MAX_SPEED 200
//#define M2_MAX_SPEED 200
#define MIDDLE_SENSOR 3

#define NUM_SENSORS  5     // number of sensors used
#define TIMEOUT       2500  // waits for 2500 us for sensor outputs to go low
#define EMITTER_PIN   2     // emitter is controlled by digital pin 2
#define DEBUG 0 // set to 1 if serial debug output needed

QTRSensorsRC qtrrc((unsigned char[]) {  21,20,19,18,17,16,15,14} ,NUM_SENSORS, TIMEOUT, EMITTER_PIN);

unsigned int sensorValues[NUM_SENSORS];

void setup()
{
  pinMode(moterRechts, OUTPUT);
  pinMode(moterLinks, OUTPUT);
  
  pinMode(motorRechtsSpeed, OUTPUT);
  pinMode(motorlinksSpeed, OUTPUT);
  
  digitalWrite(moterRechts, HIGH);
  digitalWrite(moterLinks, HIGH);
  delay(1000);
  manual_calibration(); 
  set_motors(0,0);
}

int lastError = 0;
int  last_proportional = 0;
int integral = 0;


void loop()
{
  unsigned int sensors[5];
  int position = qtrrc.readLine(sensors);
  int error = position - 2000;

  int motorSpeed = KP * error + KD * (error - lastError);
  lastError = error;

  int leftMotorSpeed = defaultspeedrechts + motorSpeed;
  int rightMotorSpeed = defaultspeedlinks - motorSpeed;

  // set motor speeds using the two motor speed variables above
  set_motors(leftMotorSpeed, rightMotorSpeed);
}

void set_motors(int motor1speed, int motor2speed)
{
  if (motor1speed > maxspeedrechts  ) motor1speed =  maxspeedrechts ; // limit top speed
  if (motor2speed > maxspeedlinks  ) motor2speed = maxspeedlinks; // limit top speed
  if (motor1speed < 0) motor1speed = 0; // keep motor above 0
  if (motor2speed < 0) motor2speed = 0; // keep motor speed above 0
  analogWrite(motorRechtsSpeed, motor1speed);   // set motor speed
  analogWrite(motorlinksSpeed, motor2speed);
  
}


void manual_calibration() {

  int i;
  for (i = 0; i < 250; i++)  // the calibration will take a few seconds
  {
    qtrrc.calibrate(QTR_EMITTERS_ON);
    delay(20);
  }

  if (DEBUG) { // if true, generate sensor dats via serial output
    Serial.begin(9600);
    for (int i = 0; i < NUM_SENSORS; i++)
    {
      Serial.print(qtrrc.calibratedMinimumOn[i]);
      Serial.print(' ');
    }
    Serial.println();

    for (int i = 0; i < NUM_SENSORS; i++)
    {
      Serial.print(qtrrc.calibratedMaximumOn[i]);
      Serial.print(' ');
    }
    Serial.println();
    Serial.println();
  }
}

But my robot is turning very slow how can i modify this?
And i can't use 8 sensors the code is made for 5

thanks

Greetings Jeroen

1- Error must be equal to "abs(setpoint-position)"

2- You are using 5 sensors but in the definition part you have given 8 sensor inputs "QTRSensorsRC qtrrc((unsigned char[]) { 21,20,19,18,17,16,15,14} ,NUM_SENSORS, TIMEOUT, EMITTER_PIN);"

3- If you don't have an emitter pin you have to define it as"#define EMITTER_PIN QTR_NO_EMITTER_PIN"

kaanmcetin:
1- Error must be equal to "abs(setpoint-position)"

2- You are using 5 sensors but in the definition part you have given 8 sensor inputs "QTRSensorsRC qtrrc((unsigned char[]) { 21,20,19,18,17,16,15,14} ,NUM_SENSORS, TIMEOUT, EMITTER_PIN);"

3- If you don't have an emitter pin you have to define it as"#define EMITTER_PIN QTR_NO_EMITTER_PIN"

Hi how does the "abs(setpoint-position)" works?
What must be added to my code?

Hi,

I have this code with the pololu qtr -8 with the arduino mega. How can i modify this code that when the robot turns, one wheel turns the other way so the curves are sharper?

#include <QTRSensors.h>

int motorRechtsSpeed = 6;
int motorlinksSpeed = 8;
int moterRechts = 7;
int moterLinks = 9;

int maxspeedrechts = 100;
int maxspeedlinks = 100;
int defaultspeedrechts = 50;
int defaultspeedlinks = 50;

// Change the values below to suit your robot's motors, weight, wheel type, etc.
#define KP .2
#define KD 5
//#define M1_DEFAULT_SPEED 50
//#define M2_DEFAULT_SPEED 50
//#define M1_MAX_SPEED 200
//#define M2_MAX_SPEED 200
#define MIDDLE_SENSOR 3

#define NUM_SENSORS  5     // number of sensors used
#define TIMEOUT       2500  // waits for 2500 us for sensor outputs to go low
#define EMITTER_PIN   2     // emitter is controlled by digital pin 2
#define DEBUG 0 // set to 1 if serial debug output needed

QTRSensorsRC qtrrc((unsigned char[]) { 18,17,16,15,14} ,NUM_SENSORS, TIMEOUT, EMITTER_PIN);

unsigned int sensorValues[NUM_SENSORS];

void setup()
{
  pinMode(moterRechts, OUTPUT);
  pinMode(moterLinks, OUTPUT);
  
  pinMode(motorRechtsSpeed, OUTPUT);
  pinMode(motorlinksSpeed, OUTPUT);
  
  digitalWrite(moterRechts, HIGH);
  digitalWrite(moterLinks, HIGH);
  delay(1000);
  manual_calibration(); 
  set_motors(0,0);
}

int lastError = 0;
int  last_proportional = 0;
int integral = 0;
int line_position=0;

void loop()
{
  unsigned int sensors[5];
  int position = qtrrc.readLine(sensors);
  int error = position - 2000;

  int motorSpeed = KP * error + KD * (error - lastError);
  lastError = error;

  int leftMotorSpeed = defaultspeedrechts + motorSpeed;
  int rightMotorSpeed = defaultspeedlinks - motorSpeed;

  // set motor speeds using the two motor speed variables above
  set_motors(leftMotorSpeed, rightMotorSpeed);
   
  
  
  
  
}

void set_motors(int motor1speed, int motor2speed)
{
  if (motor1speed > maxspeedrechts  ) motor1speed =  maxspeedrechts ; // limit top speed
  if (motor2speed > maxspeedlinks  ) motor2speed = maxspeedlinks; // limit top speed
  if (motor1speed < 0) motor1speed = 0; // keep motor above 0
  if (motor2speed < 0) motor2speed = 0; // keep motor speed above 0
  analogWrite(motorRechtsSpeed, motor1speed);   // set motor speed
  analogWrite(motorlinksSpeed, motor2speed);
  
}


void manual_calibration() {

  int i;
  for (i = 0; i < 250; i++)  // the calibration will take a few seconds
  {
    qtrrc.calibrate(QTR_EMITTERS_ON);
    delay(20);
  }

  if (DEBUG) { // if true, generate sensor dats via serial output
    Serial.begin(9600);
    for (int i = 0; i < NUM_SENSORS; i++)
    {
      Serial.print(qtrrc.calibratedMinimumOn[i]);
      Serial.print(' ');
    }
    Serial.println();

    for (int i = 0; i < NUM_SENSORS; i++)
    {
      Serial.print(qtrrc.calibratedMaximumOn[i]);
      Serial.print(' ');
    }
    Serial.println();
    Serial.println();
  }
}

Greetings Jeroen

if (motor1speed < 0) motor1speed = 0; // keep motor above 0
  if (motor2speed < 0) motor2speed = 0; // keep motor speed above 0

Why not use negative values to reverse the motor?

AWOL:

if (motor1speed < 0) motor1speed = 0; // keep motor above 0

if (motor2speed < 0) motor2speed = 0; // keep motor speed above 0



Why not use negative values to reverse the motor?

But how?

The motor reverse when the motorrechts = low

It seems to me you just answered your own question.

AWOL:
It seems to me you just answered your own question.

I tried this

  if (motor1speed < 0){  digitalWrite(moterRechts, HIGH);  motor1speed = 0;  }
  if (motor2speed < 0){ digitalWrite(moterLinks, HIGH); motor2speed = 0; }

But then the robot will drive back ways.

The robot must turn 90 degree curves but now one wheel stops and the other turns so he will turn but the wheel that stops must turn reverse.