Arduino Library for the Pololu QTR Reflectance Sensors

Arduino IDE with Pololu QTR sensors superimposed over it.

View document on multiple pages.
You can also view this document as a printable PDF.

1. Introduction
2. Library Installation
3. QTRSensors Methods & Usage Notes

1. Introduction

<p class="note_warning">This guide is for an older version of the QTRSensors Arduino library (3.1.0). The current version of the library can be found <a href="https://github.com/pololu/qtr-sensors-arduino">on GitHub</a>, and its documentation is <a href="http://pololu.github.io/qtr-sensors-arduino/">here</a>.</p> <!-- table(side_by_side_pics). |<table class="picture_with_caption center"><tr><td style="max-width: 160px"><img alt="" class="" data-gallery-pictures="[{&quot;id&quot;:&quot;0J4428&quot;,&quot;caption&quot;:&quot;\u003cp\u003eQTR-L-1A reflectance sensors.\u003c/p\u003e&quot;,&quot;url_tiny&quot;:&quot;https://a.pololu-files.com/picture/0J4428.98x98.jpg?b754854c94f6723103f6c20d033e364e&quot;,&quot;url_medium&quot;:&quot;https://a.pololu-files.com/picture/0J4428.600x480.jpg?b754854c94f6723103f6c20d033e364e&quot;,&quot;url_full&quot;:&quot;https://a.pololu-files.com/picture/0J4428.1200.jpg?b754854c94f6723103f6c20d033e364e&quot;,&quot;longest_side&quot;:800}]" data-picture-id="0J4428" data-picture-longest_side="800" src="https://a.pololu-files.com/picture/0J4428.160.jpg?b754854c94f6723103f6c20d033e364e" /></td></tr><tr><th style="max-width: 160px"><p>QTR-L-1A reflectance sensors.</p></th></tr></table>|<table class="picture_with_caption center"><tr><td style="max-width: 180px"><img alt="" class="" data-gallery-pictures="[{&quot;id&quot;:&quot;0J625&quot;,&quot;caption&quot;:&quot;\u003cp\u003eQTR-1RC reflectance sensor.\u003c/p\u003e&quot;,&quot;url_tiny&quot;:&quot;https://a.pololu-files.com/picture/0J625.98x98.jpg?e821a1f5ecbf3a8e8f74d08e3343dbfa&quot;,&quot;url_medium&quot;:&quot;https://a.pololu-files.com/picture/0J625.600x480.jpg?e821a1f5ecbf3a8e8f74d08e3343dbfa&quot;,&quot;url_full&quot;:&quot;https://a.pololu-files.com/picture/0J625.1200.jpg?e821a1f5ecbf3a8e8f74d08e3343dbfa&quot;,&quot;longest_side&quot;:677}]" data-picture-id="0J625" data-picture-longest_side="677" src="https://a.pololu-files.com/picture/0J625.180.jpg?e821a1f5ecbf3a8e8f74d08e3343dbfa" /></td></tr><tr><th style="max-width: 180px"><p>QTR-1RC reflectance sensor.</p></th></tr></table>| <table class="picture_with_caption center"><tr><td style="max-width: 150px"><img alt="" class="" data-gallery-pictures="[{&quot;id&quot;:&quot;0J615&quot;,&quot;caption&quot;:&quot;\u003cp\u003eQTR-8A reflectance sensor array.\u003c/p\u003e&quot;,&quot;url_tiny&quot;:&quot;https://a.pololu-files.com/picture/0J615.98x98.jpg?ef5903b25450c25de151ed9b43d1fce3&quot;,&quot;url_medium&quot;:&quot;https://a.pololu-files.com/picture/0J615.600x480.jpg?ef5903b25450c25de151ed9b43d1fce3&quot;,&quot;url_full&quot;:&quot;https://a.pololu-files.com/picture/0J615.1200.jpg?ef5903b25450c25de151ed9b43d1fce3&quot;,&quot;longest_side&quot;:800}]" data-picture-id="0J615" data-picture-longest_side="800" src="https://a.pololu-files.com/picture/0J615.150.jpg?ef5903b25450c25de151ed9b43d1fce3" /></td></tr><tr><th style="max-width: 150px"><p>QTR-8A reflectance sensor array.</p></th></tr></table>| | --><table class="picture_with_caption center"><tr><td style="max-width: 400px"><a href="https://a.pololu-files.com/picture/0J4642.1200.jpg?9ae24a3959a88fee8dd66d333023e2dc" class="noscript-fallback"><img alt="" class="zoomable" data-gallery-pictures="[{&quot;id&quot;:&quot;0J4642&quot;,&quot;caption&quot;:&quot;\u003cp\u003eQTR sensor size comparison. Top row: QTRX-HD-07, QTR-HD-07; middle row: QTR-3, QTR-1, QTR-L-1; bottom row: QTR-8.\u003c/p\u003e&quot;,&quot;url_tiny&quot;:&quot;https://a.pololu-files.com/picture/0J4642.98x98.jpg?9ae24a3959a88fee8dd66d333023e2dc&quot;,&quot;url_medium&quot;:&quot;https://a.pololu-files.com/picture/0J4642.600x480.jpg?9ae24a3959a88fee8dd66d333023e2dc&quot;,&quot;url_full&quot;:&quot;https://a.pololu-files.com/picture/0J4642.1200.jpg?9ae24a3959a88fee8dd66d333023e2dc&quot;,&quot;longest_side&quot;:934}]" data-picture-id="0J4642" data-picture-longest_side="934" src="https://a.pololu-files.com/picture/0J4642.400.jpg?9ae24a3959a88fee8dd66d333023e2dc" /></a></td><p></tr><tr><th style="max-width: 400px"><p>QTR sensor size comparison. Top row: QTRX-HD-07, QTR-HD-07; middle row: QTR-3, QTR-1, QTR-L-1; bottom row: QTR-8.</p></th></tr></table></p> <p>The Pololu QTR reflectance sensors carry infrared LED and phototransistor pairs that can provide analog measurements of IR reflectance, which makes them great for close-proximity edge detection and line-following applications. The modules come as compact, single-sensor units (<a href="/product/2458">QTR-1A</a> and <a href="/product/2459">QTR-1RC</a>; <a href="/product/2454">QTR-L-1A</a> and <a href="/product/2455">QTR-L-1RC</a>), 3-sensor arrays (<a href="/product/2456">QTR-3A</a> and <a href="/product/2457">QTR-3RC</a>), or as 8-sensor arrays (<a href="/product/960">QTR-8A</a> and <a href="/product/961">QTR-8RC</a>) that can be optionally split into a 2-sensor array and a 6-sensor array.</p> <p>The modules are available in two different output formats: the QTR-xA outputs an analog voltage between 0 and Vcc that can be measured by an analog-to-digital converter (ADC), and the QTR-xRC outputs require a digital I/O line capable of driving the output line high and then measuring the time for the output voltage to decay (which provides an analog measurement of reflectance).</p> <table class="side_by_side_pics"> <tr> <td><table class="picture_with_caption center"><tr><td style="max-width: 200px"><img alt="" class="" data-gallery-pictures="[{&quot;id&quot;:&quot;0J4433&quot;,&quot;caption&quot;:&quot;\u003cp\u003eQTR-L-1A reflectance sensor schematic diagram.\u003c/p\u003e&quot;,&quot;url_tiny&quot;:&quot;https://a.pololu-files.com/picture/0J4433.98x98.jpg?e738d61d87595c2b0ece249fc21fb152&quot;,&quot;url_medium&quot;:&quot;https://a.pololu-files.com/picture/0J4433.600x480.jpg?e738d61d87595c2b0ece249fc21fb152&quot;,&quot;url_full&quot;:&quot;https://a.pololu-files.com/picture/0J4433.1200.png?e738d61d87595c2b0ece249fc21fb152&quot;,&quot;longest_side&quot;:300}]" data-picture-id="0J4433" data-picture-longest_side="300" src="https://a.pololu-files.com/picture/0J4433.200.jpg?e738d61d87595c2b0ece249fc21fb152" /></td></tr><tr><th style="max-width: 200px"><p>QTR-L-1A reflectance sensor schematic diagram.</p></th></tr></table></td> <td><table class="picture_with_caption center"><tr><td style="max-width: 200px"><img alt="" class="" data-gallery-pictures="[{&quot;id&quot;:&quot;0J630&quot;,&quot;caption&quot;:&quot;\u003cp\u003eQTR-1A reflectance sensor schematic diagram.\u003c/p\u003e&quot;,&quot;url_tiny&quot;:&quot;https://a.pololu-files.com/picture/0J630.98x98.jpg?0338402f14f65ad38bf92790ff6b2cde&quot;,&quot;url_medium&quot;:&quot;https://a.pololu-files.com/picture/0J630.600x480.jpg?0338402f14f65ad38bf92790ff6b2cde&quot;,&quot;url_full&quot;:&quot;https://a.pololu-files.com/picture/0J630.1200.png?0338402f14f65ad38bf92790ff6b2cde&quot;,&quot;longest_side&quot;:300}]" data-picture-id="0J630" data-picture-longest_side="300" src="https://a.pololu-files.com/picture/0J630.200.jpg?0338402f14f65ad38bf92790ff6b2cde" /></td></tr><tr><th style="max-width: 200px"><p>QTR-1A reflectance sensor schematic diagram.</p></th></tr></table></td> </tr> </table> <table class="picture_with_caption center"><tr><td style="max-width: 200px"><img alt="" class="" data-gallery-pictures="[{&quot;id&quot;:&quot;0J631&quot;,&quot;caption&quot;:&quot;\u003cp\u003eQTR-1RC and QTR-L-1RC reflectance sensor schematic diagram.\u003c/p\u003e&quot;,&quot;url_tiny&quot;:&quot;https://a.pololu-files.com/picture/0J631.98x98.jpg?ae9455b459ff6470ff8055966838a530&quot;,&quot;url_medium&quot;:&quot;https://a.pololu-files.com/picture/0J631.600x480.jpg?ae9455b459ff6470ff8055966838a530&quot;,&quot;url_full&quot;:&quot;https://a.pololu-files.com/picture/0J631.1200.png?ae9455b459ff6470ff8055966838a530&quot;,&quot;longest_side&quot;:300}]" data-picture-id="0J631" data-picture-longest_side="300" src="https://a.pololu-files.com/picture/0J631.200.jpg?ae9455b459ff6470ff8055966838a530" /></td><p></tr><tr><th style="max-width: 200px"><p>QTR-1RC and QTR-L-1RC reflectance sensor schematic diagram.</p></th></tr></table></p> <p>Please see the <a href="/category/123/pololu-qtr-reflectance-sensors">product pages</a> for more information on how these sensors work.</p> <p>This document will explain how to install Arduino libraries for the Pololu QTR reflectance sensors, and it will provide sample sketches as well as links to library documentation. The libraries will give you everything you need to interface with a QTR-8x reflectance sensor array or multiple QTR-1x reflectance sensors, including advanced features like automatic calibration and, in the case of line detection, calculation of the line&#8217;s position.</p>

2. Library Installation

<p>If you are using version 1.6.2 or later of the <a href="https://www.arduino.cc/en/Main/Software" title="IDE">Arduino software</a>, you can use the Library Manager to install this library:</p> <p>In the Arduino IDE, open the &#8220;Sketch&#8221; menu, select &#8220;Include Library&#8221;, then &#8220;Manage Libraries&#8230;&#8221;.</p> <ol> <li>Search for &#8220;QTRSensors&#8221;.</li> <li>Click the QTRSensors entry in the list.</li> <li>Click &#8220;Install&#8221;.</li> </ol> <p>If this does not work, you can manually install the library:</p> <ol> <li>Download the <a href="https://github.com/pololu/qtr-sensors-arduino/releases">latest release archive from GitHub</a> and decompress it.</li> <li>Rename the folder &#8220;qtr-sensors-arduino-xxxx&#8221; to &#8220;QTRSensors&#8221;.</li> <li>Drag the &#8220;QTRSensors&#8221; folder into the &#8220;libraries&#8221; directory inside your Arduino sketchbook directory. You can view your sketchbook location by opening the &#8220;File&#8221; menu and selecting &#8220;Preferences&#8221; in the Arduino IDE. If there is not already a &#8220;libraries&#8221; folder in that location, you should make the folder yourself.</li> <li>After installing the library, restart the Arduino IDE.</li> </ol> <p>You should now be able to use these libraries in your sketches by selecting <strong>Sketch &gt; Import Library &gt; QTRSensors</strong> from your Arduino IDE (or simply type <strong>#include &lt;QTRSensors.h&gt;</strong> at the top of your sketch). Note that you might need to restart your Arduino IDE before it sees the new libraries.</p> <p>Once this is done, you can create a <strong>QTRSensorsAnalog</strong> object for your QTR-xA sensors and a <strong>QTRSensorsRC</strong> object for your QTR-xRC sensors:</p> <pre name="code" class="c">&#x000A;// create an object for three QTR-xA sensors on analog inputs 0, 2, and 6&#x000A;QTRSensorsAnalog qtra((unsigned char[]) {0, 2, 6}, 3);&#x000A;&#x000A;// create an object for four QTR-xRC sensors on digital pins 0 and 9, and on analog&#x000A;// inputs 1 and 3 (which are being used as digital inputs 15 and 17 in this case)&#x000A;QTRSensorsRC qtrrc((unsigned char[]) {0, 9, 15, 17}, 4);</pre> <p>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, as you can see in the code sample above. The first argument to the QTRSensorsAnalog constructor is an array of analog input pins (0 &#8211; 7) while the first argument to the QTRSensorsRC constructor is an array of digital pins (0 &#8211; 19). Note that analog inputs 0 &#8211; 5 can be used as digital pins 14 &#8211; 19. For more details, see <a href="#3">Section 3</a>.</p> <p>The only other difference you might experience is in the time it takes to read the sensor values. The QTR-xRC sensors can all be read in parallel, but each requires the timing of a pulse that might take as long as 3&nbsp;ms (you can specify how long the library should time this pulse before timing out and declaring the result full black). The QTR-xA sensors use the analog-to-digital converter (ADC) and hence must be read sequentially. Additionally, the analog results are produced by internally averaging a number of samples for each sensor (you can specify the number of samples to average) to decrease the effect of noise on the results.</p> <p>Several example sketches are available to help you get started. To view the example sketches, open the Arduino IDE and navigate to:</p> <p><strong>File &gt; Examples &gt; QTRSensors</strong></p> <p>As a first step, we recommend using <strong>QTRARawValuesExample</strong> (for QTR-xA sensors) or <strong>QTRRCRawValuesExample</strong> (for the QTR-xRC sensors). These examples will simply print the raw readings from the sensors to the serial monitor, using 9600 baud. Once that is working, you might want to try one of the more advanced examples, <strong>QTRAExample</strong> or <strong>QTRRCExample</strong>, which incorporate calibration and also estimate the position of a line.</p>

3. QTRSensors Methods & Usage Notes

<h3>QTRSensors Command Reference</h3> <p class="note">Previous versions of this library were named <strong>PololuQTRSensors</strong>, but we have changed it to <strong>QTRSensors</strong> to differentiate it from the QTR sensor library in our <a href="/docs/0J17">Arduino Libraries for the Orangutan and 3pi Robot</a>.</p> <p class="note">This documentation is for version <strong>3.1.0</strong> of the QTRSensors library. Older versions of the library do not support the dimmable QTR and QTRX sensors.</p> <p>This library defines a class for each of the QTR sensor types, and it takes care of the differences between the analog and RC sensors internally, providing you with a common interface to all types.</p> <p>For non-dimmable QTR-xA sensors, you will want to instantiate a <strong>QTRSensorsAnalog</strong> object, and for non-dimmable QTR-xRC sensors. you will want to instantiate a <strong>QTRSensorsRC</strong> object. Aside from the constructors, these two objects provide the same methods for reading sensor values (both classes are derived from the same abstract base class). The library provides access to the raw sensors values as well as to high level functions including calibration and line-tracking.</p> <p>For dimmable QTR-xD-xA and QTRX-xD-xA sensors, you will want to instantiate a <strong>QTRDimmableAnalog</strong> object, and for dimmable QTR-xD-xRC and QTRX-xD-xRC sensors. you will want to instantiate a <strong>QTRDimmableRC</strong> object. These classes support changing the emitter dimming levels and controlling the odd and even emitters separately on the dimmable sensors.</p> <p>Each of these classes must be instantiated before they are used. This allows multiple QTR sensor arrays to be controlled independently as separate objects.</p> <p>For calibration, memory is allocated using the <b>malloc()</b> command. This conserves RAM: if 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>Internally, this library uses all standard Arduino functions such as micros() for timing and analogRead() or digitalRead() for getting the sensor values, so it should work on all Arduinos without conflicting with other libraries.</p> <div class="libpololu"> <p class="cpp">void <strong>read</strong>(unsigned int *<em>sensorValues</em>, unsigned char <em>readMode</em> = QTR_EMITTERS_ON)</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 (in units of microseconds) provided in the constructor (which defaults to 2500).</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 &#8211; 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> <p class="def">Dimmable QTR sensors with separate CTRL ODD and CTRL EVEN pins also support <strong>QTR_EMITTERS_ODD_EVEN</strong>, where first the odd sensors are read with only the odd emitters on, then the even sensors are read with only the even emitters on, as well as <strong>QTR_EMITTERS_ODD_EVEN_AND_OFF</strong>, which works like a combination of ODD_EVEN and ON_AND_OFF: the odd sensors are read with the odd emitters on, the even sensors are read with the even emitters off, and all sensors are read with all emitters off. These two modes only work if you specify separate odd and even emitter control pins in the constructor.</p> <p class="def">Alternatively, any QTR sensor can be read with <strong>QTR_EMITTERS_MANUAL</strong> instead. This causes the read method to leave the emitters in their existing states instead of automatically turning them on or off before and after each reading.</p> <h4>Example usage:</h4> <pre name="code" class="c">&#x000A;unsigned int sensor_values[8];&#x000A;sensors.read(sensor_values);</pre> <p class="cpp">void <strong>emittersOn</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 unless <em>readMode</em> is <strong>QTR_EMITTERS_MANUAL</strong>, but you may wish to use these for testing purposes. This method will only do something if the emitter pin specified in the constructor is not <strong>QTR_NO_EMITTER_PIN</strong>.</p> <p class="cpp">void <strong>emittersOn</strong>(unsigned char <em>bank</em>, bool <em>wait</em> = true)</p> <p class="def"><em>Dimmable only:</em> This version of emittersOn() turns on the emitters for the specified <em>bank</em>, which is either <strong>QTR_BANK_ODD</strong> or <strong>QTR_BANK_EVEN</strong>. It will only work if you have specified separate odd and even emitter pins. If <em>wait</em> is false, the function will return immediately instead of waiting until the emitters actually turn on.</p> <p class="cpp">void <strong>emittersOff</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 unless the <em>readMode</em> is <strong>QTR_EMITTERS_MANUAL</strong>, but you may wish to use these for testing purposes.</p> <p class="cpp">void <strong>emittersOff</strong>(unsigned char <em>bank</em>, bool <em>wait</em> = true)</p> <p class="def"><em>Dimmable only:</em> This version of emittersOff() turns off the emitters for the specified <em>bank</em>, which is either <strong>QTR_BANK_ODD</strong> or <strong>QTR_BANK_EVEN</strong>. It will only work if you have specified separate odd and even emitter pins. If <em>wait</em> is false, the function will return immediately instead of waiting until the emitters actually turn off.</p> <p class="cpp">void <strong>emitterBankSelect</strong>(unsigned char <em>bank</em>)</p> <p class="def"><em>Dimmable only:</em> This function turns on the selected <em>bank</em> (<strong>QTR_BANK_ODD</strong> or <strong>QTR_BANK_EVEN</strong>) of emitters while turning off the other bank. It performs both of these operations at the same time and waits for both banks of emitters to be in the right states before returning, but it eliminates unnecessary delays that would happen if you called emitersOff() and emittersOn() separately. This function will only work if you have specified separate odd and even emitter pins.</p> <p class="cpp">void <strong>setDimmingLevel</strong>(unsigned char dimmingLevel)</p> <p class="def"><em>Dimmable only:</em> Sets the dimming level for the emitters (0&ndash;31). A dimming level of 0 corresponds to full current and brightness, with higher dimming levels meaning lower currents; see your sensor board&#8217;s product page for details. The dimming level takes effect the next time <b>emittersOn()</b> is called (which can happen in the read method). If the emitters are already on, you should call <b>emittersOff()</b> before calling emittersOn() to apply the dimming level.</p> <p class="cpp">unsigned char <strong>getDimmingLevel</strong>()</p> <p class="def"><em>Dimmable only:</em> Returns the current emitter dimming level.</p> <p class="cpp">void <strong>calibrate</strong>(unsigned char <em>readMode</em> = QTR_EMITTERS_ON)</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 <b>calibratedMinimumOn</b>, <b>calibratedMaximumOn</b>, <b>calibratedMinimumOff</b>, and <b>calibratedMaximumOff</b>. 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 <b>calibrate()</b> 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 <strong>readCalibrated</strong>(unsigned int *<em>sensorValues</em>, unsigned char <em>readMode</em> = QTR_EMITTERS_ON)</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 <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="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 (or was last seen by sensor 0 before being lost), a return value of 1000 indicates that the line is directly below sensor 1, 2000 indicates that it&#8217;s below sensor 2, etc. Intermediate values indicate that the line is between two sensors. The formula is:</p> <pre>&#x000A; 0*value0 + 1000*value1 + 2000*value2 + ...&#x000A;--------------------------------------------&#x000A; value0 + value1 + value2 + ...</pre> <p>As long as your sensors aren&#8217;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&#8217;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* <strong>calibratedMinimumOn</strong></p> <p class="def">The calibrated minimum 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 <i>readMode</i> 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.</p> <p class="cpp">unsigned int* <strong>calibratedMaximumOn</strong></p> <p class="def">The calibrated maximum values measured for each sensor, with emitters on.</p> <p class="cpp">unsigned int* <strong>calibratedMinimumOff</strong></p> <p class="def">The calibrated minimum values measured for each sensor, with emitters off.</p> <p class="cpp">unsigned int* <strong>calibratedMaximumOff</strong></p> <p class="def">The calibrated maximum values measured for each sensor, with emitters off.</p> <p class="cpp">Destructor: <strong>~QTRSensors</strong>()</p> <p class="def">The destructor for the QTRSensors class frees up memory allocated for the calibration arrays.</p> <p class="cpp">Constructor: <strong>QTRSensorsRC</strong>()</p> <p class="def">This version of the 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">Constructor: <strong>QTRSensorsRC</strong>(unsigned char* <em>digitalPins</em>, unsigned char <em>numSensors</em>, unsigned int <em>timeout</em> = 2500, unsigned char <em>emitterPin</em> = QTR_NO_EMITTER_PIN)</p> <p class="def">This constructor just calls <b>init()</b>, below.</p> <p class="cpp">void QTRSensorsRC::<strong>init</strong>(unsigned char* <em>digitalPins</em>, unsigned char <em>numSensors</em>, unsigned int <em>timeout</em> = 2500, unsigned char <em>emitterPin</em> = QTR_NO_EMITTER_PIN)</p> <p class="def">Initializes a QTR-RC (digital) sensor array.</p> <p class="def">The array <em>digitalPins</em> should contain the Arduino digital pin numbers for each sensor.</p> <p class="def"><em>numSensors</em> specifies the length of the <i>digitalPins</i> 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 microseconds 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.</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 does not exist on some of the QTR sensor arrays. If a valid pin is specified, the emitters will only be turned on during a reading. If the value <strong>QTR_NO_EMITTER_PIN</strong> (255) is used, you can leave the emitter pin disconnected and the IR emitters will always be on.</p> <p class="cpp">Constructor: <strong>QTRSensorsAnalog</strong>()</p> <p class="def">This version of the 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">Constructor: <strong>QTRSensorsAnalog</strong>(unsigned char* <em>analogPins</em>, unsigned char <em>numSensors</em>, unsigned char <em>numSamplesPerSensor</em> = 4, unsigned char <em>emitterPin</em> = QTR_NO_EMITTER_PIN)</p> <p class="def">This constructor just calls <b>init()</b>, below.</p> <p class="cpp">void <strong>init</strong>(unsigned char* <em>analogPins</em>, unsigned char <em>numSensors</em>, unsigned char <em>numSamplesPerSensor</em> = 4, unsigned char <em>emitterPin</em> = QTR_NO_EMITTER_PIN)</p> <p class="def">Initializes a QTR-A (analog) sensor array.</p> <p class="def">The array <em>pins</em> should contain the Arduino analog input pin number 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.</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 16.</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. This parameter must not exceed 64. Recommended value: 4.</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 does not exist on some of the QTR sensor arrays. If a valid pin is specified, the emitters will only be turned on during a reading. If the value <strong>QTR_NO_EMITTER_PIN</strong> (255) is used, you can leave the emitter pin disconnected and the IR emitters will always be on.</p> <p class="cpp">Constructor: <strong>QTRDimmableRC</strong>()</p> <p class="def">This version of the 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">Constructor: <strong>QTRDimmableRC</strong>(unsigned char* <em>digitalPins</em>, unsigned char <em>numSensors</em>, unsigned int <em>timeout</em> = 2500, unsigned char <em>emitterPin</em> = QTR_NO_EMITTER_PIN)</p> <p class="def">This constructor just calls <b>init()</b>, below, with one emitter pin for controlling one bank (or both banks combined).</p> <p class="cpp">Constructor: <strong>QTRDimmableRC</strong>(unsigned char* <em>digitalPins</em>, unsigned char <em>numSensors</em>, unsigned int <em>timeout</em>, unsigned char <em>oddEmitterPin</em>, unsigned char <em>evenEmitterPin</em>)</p> <p class="def">This constructor just calls <b>init()</b>, below, with two emitter pins for controlling two banks separately.</p> <p class="cpp">void QTRDimmableRC::<strong>init</strong>(unsigned char* <em>digitalPins</em>, unsigned char <em>numSensors</em>, unsigned int <em>timeout</em> = 2500, unsigned char <em>emitterPin</em> = QTR_NO_EMITTER_PIN)</p> <p class="def">Initializes a QTR-xD-xRC or QTRX-xD-xRC (digital) sensor array with one emitter pin. This version of init() works the same as the (non-dimmable) QTRSensorsRC version.</p> <p class="cpp">void QTRDimmableRC::<strong>init</strong>(unsigned char* <em>digitalPins</em>, unsigned char <em>numSensors</em>, unsigned int <em>timeout</em>, unsigned char <em>oddEmitterPin</em>, unsigned char <em>evenEmitterPin</em>)</p> <p class="def">Initializes a QTR-xD-xRC or QTRX-xD-xRC (digital) sensor array with two emitter pins for separate control of the odd and even emitters.</p> <p class="cpp">Constructor: <strong>QTRDimmableAnalog</strong>()</p> <p class="def">This version of the 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">Constructor: <strong>QTRDimmableAnalog</strong>(unsigned char* <em>digitalPins</em>, unsigned char <em>numSensors</em>, unsigned char <em>numSamplesPerSensor</em> = 4, unsigned char <em>emitterPin</em> = QTR_NO_EMITTER_PIN)</p> <p class="def">This constructor just calls <b>init()</b>, below, with one emitter pin for controlling one bank (or both banks combined).</p> <p class="cpp">Constructor: <strong>QTRDimmableAnalog</strong>(unsigned char* <em>digitalPins</em>, unsigned char <em>numSensors</em>, unsigned char <em>numSamplesPerSensor</em>, unsigned char <em>oddEmitterPin</em>, unsigned char <em>evenEmitterPin</em>)</p> <p class="def">This constructor just calls <b>init()</b>, below, with two emitter pins for controlling two banks separately.</p> <p class="cpp">void QTRDimmableAnalog::<strong>init</strong>(unsigned char* <em>digitalPins</em>, unsigned char <em>numSensors</em>, unsigned char <em>numSamplesPerSensor</em> = 4, unsigned char <em>emitterPin</em> = QTR_NO_EMITTER_PIN)</p> <p class="def">Initializes a QTR-xD-xA or QTRX-xD-xA (analog) sensor array with one emitter pin. This version of init() works the same as the (non-dimmable) QTRSensorsAnalog version.</p> <p class="cpp">void QTRDimmableAnalog::<strong>init</strong>(unsigned char* <em>digitalPins</em>, unsigned char <em>numSensors</em>, unsigned char <em>numSamplesPerSensor</em>, unsigned char <em>oddEmitterPin</em>, unsigned char <em>evenEmitterPin</em>)</p> <p class="def">Initializes a QTR-xD-xRC or QTRX-xD-xRC (analog) sensor array with two emitter pins for separate control of the odd and even emitters.</p> </div> <h3>Usage Notes</h3> <h4>Calibration</h4> <p>This library allows you to use the <strong>calibrate()</strong> method to easily calibrate your sensors for the particular conditions it will encounter. Calibrating your sensors can lead to substantially more reliable sensor readings, which in turn can help simplify your code since. As such, we recommend you build a calibration phase into your application&#8217;s initialization routine. This can be as simple as a fixed duration over which you repeated call the <strong>calibrate()</strong> method. During this calibration phase, you will need to expose each of your reflectance sensors to the lightest and darkest readings they will encounter. For example, if you have made a line follower, you will want to slide it across the line during the calibration phase so the each sensor can get a reading of how dark the line is and how light the ground is. A sample calibration routine would be:</p> <pre name="code" class="c">&#x000A;#include &lt;QTRSensors.h&gt;&#x000A;&#x000A;// create an object for your type of sensor (RC or Analog)&#x000A;// in this example we have three sensors on analog inputs 0 - 2 (digital pins 14 - 16)&#x000A;QTRSensorsRC qtr((char[]) {14, 15, 16}, 3);&#x000A;// QTRSensorsA qtr((char[]) {0, 1, 2}, 3);&#x000A;&#x000A;void setup()&#x000A;{&#x000A; // optional: wait for some input from the user, such as a button press&#x000A;&#x000A; // then start calibration phase and move the sensors over both&#x000A; // reflectance extremes they will encounter in your application:&#x000A; int i;&#x000A; for (i = 0; i &lt; 250; i++) // make the calibration take about 5 seconds&#x000A; {&#x000A; qtr.calibrate();&#x000A; delay(20);&#x000A; }&#x000A;&#x000A; // optional: signal that the calibration phase is now over and wait for further&#x000A; // input from the user, such as a button press&#x000A;}</pre> <h4>Reading the Sensors</h4> <p>This library gives you a number of different ways to read the sensors.</p> <ol> <li>You can request raw sensor values using the <strong>read()</strong> method, which takes an optional argument that lets you perform the read with the IR emitters turned off (note that turning the emitters off is only supported by the QTR-8x reflectance sensor arrays).</li> <li>You can request calibrated sensor values using the <strong>readCalibrated()</strong> method, which also takes an optional argument that lets you perform the read with the IR emitters turned off. Calibrated sensor values will always range from 0 to 1000, with 0 being as or more reflective (i.e. whiter) than the most reflective surface encountered during calibration, and 1000 being as or less reflective (i.e. blacker) than the least reflective surface encountered during calibration.</li> <li>For line-detection applications, you can request the line location using the <strong>readLine()</strong> method, which takes as optional parameters a boolean that indicates whether the line is white on a black background or black on a white background, and a boolean that indicates whether the IR emitters should be on or off during the measurement. <strong>readLine()</strong> provides calibrated values for each sensor and returns an integer that tells you where it thinks the line is. If you are using <i>N</i> sensors, a returned value of 0 means it thinks the line is on or to the outside of sensor 0, and a returned value of 1000 * (<i>N</i>-1) means it thinks the line is on or to the outside of sensor <i>N</i>-1. As you slide your sensors across the line, the line position will change monotonically from 0 to 1000 * (<i>N</i>-1), or vice versa. This line-position value can be used for closed-loop PID control.</li> </ol> <p>A sample routine to obtain the sensor values and perform rudimentary line following would be:</p> <pre name="code" class="c">&#x000A;void loop()&#x000A;{&#x000A; unsigned int sensors[3];&#x000A; // get calibrated sensor values returned in the sensors array, along with the line&#x000A; // position, which will range from 0 to 2000, with 1000 corresponding to the line&#x000A; // over the middle sensor.&#x000A; int position = qtr.readLine(sensors);&#x000A;&#x000A; // if all three sensors see very low reflectance, take some appropriate action for this &#x000A; // situation.&#x000A; if (sensors[0] &gt; 750 &amp;&amp; sensors[1] &gt; 750 &amp;&amp; sensors[2] &gt; 750)&#x000A; {&#x000A; // do something. Maybe this means we're at the edge of a course or about to fall off &#x000A; // a table, in which case, we might want to stop moving, back up, and turn around.&#x000A; return;&#x000A; }&#x000A;&#x000A; // compute our "error" from the line position. We will make it so that the error is&#x000A; // zero when the middle sensor is over the line, because this is our goal. Error&#x000A; // will range from -1000 to +1000. If we have sensor 0 on the left and sensor 2 on&#x000A; // the right, a reading of -1000 means that we see the line on the left and a reading&#x000A; // of +1000 means we see the line on the right.&#x000A; int error = position - 1000;&#x000A;&#x000A; int leftMotorSpeed = 100;&#x000A; int rightMotorSpeed = 100;&#x000A; if (error &lt; -500) // the line is on the left&#x000A; leftMotorSpeed = 0; // turn left&#x000A; if (error &gt; 500) // the line is on the right&#x000A; rightMotorSpeed = 0; // turn right&#x000A;&#x000A; // set motor speeds using the two motor speed variables above&#x000A;}</pre> <h4>PID Control</h4> <p>The integer value returned by <strong>readLine()</strong> can be easily converted into a measure of your position error for line-following applications, as was demonstrated in the previous code sample. The function used to generate this position/error value is designed to be monotonic, which means the value will almost always change in the same direction as you sweep your sensors across the line. This makes it a great quantity to use for PID control.</p> <p>Explaining the nature of PID control is beyond the scope of this document, but wikipedia has a very good <a href="http://en.wikipedia.org/wiki/PID_controller">article</a> on the subject.</p> <p>The following code gives a very simple example of PD control (I find the integral PID term is usually not necessary when it comes to line following). The specific nature of the constants will be determined by your particular application, but you should note that the derivative constant <i>Kd</i> is usually much bigger than the proportional constant <i>Kp</i>. This is because the derivative of the error is a much smaller quantity than the error itself, so in order to produce a meaningful correction it needs to be multiplied by a much larger constant.</p> <pre name="code" class="c">&#x000A;int lastError = 0;&#x000A;&#x000A;void loop()&#x000A;{&#x000A; unsigned int sensors[3];&#x000A; // get calibrated sensor values returned in the sensors array, along with the line&#x000A; // position, which will range from 0 to 2000, with 1000 corresponding to the line over&#x000A; // the middle sensor&#x000A; int position = qtr.readLine(sensors);&#x000A;&#x000A; // compute our "error" from the line position. We will make it so that the error is zero&#x000A; // when the middle sensor is over the line, because this is our goal. Error will range&#x000A; // from -1000 to +1000. If we have sensor 0 on the left and sensor 2 on the right, &#x000A; // a reading of -1000 means that we see the line on the left and a reading of +1000 &#x000A; // means we see the line on the right.&#x000A; int error = position - 1000;&#x000A;&#x000A; // set the motor speed based on proportional and derivative PID terms&#x000A; // KP is the a floating-point proportional constant (maybe start with a value around 0.1)&#x000A; // KD is the floating-point derivative constant (maybe start with a value around 5)&#x000A; // note that when doing PID, it's very important you get your signs right, or else the&#x000A; // control loop will be unstable&#x000A; int motorSpeed = KP * error + KD * (error - lastError);&#x000A; lastError = error;&#x000A;&#x000A; // M1 and M2 are base motor speeds. That is to say, they are the speeds the motors&#x000A; // should spin at if you are perfectly on the line with no error. If your motors are&#x000A; // well matched, M1 and M2 will be equal. When you start testing your PID loop, it&#x000A; // might help to start with small values for M1 and M2. You can then increase the speed&#x000A; // as you fine-tune your PID constants KP and KD.&#x000A; int m1Speed = M1 + motorSpeed;&#x000A; int m2Speed = M2 - motorSpeed;&#x000A;&#x000A; // it might help to keep the speeds positive (this is optional)&#x000A; // note that you might want to add a similiar line to keep the speeds from exceeding&#x000A; // any maximum allowed value&#x000A; if (m1Speed &lt; 0)&#x000A; m1Speed = 0;&#x000A; if (m2Speed &lt; 0)&#x000A; m2Speed = 0;&#x000A;&#x000A; // set motor speeds using the two motor speed variables above&#x000A;}</pre>

New Products

Pololu Distance Sensor v2 with Pulse Width Output, 50cm Max, Side-Entry Connector
RobustMotion RM-EGB Series 24VDC Compact Finger Gripper, 16D, Simple PNP Interface
JST PH-Style Cable, 2-Pin, Female-Female, 25cm
9V, 500mA Step-Down Voltage Regulator D45V5F9
Pololu Digital Distance Sensor v2, 10cm, Side-Entry Connector
ACS37030LLZATR-065B3 Current Sensor Compact Carrier -65A to +65A, 3.3V
ACS37042KLHBLT-010B3 Current Sensor Compact Carrier -10A to +10A, 3.3V
ACS37042KLHBLT-030B5 Current Sensor Micro Carrier -30A to +30A, 5V
Breakout for JST PH-Style Connector, 5-Pin Male Side-Entry, with SH
ACS37042KLHBLT-030B3 Current Sensor Compact Carrier -30A to +30A, 3.3V
Log In
Pololu Robotics & Electronics
Shopping cart
(702) 262-6648
Same-day shipping, worldwide
Menu
Shop Blog Forum Support
My account Comments or questions? About Pololu Contact Ordering information Distributors