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
}