I am trying to make a linefollowing robot and I am using the Pololu QTR-8A, the pololu micro metal gear motors.
I am using six of the eight sensors from the QTR (sensor 2,3,4,5,6,7) and are connected to an arduino UNO to analog pins
0-5.
Code is attached in the file.
I do get readings from the QTR sensor when I read it from the serial monitors. It also gets 5V from the arduino, so as far as hardware is concerned, I don't think that is the problem.
Could someone look at the code and tell me if it is any good, and what the problems are?
The first problem is that the code is not properly posted. It is not necessary, or desirable, to attach code that can be posted directly.
#include <DRV8835MotorShield.h>
#include <QTRSensors.h>
#define Kp 0.05 // experiment to determine this, start by something small that just makes your bot follow the line at a slow speed
#define Kd 2 // experiment to determine this, slowly increase the speeds and adjust this value. ( Note: Kp < Kd)
#define rightMaxSpeed 200 // max speed of the robot
#define leftMaxSpeed 200 // max speed of the robot
#define rightBaseSpeed 150 // this is the speed at which the motors should spin when the robot is perfectly on the line
#define leftBaseSpeed 150 // this is the speed at which the motors should spin when the robot is perfectly on the line
#define NUM_SENSORS 6 // 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
DRV8835MotorShield motors; //don't forget this line
QTRSensorsAnalog qtra((unsigned char[]) { 0, 1, 2, 3, 4, 5} ,NUM_SENSORS, TIMEOUT, EMITTER_PIN); // sensor connected through analog pins A0 - A5 i.e. digital pins 14-19
unsigned int sensorValues[NUM_SENSORS];
void setup()
{
motors.flipM1(true);
motors.flipM2(true);
/* comment this part out for automatic calibration
if ( i < 25 || i >= 75 ) // turn to the left and right to expose the sensors to the brightest and darkest readings that may be encountered
turn_right();
else
turn_left(); */
qtra.calibrate(QTR_EMITTERS_ON);
delay(20);
delay(10000); // wait for 2s to position the bot before entering the main loop
/* comment out for serial printing
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();
*/
}
int lastError = 0;
void loop()
{
unsigned int sensors[6];
int position = qtra.readLine(sensors); // get calibrated readings along with the line position, refer to the QTR Sensors Arduino Library for more details on line position.
int error = position - 2500;
int motorSpeed = Kp * error + Kd * (error - lastError);
lastError = error;
int rightMotorSpeed = rightBaseSpeed + motorSpeed;
int leftMotorSpeed = leftBaseSpeed - motorSpeed;
if (rightMotorSpeed > rightMaxSpeed ) rightMotorSpeed = rightMaxSpeed; // prevent the motor from going beyond max speed
if (leftMotorSpeed > leftMaxSpeed ) leftMotorSpeed = leftMaxSpeed; // prevent the motor from going beyond max speed
if (rightMotorSpeed < 0) rightMotorSpeed = 0; // keep the motor speed positive
if (leftMotorSpeed < 0) leftMotorSpeed = 0; // keep the motor speed positive
{
// move forward with appropriate speeds
motors.setM1Speed(rightMotorSpeed); //only works if "DRV8835MotorShield motors;" is defined in the beginning
motors.setM2Speed(leftMotorSpeed);
}
}
delay(10000); // wait for 2s to position the bot before entering the main loop
If you are going to have useless comments, they MUST be accurate useless comments.
The thing is that this is a code from someone else and I adjusted it a little bit to match my hardware.
"If you are going to have useless comments, they MUST be accurate useless comments."
True, my bad I left this unedited
"What value ARE you getting for position?"
When I hooked up the arduino and the sensors to my PC I was getting values around zero for dark paper and
high values around 800-900 for white paper.
"Why do you think that a good value would be 2500?"
Because that seems to be the standard, most PID line following codes I saw use a value around 2500.
"What value are you computing here? The value is NOT used to set the speed of any motor, so the name of the variable that holds the value is wrong."
I am trying to compute the speed of the motors according to the amount of error the sensors detect.
Whether it is the "standard" or not, the proper value is the one that you get when the robot is centered on the line. Any value other than that should cause the robot to steer back towards the line.
Given that you are getting readings of around 0 when following a black line, trying to get to a position where the reading is 2500 IS going to cause the robot to steer hard in one direction.
I am trying to compute the speed of the motors according to the amount of error the sensors detect.
Not with that statement. You are trying to compute the difference in speed of the left and right motors. Using a meaningful name IS important.