Pololu QTR Sensor Library, based on the QTR Arduino Library

Dependents:   Nucleo_QTR ZumoReflectanceSensorArray speed_robot

Committer:
phillippsm
Date:
Thu Aug 27 01:42:08 2015 +0000
Revision:
1:a664ab7aba8d
Parent:
0:d54bb6a949bf
Alpha 0.1 - Minor changes to timing and removing redundant code

Who changed what in which revision?

UserRevisionLine numberNew contents of line
phillippsm 0:d54bb6a949bf 1 /*
phillippsm 0:d54bb6a949bf 2 QTRSensors.h - Library for using Pololu QTR reflectance
phillippsm 0:d54bb6a949bf 3 sensors and reflectance sensor arrays: QTR-1A, QTR-8A, QTR-1RC, and
phillippsm 0:d54bb6a949bf 4 QTR-8RC. The object used will determine the type of the sensor (either
phillippsm 0:d54bb6a949bf 5 QTR-xA or QTR-xRC). Then simply specify in the constructor which
phillippsm 0:d54bb6a949bf 6 Arduino I/O pins are connected to a QTR sensor, and the read() method
phillippsm 0:d54bb6a949bf 7 will obtain reflectance measurements for those sensors. Smaller sensor
phillippsm 0:d54bb6a949bf 8 values correspond to higher reflectance (e.g. white) while larger
phillippsm 0:d54bb6a949bf 9 sensor values correspond to lower reflectance (e.g. black or a void).
phillippsm 0:d54bb6a949bf 10
phillippsm 0:d54bb6a949bf 11 * QTRSensorsRC should be used for QTR-1RC and QTR-8RC sensors.
phillippsm 0:d54bb6a949bf 12 * QTRSensorsAnalog should be used for QTR-1A and QTR-8A sensors.
phillippsm 0:d54bb6a949bf 13 */
phillippsm 0:d54bb6a949bf 14
phillippsm 0:d54bb6a949bf 15 /*
phillippsm 0:d54bb6a949bf 16 * Written by Ben Schmidel et al., October 4, 2010
phillippsm 0:d54bb6a949bf 17 * Copyright (c) 2008-2012 Pololu Corporation. For more information, see
phillippsm 0:d54bb6a949bf 18 *
phillippsm 0:d54bb6a949bf 19 * http://www.pololu.com
phillippsm 0:d54bb6a949bf 20 * http://forum.pololu.com
phillippsm 0:d54bb6a949bf 21 * http://www.pololu.com/docs/0J19
phillippsm 0:d54bb6a949bf 22 *
phillippsm 0:d54bb6a949bf 23 * You may freely modify and share this code, as long as you keep this
phillippsm 0:d54bb6a949bf 24 * notice intact (including the two links above). Licensed under the
phillippsm 0:d54bb6a949bf 25 * Creative Commons BY-SA 3.0 license:
phillippsm 0:d54bb6a949bf 26 *
phillippsm 0:d54bb6a949bf 27 * http://creativecommons.org/licenses/by-sa/3.0/
phillippsm 0:d54bb6a949bf 28 *
phillippsm 0:d54bb6a949bf 29 * Disclaimer: To the extent permitted by law, Pololu provides this work
phillippsm 0:d54bb6a949bf 30 * without any warranty. It might be defective, in which case you agree
phillippsm 0:d54bb6a949bf 31 * to be responsible for all resulting costs and damages.
phillippsm 0:d54bb6a949bf 32 *
phillippsm 0:d54bb6a949bf 33 * Modified by Matthew Phillipps, August 24, 2015
phillippsm 0:d54bb6a949bf 34 * Adapted to mbed platform (especially STM Nucleo boards)
phillippsm 0:d54bb6a949bf 35 * Some changes to memory management
phillippsm 0:d54bb6a949bf 36 */
phillippsm 0:d54bb6a949bf 37 #include "mbed.h"
phillippsm 0:d54bb6a949bf 38 #include <vector>
phillippsm 0:d54bb6a949bf 39
phillippsm 0:d54bb6a949bf 40 #ifndef QTRSensors_h
phillippsm 0:d54bb6a949bf 41 #define QTRSensors_h
phillippsm 0:d54bb6a949bf 42
phillippsm 0:d54bb6a949bf 43 #define QTR_EMITTERS_OFF 0
phillippsm 0:d54bb6a949bf 44 #define QTR_EMITTERS_ON 1
phillippsm 0:d54bb6a949bf 45 #define QTR_EMITTERS_ON_AND_OFF 2
phillippsm 0:d54bb6a949bf 46
phillippsm 0:d54bb6a949bf 47 #define QTR_NO_EMITTER_PIN 255
phillippsm 0:d54bb6a949bf 48
phillippsm 0:d54bb6a949bf 49 #define QTR_MAX_SENSORS 16
phillippsm 0:d54bb6a949bf 50 #define HIGH 1
phillippsm 0:d54bb6a949bf 51 #define LOW 0
phillippsm 0:d54bb6a949bf 52
phillippsm 0:d54bb6a949bf 53 // This class cannot be instantiated directly (it has no constructor).
phillippsm 0:d54bb6a949bf 54 // Instead, you should instantiate one of its two derived classes (either the
phillippsm 0:d54bb6a949bf 55 // QTR-A or QTR-RC version, depending on the type of your sensor).
phillippsm 0:d54bb6a949bf 56 class QTRSensors
phillippsm 0:d54bb6a949bf 57 {
phillippsm 0:d54bb6a949bf 58 public:
phillippsm 0:d54bb6a949bf 59
phillippsm 0:d54bb6a949bf 60 // Reads the sensor values into an array. There *MUST* be space
phillippsm 0:d54bb6a949bf 61 // for as many values as there were sensors specified in the constructor.
phillippsm 0:d54bb6a949bf 62 // Example usage:
phillippsm 0:d54bb6a949bf 63 // unsigned int sensor_values[8];
phillippsm 0:d54bb6a949bf 64 // sensors.read(sensor_values);
phillippsm 0:d54bb6a949bf 65 // The values returned are a measure of the reflectance in abstract units,
phillippsm 0:d54bb6a949bf 66 // with higher values corresponding to lower reflectance (e.g. a black
phillippsm 0:d54bb6a949bf 67 // surface or a void).
phillippsm 0:d54bb6a949bf 68 // If measureOffAndOn is true, measures the values with the
phillippsm 0:d54bb6a949bf 69 // emitters on AND off and returns on - (timeout - off). If this
phillippsm 0:d54bb6a949bf 70 // value is less than zero, it returns zero.
phillippsm 0:d54bb6a949bf 71 // This method will call the appropriate derived class's readPrivate(),
phillippsm 0:d54bb6a949bf 72 // which is defined as a virtual function in the base class and
phillippsm 0:d54bb6a949bf 73 // overridden by each derived class's own implementation.
phillippsm 0:d54bb6a949bf 74 void read(unsigned int *sensor_values, unsigned char readMode = QTR_EMITTERS_ON);
phillippsm 0:d54bb6a949bf 75
phillippsm 0:d54bb6a949bf 76 // Turn the IR LEDs off and on. This is mainly for use by the
phillippsm 0:d54bb6a949bf 77 // read method, and calling these functions before or
phillippsm 0:d54bb6a949bf 78 // after the reading the sensors will have no effect on the
phillippsm 0:d54bb6a949bf 79 // readings, but you may wish to use these for testing purposes.
phillippsm 0:d54bb6a949bf 80 void emittersOff();
phillippsm 0:d54bb6a949bf 81 void emittersOn();
phillippsm 0:d54bb6a949bf 82
phillippsm 0:d54bb6a949bf 83 // Reads the sensors for calibration. The sensor values are
phillippsm 0:d54bb6a949bf 84 // not returned; instead, the maximum and minimum values found
phillippsm 0:d54bb6a949bf 85 // over time are stored internally and used for the
phillippsm 0:d54bb6a949bf 86 // readCalibrated() method.
phillippsm 0:d54bb6a949bf 87 void calibrate(unsigned char readMode = QTR_EMITTERS_ON);
phillippsm 0:d54bb6a949bf 88
phillippsm 0:d54bb6a949bf 89 // Resets all calibration that has been done.
phillippsm 0:d54bb6a949bf 90 void resetCalibration();
phillippsm 0:d54bb6a949bf 91
phillippsm 0:d54bb6a949bf 92 // Returns values calibrated to a value between 0 and 1000, where
phillippsm 0:d54bb6a949bf 93 // 0 corresponds to the minimum value read by calibrate() and 1000
phillippsm 0:d54bb6a949bf 94 // corresponds to the maximum value. Calibration values are
phillippsm 0:d54bb6a949bf 95 // stored separately for each sensor, so that differences in the
phillippsm 0:d54bb6a949bf 96 // sensors are accounted for automatically.
phillippsm 0:d54bb6a949bf 97 void readCalibrated(unsigned int *sensor_values, unsigned char readMode = QTR_EMITTERS_ON);
phillippsm 0:d54bb6a949bf 98
phillippsm 0:d54bb6a949bf 99 // Operates the same as read calibrated, but also returns an
phillippsm 0:d54bb6a949bf 100 // estimated position of the robot with respect to a line. The
phillippsm 0:d54bb6a949bf 101 // estimate is made using a weighted average of the sensor indices
phillippsm 0:d54bb6a949bf 102 // multiplied by 1000, so that a return value of 0 indicates that
phillippsm 0:d54bb6a949bf 103 // the line is directly below sensor 0, a return value of 1000
phillippsm 0:d54bb6a949bf 104 // indicates that the line is directly below sensor 1, 2000
phillippsm 0:d54bb6a949bf 105 // indicates that it's below sensor 2000, etc. Intermediate
phillippsm 0:d54bb6a949bf 106 // values indicate that the line is between two sensors. The
phillippsm 0:d54bb6a949bf 107 // formula is:
phillippsm 0:d54bb6a949bf 108 //
phillippsm 0:d54bb6a949bf 109 // 0*value0 + 1000*value1 + 2000*value2 + ...
phillippsm 0:d54bb6a949bf 110 // --------------------------------------------
phillippsm 0:d54bb6a949bf 111 // value0 + value1 + value2 + ...
phillippsm 0:d54bb6a949bf 112 //
phillippsm 0:d54bb6a949bf 113 // By default, this function assumes a dark line (high values)
phillippsm 0:d54bb6a949bf 114 // surrounded by white (low values). If your line is light on
phillippsm 0:d54bb6a949bf 115 // black, set the optional second argument white_line to true. In
phillippsm 0:d54bb6a949bf 116 // this case, each sensor value will be replaced by (1000-value)
phillippsm 0:d54bb6a949bf 117 // before the averaging.
phillippsm 0:d54bb6a949bf 118 int readLine(unsigned int *sensor_values, unsigned char readMode = QTR_EMITTERS_ON, unsigned char white_line = 0);
phillippsm 0:d54bb6a949bf 119
phillippsm 0:d54bb6a949bf 120 unsigned int *calibratedMinimumOn;
phillippsm 0:d54bb6a949bf 121 unsigned int *calibratedMaximumOn;
phillippsm 0:d54bb6a949bf 122 unsigned int *calibratedMinimumOff;
phillippsm 0:d54bb6a949bf 123 unsigned int *calibratedMaximumOff;
phillippsm 0:d54bb6a949bf 124
phillippsm 0:d54bb6a949bf 125 // Calibrated minumum and maximum values. These start at 1000 and
phillippsm 0:d54bb6a949bf 126 // 0, respectively, so that the very first sensor reading will
phillippsm 0:d54bb6a949bf 127 // update both of them.
phillippsm 0:d54bb6a949bf 128 //
phillippsm 0:d54bb6a949bf 129 // The pointers are unallocated until calibrate() is called, and
phillippsm 0:d54bb6a949bf 130 // then allocated to exactly the size required. Depending on the
phillippsm 0:d54bb6a949bf 131 // readMode argument to calibrate, only the On or Off values may
phillippsm 0:d54bb6a949bf 132 // be allocated, as required.
phillippsm 0:d54bb6a949bf 133 //
phillippsm 0:d54bb6a949bf 134 // These variables are made public so that you can use them for
phillippsm 0:d54bb6a949bf 135 // your own calculations and do things like saving the values to
phillippsm 0:d54bb6a949bf 136 // EEPROM, performing sanity checking, etc.
phillippsm 0:d54bb6a949bf 137
phillippsm 0:d54bb6a949bf 138 ~QTRSensors();
phillippsm 0:d54bb6a949bf 139
phillippsm 0:d54bb6a949bf 140 protected:
phillippsm 0:d54bb6a949bf 141
phillippsm 0:d54bb6a949bf 142 QTRSensors()
phillippsm 0:d54bb6a949bf 143 {
phillippsm 0:d54bb6a949bf 144
phillippsm 0:d54bb6a949bf 145 };
phillippsm 0:d54bb6a949bf 146
phillippsm 0:d54bb6a949bf 147 void init(PinName *pins, unsigned char numSensors, PinName emitterPin, bool analog);
phillippsm 0:d54bb6a949bf 148
phillippsm 0:d54bb6a949bf 149 bool _analog;
phillippsm 0:d54bb6a949bf 150 PinName *_pins;
phillippsm 0:d54bb6a949bf 151 unsigned char _numSensors;
phillippsm 0:d54bb6a949bf 152 PinName _emitterPin;
phillippsm 0:d54bb6a949bf 153 unsigned int _maxValue; // the maximum value returned by this function
phillippsm 0:d54bb6a949bf 154 DigitalOut *_emitter;
phillippsm 0:d54bb6a949bf 155 std::vector<DigitalInOut *> _qtrPins;
phillippsm 0:d54bb6a949bf 156 std::vector<AnalogIn *> _qtrAIPins;
phillippsm 0:d54bb6a949bf 157
phillippsm 0:d54bb6a949bf 158 private:
phillippsm 0:d54bb6a949bf 159
phillippsm 0:d54bb6a949bf 160 virtual void readPrivate(unsigned int *sensor_values) = 0;
phillippsm 0:d54bb6a949bf 161
phillippsm 0:d54bb6a949bf 162 // Handles the actual calibration. calibratedMinimum and
phillippsm 0:d54bb6a949bf 163 // calibratedMaximum are pointers to the requested calibration
phillippsm 0:d54bb6a949bf 164 // arrays, which will be allocated if necessary.
phillippsm 0:d54bb6a949bf 165 void calibrateOnOrOff(unsigned int **calibratedMaximum,
phillippsm 0:d54bb6a949bf 166 unsigned int **calibratedMinimum,
phillippsm 0:d54bb6a949bf 167 unsigned char readMode);
phillippsm 0:d54bb6a949bf 168 };
phillippsm 0:d54bb6a949bf 169
phillippsm 0:d54bb6a949bf 170
phillippsm 0:d54bb6a949bf 171
phillippsm 0:d54bb6a949bf 172 // Object to be used for QTR-1RC and QTR-8RC sensors
phillippsm 0:d54bb6a949bf 173 class QTRSensorsRC : public QTRSensors
phillippsm 0:d54bb6a949bf 174 {
phillippsm 0:d54bb6a949bf 175 public:
phillippsm 0:d54bb6a949bf 176
phillippsm 0:d54bb6a949bf 177 // if this constructor is used, the user must call init() before using
phillippsm 0:d54bb6a949bf 178 // the methods in this class
phillippsm 0:d54bb6a949bf 179 QTRSensorsRC();
phillippsm 0:d54bb6a949bf 180
phillippsm 0:d54bb6a949bf 181 // this constructor just calls init()
phillippsm 0:d54bb6a949bf 182 QTRSensorsRC(PinName* pins, unsigned char numSensors,
phillippsm 0:d54bb6a949bf 183 unsigned int timeout = 4000, PinName emitterPin = NC);
phillippsm 0:d54bb6a949bf 184
phillippsm 0:d54bb6a949bf 185 // The array 'pins' contains the Arduino pin number for each sensor.
phillippsm 0:d54bb6a949bf 186
phillippsm 0:d54bb6a949bf 187 // 'numSensors' specifies the length of the 'pins' array (i.e. the
phillippsm 0:d54bb6a949bf 188 // number of QTR-RC sensors you are using). numSensors must be
phillippsm 0:d54bb6a949bf 189 // no greater than 16.
phillippsm 0:d54bb6a949bf 190
phillippsm 0:d54bb6a949bf 191 // 'timeout' specifies the length of time in microseconds beyond
phillippsm 0:d54bb6a949bf 192 // which you consider the sensor reading completely black. That is to say,
phillippsm 0:d54bb6a949bf 193 // if the pulse length for a pin exceeds 'timeout', pulse timing will stop
phillippsm 0:d54bb6a949bf 194 // and the reading for that pin will be considered full black.
phillippsm 0:d54bb6a949bf 195 // It is recommended that you set timeout to be between 1000 and
phillippsm 0:d54bb6a949bf 196 // 3000 us, depending on things like the height of your sensors and
phillippsm 0:d54bb6a949bf 197 // ambient lighting. Using timeout allows you to shorten the
phillippsm 0:d54bb6a949bf 198 // duration of a sensor-reading cycle while still maintaining
phillippsm 0:d54bb6a949bf 199 // useful analog measurements of reflectance
phillippsm 0:d54bb6a949bf 200
phillippsm 0:d54bb6a949bf 201 // 'emitterPin' is the Arduino pin that controls the IR LEDs on the 8RC
phillippsm 0:d54bb6a949bf 202 // modules. If you are using a 1RC (i.e. if there is no emitter pin),
phillippsm 0:d54bb6a949bf 203 // or if you just want the emitters on all the time and don't want to
phillippsm 0:d54bb6a949bf 204 // use an I/O pin to control it, use a value of 255 (QTR_NO_EMITTER_PIN).
phillippsm 0:d54bb6a949bf 205 void init(PinName* pins, unsigned char numSensors,
phillippsm 0:d54bb6a949bf 206 unsigned int timeout = 2000, PinName emitterPin = NC); // NC = Not Connected
phillippsm 0:d54bb6a949bf 207
phillippsm 0:d54bb6a949bf 208
phillippsm 0:d54bb6a949bf 209
phillippsm 0:d54bb6a949bf 210 private:
phillippsm 0:d54bb6a949bf 211
phillippsm 0:d54bb6a949bf 212 // Reads the sensor values into an array. There *MUST* be space
phillippsm 0:d54bb6a949bf 213 // for as many values as there were sensors specified in the constructor.
phillippsm 0:d54bb6a949bf 214 // Example usage:
phillippsm 0:d54bb6a949bf 215 // unsigned int sensor_values[8];
phillippsm 0:d54bb6a949bf 216 // sensors.read(sensor_values);
phillippsm 0:d54bb6a949bf 217 // The values returned are a measure of the reflectance in microseconds.
phillippsm 0:d54bb6a949bf 218 void readPrivate(unsigned int *sensor_values);
phillippsm 0:d54bb6a949bf 219 };
phillippsm 0:d54bb6a949bf 220
phillippsm 0:d54bb6a949bf 221
phillippsm 0:d54bb6a949bf 222
phillippsm 0:d54bb6a949bf 223 // Object to be used for QTR-1A and QTR-8A sensors
phillippsm 0:d54bb6a949bf 224 class QTRSensorsAnalog : public QTRSensors
phillippsm 0:d54bb6a949bf 225 {
phillippsm 0:d54bb6a949bf 226 public:
phillippsm 0:d54bb6a949bf 227
phillippsm 0:d54bb6a949bf 228 // if this constructor is used, the user must call init() before using
phillippsm 0:d54bb6a949bf 229 // the methods in this class
phillippsm 0:d54bb6a949bf 230 QTRSensorsAnalog();
phillippsm 0:d54bb6a949bf 231
phillippsm 0:d54bb6a949bf 232 // this constructor just calls init()
phillippsm 0:d54bb6a949bf 233 QTRSensorsAnalog(PinName* pins,
phillippsm 0:d54bb6a949bf 234 unsigned char numSensors,
phillippsm 0:d54bb6a949bf 235 unsigned char numSamplesPerSensor = 4,
phillippsm 0:d54bb6a949bf 236 PinName emitterPin = NC);
phillippsm 0:d54bb6a949bf 237
phillippsm 0:d54bb6a949bf 238 // the array 'pins' contains the Arduino analog pin assignment for each
phillippsm 0:d54bb6a949bf 239 // sensor. For example, if pins is {0, 1, 7}, sensor 1 is on
phillippsm 0:d54bb6a949bf 240 // Arduino analog input 0, sensor 2 is on Arduino analog input 1,
phillippsm 0:d54bb6a949bf 241 // and sensor 3 is on Arduino analog input 7.
phillippsm 0:d54bb6a949bf 242
phillippsm 0:d54bb6a949bf 243 // 'numSensors' specifies the length of the 'analogPins' array (i.e. the
phillippsm 0:d54bb6a949bf 244 // number of QTR-A sensors you are using). numSensors must be
phillippsm 0:d54bb6a949bf 245 // no greater than 16.
phillippsm 0:d54bb6a949bf 246
phillippsm 0:d54bb6a949bf 247 // 'numSamplesPerSensor' indicates the number of 10-bit analog samples
phillippsm 0:d54bb6a949bf 248 // to average per channel (i.e. per sensor) for each reading. The total
phillippsm 0:d54bb6a949bf 249 // number of analog-to-digital conversions performed will be equal to
phillippsm 0:d54bb6a949bf 250 // numSensors*numSamplesPerSensor. Note that it takes about 100 us to
phillippsm 0:d54bb6a949bf 251 // perform a single analog-to-digital conversion, so:
phillippsm 0:d54bb6a949bf 252 // if numSamplesPerSensor is 4 and numSensors is 6, it will take
phillippsm 0:d54bb6a949bf 253 // 4 * 6 * 100 us = ~2.5 ms to perform a full readLine().
phillippsm 0:d54bb6a949bf 254 // Increasing this parameter increases noise suppression at the cost of
phillippsm 0:d54bb6a949bf 255 // sample rate. The recommended value is 4.
phillippsm 0:d54bb6a949bf 256
phillippsm 0:d54bb6a949bf 257 // 'emitterPin' is the Arduino pin that controls the IR LEDs on the 8RC
phillippsm 0:d54bb6a949bf 258 // modules. If you are using a 1RC (i.e. if there is no emitter pin),
phillippsm 0:d54bb6a949bf 259 // or if you just want the emitters on all the time and don't want to
phillippsm 0:d54bb6a949bf 260 // use an I/O pin to control it, use a value of 255 (QTR_NO_EMITTER_PIN).
phillippsm 0:d54bb6a949bf 261 void init(PinName *analogPins, unsigned char numSensors,
phillippsm 0:d54bb6a949bf 262 unsigned char numSamplesPerSensor = 4, PinName emitterPin = NC);
phillippsm 0:d54bb6a949bf 263
phillippsm 0:d54bb6a949bf 264
phillippsm 0:d54bb6a949bf 265
phillippsm 0:d54bb6a949bf 266 private:
phillippsm 0:d54bb6a949bf 267
phillippsm 0:d54bb6a949bf 268 // Reads the sensor values into an array. There *MUST* be space
phillippsm 0:d54bb6a949bf 269 // for as many values as there were sensors specified in the constructor.
phillippsm 0:d54bb6a949bf 270 // Example usage:
phillippsm 0:d54bb6a949bf 271 // unsigned int sensor_values[8];
phillippsm 0:d54bb6a949bf 272 // sensors.read(sensor_values);
phillippsm 0:d54bb6a949bf 273 // The values returned are a measure of the reflectance in terms of a
phillippsm 0:d54bb6a949bf 274 // 10-bit ADC average with higher values corresponding to lower
phillippsm 0:d54bb6a949bf 275 // reflectance (e.g. a black surface or a void).
phillippsm 0:d54bb6a949bf 276 void readPrivate(unsigned int *sensor_values);
phillippsm 0:d54bb6a949bf 277
phillippsm 0:d54bb6a949bf 278 unsigned char _numSamplesPerSensor;
phillippsm 0:d54bb6a949bf 279 };
phillippsm 0:d54bb6a949bf 280
phillippsm 0:d54bb6a949bf 281
phillippsm 0:d54bb6a949bf 282 #endif