Arduino Library for QTR Reflectance Sensors

void loop()
{
unsigned int sensors[3];
// get calibrated sensor values returned in the sensors array, along with the line position
// position will range from 0 to 2000, with 1000 corresponding to the line over the middle sensor
int position = qtr.readLine(sensors);
// if all three sensors see very low reflectance, take some appropriate action for this situation
if (sensors[0] > 750 && sensors[1] > 750 && sensors[2] > 750)
{
// do something. Maybe this means we're at the edge of a course or about to fall off a table,
// in which case, we might want to stop moving, back up, and turn around.
return;
}
// compute our "error" from the line position. We will make it so that the error is zero when
// the middle sensor is over the line, because this is our goal. Error will range from
// -1000 to +1000. If we have sensor 0 on the left and sensor 2 on the right, a reading of -1000
// means that we see the line on the left and a reading of +1000 means we see the line on
// the right.
int error = position - 1000;
int leftMotorSpeed = 100;
int rightMotorSpeed = 100;
if (error < -500) // the line is on the left
leftMotorSpeed = 0; // turn left
if (error > 500) // the line is on the right
rightMotorSpeed = 0; // turn right
// set motor speeds using the two motor speed variables above
}
PID Control
The integer value returned by readLine() can be easily converted into a measure of your position error for line-following
applications, as was demonstrated in the previous code sample. The function used to generate this position/error value is
designed to be monotonic, which means the value will almost always change in the same direction as you sweep your
sensors across the line. This makes it a great quantity to use for PID control.
Explaining the nature of PID control is beyond the scope of this document, but wikipedia has a very good
article [http://en.wikipedia.org/wiki/PID_controller] on the subject.
The following code gives a very simple example of PD control (I find the integral PID term is usually not necessary when
it comes to line following). The specific nature of the constants will be determined by your particular application, but you
should note that the derivative constant Kd is usually much bigger than the proportional constant Kp. This is because the
derivative of the error is a much smaller quantity than the error itself, so in order to produce a meaningful correction it
needs to be multiplied by a much larger constant.
int lastError = 0;
void loop()
{
unsigned int sensors[3];
// get calibrated sensor values returned in the sensors array, along with the line position
// position will range from 0 to 2000, with 1000 corresponding to the line over the middle sensor
int position = qtr.readLine(sensors);
// compute our "error" from the line position. We will make it so that the error is zero when
// the middle sensor is over the line, because this is our goal. Error will range from
// -1000 to +1000. If we have sensor 0 on the left and sensor 2 on the right, a reading of -1000
// means that we see the line on the left and a reading of +1000 means we see the line on
// the right.
int error = position - 1000;
// set the motor speed based on proportional and derivative PID terms
// KP is the a floating-point proportional constant (maybe start with a value around 0.1)
// KD is the floating-point derivative constant (maybe start with a value around 5)
// note that when doing PID, it's very important you get your signs right, or else the
// control loop will be unstable
int motorSpeed = KP * error + KD * (error - lastError);
Arduino Library for the Pololu QTR Reflectance Sensors © 2001–2009 Pololu Corporation
3. PololuQTRSensors Methods & Usage Notes Page 7 of 8