Support » Pololu AVR Library Command Reference »
16. QTR Reflectance Sensors
<p>The PololuQTRSensors class and the C functions in this section provide an interface for using Pololu’s <a href="/product/961">QTR reflectance sensors</a> together with the Orangutan. The library provides access to the raw sensors values as well as to high level functions including calibration and line-tracking.</p>
<p class="note">We recommend not using this part of the library directly on the 3pi. Instead, we have provided an initialization function and convenient access functions through the Pololu3pi class. See <a href="/docs/0J18/19">Section 19</a> for details.</p>
<p>This section of the library defines an object for each of the two QTR sensor types, with the <strong>PololuQTRSensorsAnalog</strong> class intended for use with QTR-xA sensors and the <strong>PololuQTRSensorsRC</strong> class intended for use with QTR-xRC sensors. This library takes care of the differences between the QTR-xA and QTR-xRC sensors internally, providing you with a common interface to both sensors. The only external difference is in the constructors. This is achieved by having both of these classes derive from the abstract base class <strong>PololuQTRSensors</strong>. This base class cannot be instantiated.</p>
<p>The PololuQTRSensorsAnalog and PololuQTRSensorsRC classes are the only classes in the Pololu AVR library that must be instantiated before they are used. This allows multiple QTR sensor arrays to be controlled independently as separate PololuQTRSensors objects. The multiple independent array support is not available within the C environment, but multiple arrays can still be configured as a single array, as long as the total number of sensors does not exceed 8.</p>
<p>For calibration, memory is allocated using the <b>malloc()</b> command. This conserves RAM: if all eight sensors are calibrated with the emitters both on an off, a total of 64 bytes would be dedicated to storing calibration values. However, for an application where only three sensors are used, and the emitters are always on during reads, only 6 bytes are required.</p>
<p>Note that the PololuQTRSensorsRC class uses Timer2 during sensor reads to time the sensor pulses, so it might not work with code that uses Timer2 for other purposes. Once the sensor read is complete, Timer2 is restored to its original state; there are no restrictions on its use between sensor reads. The PololuQTRSensorsAnalog class does not use Timer2 at all, and all of the PololuQTRSensors code is compatible with the other Pololu AVR libraries.</p>
<p class="note_warning"><strong>Note:</strong> We also have a <a href="https://github.com/pololu/qtr-sensors-arduino">library for the Arduino IDE</a> that provides the same functionality as this AVR library and additionally supports our second-generation dimmable <a href="/category/123/pololu-qtr-reflectance-sensors">QTR reflectance sensors</a>.</p>
<p>For a higher level overview of this library and example programs that show how this library can be used, please see <strong><a href="/docs/0J20/3.k">Section 3.k</a></strong> of the <a href="/docs/0J20">Pololu AVR C/C++ Library User’s Guide</a>.</p>
<div class="libpololu">
<h2>Reference</h2>
<div class="key">
<p class="cpp"><strong>C++ and methods are shown in red.</strong></p>
<p class="c"><strong>C functions are shown in green.</strong></p>
</div>
<p class="cpp">void PololuQTRSensors::<strong>read</strong>(unsigned int *<em>sensorValues</em>, unsigned char <em>readMode</em> = QTR_EMITTERS_ON)</p>
<p class="c">void <strong>qtr_read</strong>(unsigned int *<em>sensorValues</em>, unsigned char <em>readMode</em>)</p>
<p class="def">Reads the raw sensor values into an array. There <b>MUST</b> be space for as many values as there were sensors specified in the constructor. The values returned are a measure of the reflectance in units that depend on the type of sensor being used, with higher values corresponding to lower reflectance (a black surface or a void). QTR-xA sensors will return a raw value between 0 and 1023. QTR-xRC sensors will return a raw value between 0 and the <em>timeout</em> argument provided in the constructor (which defaults to 4000). The units will be in Timer2 counts, where Timer2 is running at the CPU clock divided by 8 (i.e. 2 MHz on a 16 MHz processor, or 2.5 MHz on a 20 MHz processor).</p>
<p class="def">The functions that read values from the sensors all take an argument <em>readMode,</em> which specifies the kind of read that will be performed. Several options are defined: <strong>QTR_EMITTERS_OFF</strong> specifies that the reading should be made without turning on the infrared (IR) emitters, in which case the reading represents ambient light levels near the sensor; <strong>QTR_EMITTERS_ON</strong> specifies that the emitters should be turned on for the reading, which results in a measure of reflectance; and <strong>QTR_EMITTERS_ON_AND_OFF</strong> specifies that a reading should be made in both the on and off states. The values returned when the <strong>QTR_EMITTERS_ON_AND_OFF</strong> option is used are given by <b>on + max – off</b>, where <b>on</b> is the reading with the emitters on, <b>off</b> is the reading with the emitters off, and <b>max</b> is the maximum sensor reading. This option can reduce the amount of interference from uneven ambient lighting. Note that emitter control will only work if you specify a valid emitter pin in the constructor.</p>
<h3>Example usage:</h3>
<pre name="code" class="c">
unsigned int sensor_values[8];
sensors.read(sensor_values);</pre>
<p class="cpp">void PololuQTRSensors::<strong>emittersOn</strong>()</p>
<p class="c">void <strong>qtr_emitters_on</strong>()</p>
<p class="def">Turn the IR LEDs on. This is mainly for use by the read method, and calling these functions before or after the reading the sensors will have no effect on the readings, but you may wish to use these for testing purposes. This method will only do something if a valid emitter pin was specified in the constructor.</p>
<p class="cpp">void PololuQTRSensors::<strong>emittersOff</strong>()</p>
<p class="c">void <strong>qtr_emitters_off</strong>()</p>
<p class="def">Turn the IR LEDs off. This is mainly for use by the read method, and calling these functions before or after the reading the sensors will have no effect on the readings, but you may wish to use these for testing purposes.</p>
<p class="cpp">void PololuQTRSensors::<strong>calibrate</strong>(unsigned char <em>readMode</em> = QTR_EMITTERS_ON)</p>
<p class="c">void <strong>qtr_calibrate</strong>(unsigned char <em>readMode</em>)</p>
<p class="def">Reads the sensors for calibration. The sensor values are not returned; instead, the maximum and minimum values found over time are stored internally and used for the <b>readCalibrated()</b> method. You can access the calibration (i.e raw max and min sensor readings) through the public member pointers calibratedMinimumOn, calibratedMaximumOn, calibratedMinimumOff, and calibratedMaximumOff. Note that these pointers will point to arrays of length <em>numSensors</em>, as specified in the constructor, and they will only be allocated after calibrate() has been called. If you only calibrate with the emitters on, the calibration arrays that hold the off values will not be allocated.</p>
<p class="cpp">void PololuQTRSensors::<strong>readCalibrated</strong>(unsigned int *<em>sensorValues</em>, unsigned char <em>readMode</em> = QTR_EMITTERS_ON)</p>
<p class="c">void <strong>qtr_read_calibrated</strong>(unsigned int *<em>sensorValues</em>, unsigned char <em>readMode</em>)</p>
<p class="def">Returns sensor readings calibrated to a value between 0 and 1000, where 0 corresponds to a reading that is less than or equal to the minimum value read by <b>calibrate()</b> and 1000 corresponds to a reading that is greater than or equal to the maximum value. Calibration values are stored separately for each sensor, so that differences in the sensors are accounted for automatically.</p>
<p class="cpp">unsigned int PololuQTRSensors::<strong>readLine</strong>(unsigned int *<em>sensorValues</em>, unsigned char <em>readMode</em> = QTR_EMITTERS_ON, unsigned char <em>whiteLine</em> = 0)</p>
<p class="c">unsigned int <strong>qtr_read_line</strong>(unsigned int *<em>sensorValues</em>, unsigned char <em>readMode</em>)</p>
<p class="def">Operates the same as read calibrated, but with a feature designed for line following: this function returns an estimated position of the line. The estimate is made using a weighted average of the sensor indices multiplied by 1000, so that a return value of 0 indicates that the line is directly below sensor 0, a return value of 1000 indicates that the line is directly below sensor 1, 2000 indicates that it’s below sensor 2, etc. Intermediate values indicate that the line is between two sensors. The formula is:</p>
<pre>
 0*value0 + 1000*value1 + 2000*value2 + ...
--------------------------------------------
 value0 + value1 + value2 + ...</pre>
<p>As long as your sensors aren’t spaced too far apart relative to the line, this returned value is designed to be monotonic, which makes it great for use in closed-loop PID control. Additionally, this method remembers where it last saw the line, so if you ever lose the line to the left or the right, it’s line position will continue to indicate the direction you need to go to reacquire the line. For example, if sensor 4 is your rightmost sensor and you end up completely off the line to the left, this function will continue to return 4000.</p>
<p class="def">By default, this function assumes a dark line (high values) surrounded by white (low values). If your line is light on black, set the optional second argument <em>whiteLine</em> to true. In this case, each sensor value will be replaced by the maximum possible value minus its actual value before the averaging.</p>
<p class="cpp">unsigned int* PololuQTRSensors::<strong>calibratedMinimumOn</strong></p>
<p class="c">unsigned int* <strong>qtr_calibrated_minimum_on</strong>()</p>
<p class="def">The calibrated minumum values measured for each sensor, with emitters on. The pointers are unallocated and set to 0 until <b>calibrate()</b> is called, and then allocated to exactly the size required. Depending on the readMode argument to calibrate(), only the On or Off values may be allocated, as required. This and the following variables are made public so that you can use them for your own calculations and do things like saving the values to EEPROM, performing sanity checking, etc. The calibration values are available through function calls from C.</p>
<p class="cpp">unsigned int* PololuQTRSensors::<strong>calibratedMaximumOn</strong></p>
<p class="c">unsigned int* <strong>qtr_calibrated_maximum_on</strong>()</p>
<p class="def">The calibrated maximum values measured for each sensor, with emitters on.</p>
<p class="cpp">unsigned int* PololuQTRSensors::<strong>calibratedMinimumOff</strong></p>
<p class="c">unsigned int* <strong>qtr_calibrated_minimum_off</strong>()</p>
<p class="def">The calibrated minimum values measured for each sensor, with emitters off.</p>
<p class="cpp">unsigned int* PololuQTRSensors::<strong>calibratedMaximumOff</strong></p>
<p class="c">unsigned int* <strong>qtr_calibrated_maximum_off</strong>()</p>
<p class="def">The calibrated maximum values measured for each sensor, with emitters off.</p>
<p class="cpp">PololuQTRSensors::~<strong>PololuQTRSensors</strong>()</p>
<p class="def">The destructor for the PololuQTRSensors class frees up memory allocated for the calibration arrays. This feature is not available in C.</p>
<p class="cpp">PololuQTRSensorsRC::<strong>PololuQTRSensorsRC</strong>()</p>
<p class="def">This constructor performs no initialization. If it is used, the user must call <b>init()</b> before using the methods in this class.</p>
<p class="cpp">PololuQTRSensorsRC::<strong>PololuQTRSensorsRC</strong>(unsigned char* <em>pins</em>, unsigned char <em>numSensors</em>, unsigned int <em>timeout</em> = 4000, unsigned char <em>emitterPin</em> = 255);</p>
<p class="def">This constructor just calls <b>init()</b>, below.</p>
<p class="cpp">void PololuQTRSensorsRC::<strong>init</strong>(unsigned char* <em>pins</em>, unsigned char <em>numSensors</em>, unsigned int <em>timeout</em> = 4000, unsigned char <em>emitterPin</em> = 255)</p>
<p class="c">void <strong>qtr_rc_init</strong>(unsigned char* <em>pins</em>, unsigned char <em>numSensors</em>, unsigned int <em>timeout</em>, unsigned char <em>emitterPin</em>)</p>
<p class="def">Initializes a QTR-RC (digital) sensor array.</p>
<p class="def">The array <em>pins</em> should contain the pin numbers for each sensor, defined using the IO_* keywords provided by the library. For example, if <em>pins</em> is {IO_D3, IO_D6, IO_C1}, sensor 0 is on PD3, sensor 1 is on PD6, and sensor 2 is on PC1.</p>
<p class="def">For ATmegaxx8-based controllers, the pin numbers are Arduino-compatible so you can define the <em>pins</em> array using Arduino pin numbers. For example, if <em>pins</em> is {3, 6, 15}, sensor 0 is on digital pin 3 or PD3, sensor 1 is on digital pin 6 or PD6, and sensor 2 is on digital pin 15 or PC1 (Arduino analog input 1). Digital pins 0 – 7 correpsond to port D pins PD0 – PD7, respectively. Digital pins 8 – 13 correspond to port B pins PB0 – PB5. Digital pins 14 – 19 correspond to port C pins PC0 – PC5, which are referred to in the Arduino environment as analog inputs 0 – 5.</p>
<p class="def"><em>numSensors</em> specifies the length of the ‘pins’ array (the number of QTR-RC sensors you are using). <em>numSensors</em> must be no greater than 16.</p>
<p class="def"><em>timeout</em> specifies the length of time in Timer2 counts beyond which you consider the sensor reading completely black. That is to say, if the pulse length for a pin exceeds <em>timeout</em>, pulse timing will stop and the reading for that pin will be considered full black. It is recommended that you set timeout to be between 1000 and 3000 us, depending on factors like the height of your sensors and ambient lighting. This allows you to shorten the duration of a sensor-reading cycle while maintaining useful measurements of reflectance. On a 16 MHz microcontroller, you can convert Timer2 counts to microseconds by dividing by 2 (2000 us = 4000 Timer2 counts = <em>timeout</em> of 4000). On a 20 MHz microcontroller, you can convert Timer2 counts to microseconds by dividing by 2.5 or multiplying by 0.4 (2000 us = 5000 Timer2 counts = <em>timeout</em> of 5000).</p>
<p class="def"><em>emitterPin</em> is the Arduino digital pin that controls whether the IR LEDs are on or off. This pin is optional and only exists on the 8A and 8RC QTR sensor arrays. If a valid pin is specified, the emitters will only be turned on during a reading. If an invalid pin is specified (e.g. 255), the IR emitters will always be on.</p>
<p class="cpp">PololuQTRSensorsAnalog::<strong>PololuQTRSensorsAnalog</strong>()</p>
<p class="def">This constructor performs no initialization. If this constructor is used, the user must call <b>init()</b> before using the methods in this class.</p>
<p class="cpp">PololuQTRSensorsAnalog::<strong>PololuQTRSensorsAnalog</strong>(unsigned char* <em>analogPins</em>, unsigned char <em>numSensors</em>, unsigned char <em>numSamplesPerSensor</em> = 4, unsigned char <em>emitterPin</em> = 255)</p>
<p class="def">This constructor just calls <b>init()</b>, below.</p>
<p class="cpp">void PololuQTRSensorsAnalog::<strong>init</strong>(unsigned char* <em>analogPins</em>, unsigned char <em>numSensors</em>, unsigned char <em>numSamplesPerSensor</em> = 4, unsigned char <em>emitterPin</em> = 255)</p>
<p class="c">void <strong>qtr_analog_init</strong>(unsigned char* <em>analogPins</em>, unsigned char <em>numSensors</em>, unsigned char <em>numSamplesPerSensor</em>, unsigned char <em>emitterPin</em>)</p>
<p class="def">Initializes a QTR-A (analog) sensor array.</p>
<p class="def">The array <em>pins</em> contains the analog pin assignment for each sensor. For example, if <em>pins</em> is {0, 1, 7}, sensor 1 is on analog input 0, sensor 2 is on analog input 1, and sensor 3 is on analog input 7. The ATmegaxx8 has 8 total analog input channels (ADC0 – ADC7) that correspond to port C pins PC0 – PC5 and dedicated analog inputs ADC6 and ADC7. The Orangutan SVP and X2 also have 8 analog input channels (ADC0 – ADC7) but they correspond to port A pins PA0 – PA7. The analog channels provided by the Orangutan SVP’s auxiliary processor (channels A, B, C, and D) are <em>not</em> supported by this library.</p>
<p class="def"><em>numSensors</em> specifies the length of the <em>analogPins</em> array (the number of QTR-A sensors you are using). numSensors must be no greater than 8.</p>
<p class="def"><em>numSamplesPerSensor</em> indicates the number of 10-bit analog samples to average per channel (per sensor) for each reading. The total number of analog-to-digital conversions performed will be equal to <em>numSensors</em> times <em>numSamplesPerSensor</em>. Increasing this parameter increases noise suppression at the cost of sample rate. Recommended value: 4.</p>
<p class="def"><em>emitterPin</em> is the digital pin (see <b>qtr_rc_init()</b>, above) that controls whether the IR LEDs are on or off. This pin is optional and only exists on the 8A and 8RC QTR sensor arrays. If a valid pin is specified, the emitters will only be turned on during a reading. If an invalid pin is specified (e.g. 255), the IR emitters will always be on.</p>
</div>