In: Electrical Engineering
Write an Arduino Program that detects a reflective surface using the line sensor array of a QTR-3RC (*Must be specific to this sensor! please this is important*)
Must include a function that when called
returns..
0 (line to the left of the robot)
1 (line under the robot on the left side)
2 (line under the robot on the right side)
3 (line to the right of the robot)
Output the results to the serial port in 0.5 second intervals
PLEASE USE CODE SPECIFIC TO QTR-3RC
SENSOR!!!!!!
A sample calibration routine would be:
#include <QTRSensors.h>
// create an object for your type of sensor (RC or Analog)
// in this example we have three sensors on analog inputs 0 - 2,
a.k.a. digital pins 14 - 16
QTRSensorsRC qtr((char[]) {14, 15, 16}, 3);
// QTRSensorsA qtr((char[]) {0, 1, 2}, 3);
void setup()
{
// optional: wait for some input from the user, such as
a button press
// then start calibration phase and move the sensors
over both
// reflectance extremes they will encounter in your
application:
int i;
for (i = 0; i < 250; i++) // make the calibration
take about 5 seconds
{
qtr.calibrate();
delay(20);
}
// optional: signal that the calibration phase is now
over and wait for further
// input from the user, such as a button press
}
A routine to obtain the sensor values and perform rudimentary line following would be:
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:
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);
lastError = error;
// M1 and M2 are base motor speeds. That is to say,
they are the speeds the motors should
// spin at if you are perfectly on the line with no
error. If your motors are well matched,
// M1 and M2 will be equal. When you start testing your
PID loop, it might help to start with
// small values for M1 and M2. You can then increase
the speed as you fine-tune your
// PID constants KP and KD.
int m1Speed = M1 + motorSpeed;
int m2Speed = M2 - motorSpeed;
// it might help to keep the speeds positive (this is
optional)
// note that you might want to add a similiar line to
keep the speeds from exceeding
// any maximum allowed value
if (m1Speed < 0)
m1Speed = 0;
if (m2Speed < 0)
m2Speed = 0;
// set motor speeds using the two motor speed variables
above
}