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