Pololu AVR Library Command Reference
Pololu AVR Library Command Reference
Pololu AVR Library Command Reference
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Orangutan Analog-to-Digital Conversion . . . . . . . . . . . . . . . . . . . . . . . . . 4
3. Orangutan Buzzer: Beeps and Music . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4. Orangutan Digital I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
5. Orangutan LCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
6. Orangutan LEDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
7. Orangutan Motor Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
8. Orangutan Pushbuttons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
9. Orangutan Serial Port Communication . . . . . . . . . . . . . . . . . . . . . . . . . 26
10. Orangutan Servos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
11. Orangutan SPI Master Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
12. Orangutan SVP Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
13. Orangutan System Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
14. QTR Reflectance Sensors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
15. Timing and Delays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
16. Wheel Encoders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
17. 3pi Robot Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Page 1 of 52
Pololu AVR Library Command Reference © 2001–2010 Pololu Corporation
1. Introduction
This document describes a programming library designed for use with Pololu products.
The library is used to create programs that run on Atmel ATmega1284PA, ATmega324PA,
ATmega328P, ATmega168 and ATmega48 processors, and it supports the following
products:
Pololu 3pi robot: a mega168/328-based robot controller. The 3pi robot essentially
contains an SV-328 and a 5-sensor version of the QTR-8RC, both of which are in the
list below.
Pololu Orangutan SVP-324: based on the mega324, the SVP-324 robot controller
is a super-sized version of the SV-328, with a built-in AVR ISP programmer, more I/O
lines, and more regulated power.
Pololu Orangutan SVP-1284: based on the mega1284, the SVP-1284 robot
controller is a super-sized version of the SV-328, with a built-in AVR ISP programmer,
more I/O lines, more regulated power, and more memory.
Pololu Orangutan SV-328: a full-featured, mega328-based robot controller that
includes an LCD display. The SV-328 runs on an input voltage of 6-13.5V, giving
you a wide range of robot power supply options, and can supply up to 3 A on its
regulated 5 V bus. This library also supports the original Orangutan SV-168, which
was replaced by the SV-328.
Pololu Orangutan LV-168: a full-featured, mega168-based robot controller that
includes an LCD display. The LV-168 runs on an input voltage of 2-5V, allowing two
or three batteries to power a robot.
Pololu Baby Orangutan B-48: a compact, complete robot controller based on the
mega48. The B-48 packs a voltage regulator, processor, and a two-channel motor-
driver into a 24-pin DIP format.
Pololu Baby Orangutan B-328: a mega328 version of the above. The mega328
offers more memory for your programs (32 KB flash, 2 KB RAM). This library also
supports the Baby Orangutan B-168, which was replaced by the Baby B-328.
Pololu QTR-1A and QTR-8A reflectance sensors (analog): an analog sensor
containing IR/phototransistor pairs that allows a robot to detect the difference
between shades of color. The QTR sensors can be used for following lines on the
floor, for obstacle or drop-off (stairway) detection, and for various other applications.
Pololu QTR-1RC and QTR-8RC reflectance sensors (RC): a version of the above
that is read using digital inputs; this is compatible with the Parallax QTI sensors.
Encoder for Pololu Wheel 42x19 mm: a wheel encoder solution that allows a
robot to measure how far it has traveled.
The library is written in C++ and may be used in three different programming
environments:
1. Introduction Page 2 of 52
Pololu AVR Library Command Reference © 2001–2010 Pololu Corporation
• C++: supported by the AVR-GCC/WinAVR project. See the Pololu AVR C/C++
Library User’s Guide [http://www.pololu.com/docs/0J20] to get started.
• C / AVR Studio: bindings to the C language are included in the library so that
you can write programs entirely in C, which is the standard for Atmel’s AVR
Studio [http://www.atmel.com/avrstudio/]. See the Pololu AVR C/C++ Library User’s
Guide [http://www.pololu.com/docs/0J20] to get started.
1. Introduction Page 3 of 52
Pololu AVR Library Command Reference © 2001–2010 Pololu Corporation
For a higher level overview of this library and example programs that show how this library
can be used, please see Section 5.a of the guide to Programming Orangutans and the
3pi Robot from the Arduino Environment [http://www.pololu.com/docs/0J17] or Section 6.c
of the Pololu AVR C/C++ Library User’s Guide [http://www.pololu.com/docs/0J20].
Channels
The tables below give a summary of the analog inputs available on your AVR. Some of
these pins are hardwired to sensors or trimpots built in to your device, while other pins are
available for you to connect your own sensors to. Please refer to the pin assignment table in
the user’s guide for your device for more information.
Analog Channels on the 3pi robot, SV-xx8, LV-168, and Baby Orangutan
Channel Pin Keyword Note
0 PC0/ADC0
1 PC1/ADC1
2 PC2/ADC2
3 PC3/ADC3
4 PC4/ADC4
5 PC5/ADC5
6 ADC6 TEMP_SENSOR External temperature sensor on LV-168
7 ADC7 TRIMPOT User trimmer potentiometer
Reading the analog channels on the Orangutan SVP that are measured by the auxiliary
processor requires the auxiliary processor to be in the correct mode. See the documentation
for the setMode command in Section 12 for more information.
Function Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
Example:
// run the ADC in 10-bit conversion mode
OrangutanAnalog::setMode(MODE_10_BIT);
during the conversions; after the conversions, the pin is restored to its previous state.
On the Orangutan SVP, the channels measured by the auxiliary processor are averaged
on the auxiliary processor, and the library does not support further averaging. For those
channels, this function is equivalent to analog_read.
conversion on an analog input with this method, then poll isConverting() in your main
loop. Once isConverting() returns a zero, the result can be obtained through a call to
conversionResult() and this method can be used to start a new conversion. Note that this
function automatically configures the specified pin as an input and disables its internal
pull-up resistor. Since this function only initiates the conversion, it cannot restore the pin
to its previous state once the conversion is finished like the read() method does.
Example:
OrangutanAnalog::toMillivolts(OrangutanAnalog::read(0));
// e.g. will return 5000 if analog input 0 is at 5 V
For a higher level overview of this library and example programs that show how this library
can be used, please see Section 5.b of the guide to Programming Orangutans from the
Arduino Environment [http://www.pololu.com/docs/0J17] or Section 6.d of the Pololu AVR
C/C++ Library User’s Guide [http://www.pololu.com/docs/0J20].
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
Example
// play a 6 kHz note for 250 ms at half volume
OrangutanBuzzer::playFrequency(6000, 250, 7);
// wait for buzzer to finish playing the note
while (OrangutanBuzzer::isPlaying());
Note Macros
To make it easier for you to specify notes in your code, this library defines the following
macros:
#define G( x ) ( 7 + x*12 )
#define G_SHARP( x ) ( 8 + x*12 )
#define A_FLAT( x ) ( 8 + x*12 )
#define A( x ) ( 9 + x*12 )
#define A_SHARP( x ) ( 10 + x*12 )
#define B_FLAT( x ) ( 10 + x*12 )
#define B( x ) ( 11 + x*12 )
The notes are specified by the characters C, D, E, F, G, A, and B, and they are played
by default as “quarter notes” with a length of 500 ms. This corresponds to a tempo of
120 beats/min. Other durations can be specified by putting a number immediately after
the note. For example, C8 specifies C played as an eighth note, with half the duration of
a quarter note. The special note R plays a rest (no sound). The sequence parser is case-
insensitive and ignore spaces, which may be used to format your music nicely.
• ’!’ resets the octave, tempo, duration, volume, and staccato setting to their default
values. These settings persist from one play() to the next, which allows you to more
conveniently break up your music into reusable sections.
• ‘1’ – "2000": when immediately following a note, a number determines the duration
of the note. For example, C16 specifies C played as a sixteenth note (1/16th the length
of a whole note).
Examples:
// play a C major scale up and back down:
OrangutanBuzzer::play("!L16 V8 cdefgab>cbagfedc");
Example:
#include <avr/pgmspace.h>
const char melody[] PROGMEM = "!L16 V8 cdefgab>cbagfedc";
void someFunction()
{
OrangutanBuzzer::playFromProgramSpace(melody);
}
This method returns 1 (true) if the buzzer is currently playing a note/frequency. Otherwise,
it returns 0 (false). You can poll this method to determine when it’s time to play the next
note in a sequence, or you can use it as the argument to a delay loop to wait while the
buzzer is busy.
For a high-level explanation of what the AVR’s digital I/O pins can do, and example programs
using this section of the library, see Section 6.e of the Pololu AVR C/C++ Library User’s
Guide [http://www.pololu.com/docs/0J20].
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
5. Orangutan LCD
The OrangutanLCD class and the C functions in this section provide a variety of ways of
displaying data to the LCD screen of an Orangutan SV, Orangutan LV-168, Orangutan SVP,
and 3pi robot, providing an essential tool for user interfaces and debugging. The library
implements the standard 4-bit HD44780 protocol, and it uses the busy-wait-flag feature
to avoid the unnecessarily long delays present in other 4-bit LCD Arduino libraries. It is
designed to gracefully handle alternate use of the four LCD data lines. It will change their
data direction registers and output states only when needed for an LCD command, after
which it will immediately restore the registers to their previous states. This allows the LCD
data lines to function, for example, as pushbutton inputs and an LED driver on the 3pi and
Orangutans.
For a list of the standard characters available on the LCD, see page 17 of the HD44780
interface datasheet [http://www.pololu.com/file/download/HD44780.pdf?file_id=0J72] (330k pdf).
For C and C++ users, the standard C function printf() is made available. See below for
more information.
For a higher level overview of this library and example programs that show how this library
can be used, please see Section 5.c of the guide to Programming Orangutans from the
Arduino Environment [http://www.pololu.com/docs/0J17] or Section 6.f of the Pololu AVR
C/C++ Library User’s Guide [http://www.pololu.com/docs/0J20].
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
void OrangutanLCD::initPrintf()
void lcd_init_printf()
Initializes the display for use with the standard C function printf(). This is not available
in the Arduino environment. See the avr-libc manual [http://www.nongnu.org/avr-libc/user-
manual/group__avr__stdio.html] for more information on how to use printf with an AVR, and
please note that using printf() will consume a significant amount of your Orangutan’s
resources.
Example:
OrangutanLCD::print('A');
Example:
OrangutanLCD::print("Hello!");
Example:
#include <avr/pgmspace.h>
const char hello[] PROGMEM = "Hello ";
void someFunction()
{
OrangutanLCD::printFromProgramSpace(hello);
OrangutanLCD::printFromProgramSpace(PSTR("there!"));
}
Prints the specified signed integer (2-byte) value to the display at the current cursor
position. It will not wrap or otherwise span lines. There is no C version of this method, but
print_long(value) should be sufficient.
Example:
OrangutanLCD::print(-25);
Note: the clear() method must be called before these characters are used.
The pointer picture_ptr must be a pointer to an 8 byte array in program space containing
the picture data. Bit 0 of byte 0 is the upper-right pixel of the 5x8 character, and bit 4 of
byte 7 is the lower-left pixel. The example below demonstrates how to construct this kind
of array.
Example:
#include <avr/pgmspace.h>
// the PROGMEM macro comes from the pgmspace.h header file
// and causes the smile pointer to point to program memory instead
// of RAM
const char smile[] PROGMEM = {
0b00000,
0b01010,
0b01010,
0b01010,
0b00000,
0b10001,
0b01110,
0b00000
};
void setup()
{
// set character 3 to a smiley face
OrangutanLCD::loadCustomCharacter(smile, 3);
// clear the lcd (this must be done before we can use the above character)
OrangutanLCD::clear();
6. Orangutan LEDs
The OrangutanLEDs class and the C functions in this section are a very simple interface to
the two user LEDs included on Orangutan controllers and 3pi. Note that the red LED is on
the same pin as the UART0 serial transmitter (PD1), so if you are using UART0 for serial
transmission then the red LED functions will not work, and you will see the red LED blink
briefly whenever data is transmitted on UART0. Note that the green LED is on the same pin
as an LCD control pin; the green LED will blink briefly whenever data is sent to the LCD, but
the two functions will otherwise not interfere with each other.
For a higher level overview of this library and example programs that show how this library
can be used, please see Section 5.d of the guide to Programming Orangutans from the
Arduino Environment [http://www.pololu.com/docs/0J17] or Section 6.g of the Pololu AVR
C/C++ Library User’s Guide [http://www.pololu.com/docs/0J20].
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
Example:
OrangutanLEDs::red(1); // turn the red LED on
Example:
OrangutanLEDs::green(1); // turn the green LED on
For a higher level overview of this library and example programs that show how this library
can be used, please see Section 5.e of the guide to Programming Orangutans from the
Arduino Environment [http://www.pololu.com/docs/0J17] or Section 6.h of the Pololu AVR
C/C++ Library User’s Guide [http://www.pololu.com/docs/0J20].
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
8. Orangutan Pushbuttons
The OrangutanPushbuttons class and the C functions in this section provide access to
the three pushbuttons on the Orangutan SV, Orangutan SVP, Orangutan LV-168, and 3pi.
Various methods are provided for accessing button presses, which will be useful in different
situations.
For a higher level overview of this library and programs that show how this library can
be used, please see Section 5.f of the guide to Programming Orangutans from the
Arduino Environment [http://www.pololu.com/docs/0J17] or Section 6.i of the Pololu AVR
C/C++ Library User’s Guide [http://www.pololu.com/docs/0J20].
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
Example:
unsigned char button = OrangutanPushbuttons::waitForPress(TOP_BUTTON | BOTTOM_BUTTON);
The Baby Orangutan B, Orangutan SV, Orangutan LV-168, and 3pi robot are based on
the ATmega48/168/328 line of AVR processors, which have a single UART that enables
communication on pins PD0 (RXD) and PD1 (TXD). Since there is only one UART on these
devices, you must omit the port argument when using the commands below.
The Orangutan SVP is based on the AVR ATmega324PA or ATmega1284P processor, which
has two UARTs. Port UART0 uses pins PD0 (RXD0) and PD1 (TXD0). Port UART1 uses
pins PD2 (RXD1) and PD3 (TXD1). The SVP also has a port called USB_COMM which lets
you connect your Orangutan directly to a computer to send and receive bytes over USB.
When using this port, you must call check() regularly because this port does not support
interrupts. See the Orangutan SVP User’s Guide for more information about using this port.
Since there are multiple serial ports, you must include the port argument when using the
commands below, and it must be either UART0, UART1, or USB_COMM.
When sending data on a UART, a UDRE interrupt vector is called after each byte is sent,
allowing the library to automatically start sending the next byte from the send buffer. When
receiving data, an RX interrupt vector is called after each byte is received, allowing the
library to automatically store the byte in the receive buffer. To use a polling method instead
of interrupts, see the setMode() and check() functions below.
These functions are not available within the Arduino environment, which has its
own serial functions.
For a higher level overview of this library and programs that show how this library can
be used, please see Section 6.j of the Pololu AVR C/C++ Library User’s
Guide [http://www.pololu.com/docs/0J20].
Reference
C++ methods are shown in red.
C functions are shown in green.
the old buffer will be discarded and tramission will be cut short. This means that you
should almost always wait until the data has been sent before calling this function again.
See sendBlocking(), below, for an easy way to do this.
static void OrangutanSerial::sendBlocking([unsigned char port,] char *buffer,
unsigned char size)
void serial_send_blocking([unsigned char port,] char *buffer, unsigned char size)
Same as send(), but waits until transmission of the last byte has started before returning.
When this function returns, it is safe to call send() or sendBlocking() again.
need to use this function. The default and only allowed mode for the Orangutan SVP’s
USB_COMM port is SERIAL_CHECK, so you should call this function often if you want to
use that port.
This library uses the AVR’s Timer 1 and several interrupts TIMER1_CAPT,
TIMER1_COMPA (not used on the Orangutan SVP), and TIMER1_COMPB.
For a higher-level overview of how servo control works and how the library works on the
different Orangutan models, see Section 6.k of the Pololu AVR C/C++ Library User’s
Guide [http://www.pololu.com/docs/0J20].
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
The servoPins parameter should be the RAM address of an array of AVR IO pin numbers
defined using the IO_* keywords provided by the library (e.g. IO_C0).
The Orangutan SVP version of this function takes an array of AVR pins that you have
wired to the demux selection pins. The length of the array should be 0–3. The number of
servos you can control is 2numPins. The servo pulses are transmitted on pin PD5, which is
connected to the input of the demux.
On the other Orangutans, this function takes an array of AVR pins that you have connected
to the signal pins on your servos. The length of the array should be 0–8. Each pin controls
one servo.
Otherwise, valid target positions are between 400 and 2450 us. The servoNum parameter
should be a servo number between 0 and 7.
SPI is a synchronous communication protocol where the basic transaction consists of the
master pulsing the SPI clock (SCK) line 8 times while bits are simultaneously exchanged
between the (selected) slave and the master on the Master-in/Slave-out (MISO) and Master-
out/Slave-in (MOSI) lines. There is no way for the master to send a byte without receiving
one, and there is no way for the master to receive a byte without sending one.
The functions in this section will automatically configure the MOSI and SCK lines as outputs
and the MISO line as an input.
The AVR’s SPI module is designed so that if the SS pin is an input and it reads low (0 V), then
the SPI module will automatically go in to slave mode (the MSTR bit in SPCR will become
zero) and all SPI transmission functions in this library will return a result of zero. Therefore,
it is recommended to make SS an output before doing SPI master communication. If SS is
an input, then the SPI inititialization routine in this library will enable the pull-up resistor on
that line.
The Orangutan SV, Orangutan LV-168, Baby Orangutan B, and 3pi robot are based on
the ATmega48/168/328 line of AVR processors, so SS is pin PB2, MOSI is PB3, MISO is PB4,
and SCK is PB5.
The Orangutan SVP is based on the AVR ATmega324 or ATmega1284, so SS is pin PB4,
MOSI is PB5, MISO is PB6, and SCK is PB7.
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
The speed_divider parameter specifies the ratio of the AVR’s clock frequency to the SPI
frequency. The library defines several keywords of the form SPI_SPEED_DIVIDER_xxx for
use as the speed_divider argument. These keywords are shown in the table below:
The options argument controls three important configuration options for the SPI module.
The options argument can be 0 to select all the default options. To over-ride the defaults,
the options argument should be a combination of some of the following keywords,
combined using the inclusive-or operator ”|”.
• SPI_SCK_IDLE_LOW (default): The idle state of SCK will be low; the leading edge
will be rising and the trailing edge will be falling.
• SPI_SCK_IDLE_HIGH: The idle state of SCK will be high; the leading edge will be
falling and the trailing edge will be rising.
• SPI_MSB_FIRST (default): Bytes will be transmitted/received starting with the
most-significant bit first.
• SPI_LSB_FIRST: Bytes will be transmitted/received starting with the least-
significant bit first.
• SPI_EDGE_LEADING (default): The AVR will sample data on MISO on the leading
edge of SCK.
• SPI_EDGE_TRAILING: The AVR will sample data on MISO on the trailing edge of
SCK.
Example usage:
// Initialize the SPI module in master mode at 20/2 = 10 MHz, sample on the trailing edge,
// LSB first, SCK idle state low.
OrangutanSPIMaster::init(SPI_SPEED_DIVIDER_2, SPI_EDGE_TRAILING | SPI_LSB_FIRST);
For a higher level overview of how the library works on the Orangutan SVP, please see
Section 6.l of the Pololu AVR C/C++ Library User’s Guide [http://www.pololu.com/docs/
0J20].
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
Additionally, the mode parameter can be inclusively ored with the keyword
SVP_SLAVE_SELECT_ON to enable the SPI slave select feature.
• If SPI slave select is not enabled (default), then the ADC/SS line will be an analog
input. This line is hardwired to a user trimpot, so the name of the analog channel is
TRIMPOT. However, if you want to use this analog input for something else, you can
cut the labeled trace between POT and ADC/SS on the bottom of the board. This is the
default mode; the auxiliary processor will be in this mode whenever it starts running,
and will revert to this mode whenever the AVR is reset for any reason.
• If SPI slave select is enabled, then the line will be used as the SPI slave select
line, SS. When SS is high, the auxiliary processor will ignore all bytes received on SPI
and will not drive the MISO line. This allows the AVR to communicate with other SPI
devices using the hardware SPI module. See Section 11. When SS is driven low, then
the AVR can communicate with the auxiliary processor over SPI as usual. The SS line
is pulled high through a 100 kilo-ohm pull-up resistor.
static unsigned char OrangutanSVP::usbPowerPresent()
unsigned char usb_power_present()
Returns 1 if the voltage on the power line of the USB connector is high. This indicates
that the device is plugged in to a computer or USB power supply. Returns 0 otherwise.
This function is useful if you want your Orangutan to behave differently when it is
plugged in to USB (for example, by not running its motors).
This command asks the Orangutan SVP’s auxiliary processor what version of its
firmware is running. The return value of this function for all Orangutans released
so far should be 1. This command can be useful for testing or debugging the SPI
connection to the auxiliary processor.
Small stack overflows that happen rarely might cause bugs that are subtle and hard to
detect. We recommend that you use getFreeRAM() within your main loop and also at
some points within function calls, especially any recursive or highly nested calls, and cause
your robot to display an error indicator or a warning of some type if memory gets tight.
If your Orangutan is controlling a system that might damage itself or cause danger to
an operator it should go into a safe shutdown mode immediately upon detection of a low
memory error. For example, a BattleBot could shut down all motors, and a robotic aircraft
could deploy its parachute.
By checking available memory at various levels within your code, you can get an idea of
how much memory each function call consumes, and think about redesigning the code
to use memory more efficiently. The getFreeRam() function itself should not take a
noticeable amount of time and use just 6 bytes of RAM itself, so you can use it freely
throughout your code.
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 Section 17 for details.
This section of the library defines an object for each of the two QTR sensor types, with
the PololuQTRSensorsAnalog class intended for use with QTR-xA sensors and the
PololuQTRSensorsRC 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
PololuQTRSensors. This base class cannot be instantiated.
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.
For calibration, memory is allocated using the malloc() 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.
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.
For a higher level overview of this library and example programs that show how this library
can be used, please see the guide Arduino Libraries for the Pololu QTR Reflectance
Sensors [http://www.pololu.com/docs/0J19] or Section 6.m of the Pololu AVR C/C++ Library
User’s Guide [http://www.pololu.com/docs/0J20].
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
The functions that read values from the sensors all take an argument readMode, which
specifies the kind of read that will be performed. Several options are defined:
QTR_EMITTERS_OFF 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; QTR_EMITTERS_ON specifies that the emitters should be turned on for the
reading, which results in a measure of reflectance; and QTR_EMITTERS_ON_AND_OFF
specifies that a reading should be made in both the on and off states. The values returned
when the QTR_EMITTERS_ON_AND_OFF option is used are given by on + max – off,
where on is the reading with the emitters on, off is the reading with the emitters off, and
max 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.
Example usage:
unsigned int sensor_values[8];
sensors.read(sensor_values);
void PololuQTRSensors::emittersOn()
void qtr_emitters_on()
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.
void PololuQTRSensors::emittersOff()
void qtr_emitters_off()
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.
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.
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 whiteLine to true.
In this case, each sensor value will be replaced by the maximum possible value minus its
actual value before the averaging.
PololuQTRSensors::~PololuQTRSensors()
The destructor for the PololuQTRSensors class frees up memory allocated for the
calibration arrays. This feature is not available in C.
PololuQTRSensorsRC::PololuQTRSensorsRC()
This constructor performs no initialization. If it is used, the user must call init() before
using the methods in this class.
The array pins contains the (Arduino) pin numbers for each sensor. For example, if pins
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.
numSensors specifies the length of the ‘pins’ array (the number of QTR-RC sensors you
are using). numSensors must be no greater than 16.
timeout 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
timeout, 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 = timeout 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 = timeout of 5000).
emitterPin 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.
PololuQTRSensorsAnalog::PololuQTRSensorsAnalog()
This constructor performs no initialization. If this constructor is used, the user must call
init() before using the methods in this class.
The array pins contains the analog pin assignment for each sensor. For example, if pins
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.
numSensors specifies the length of the analogPins array (the number of QTR-A sensors
you are using). numSensors must be no greater than 8.
emitterPin is the digital pin (see qtr_rc_init(), 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.
The timing functions use an interrupt on Timer2, which is configured when time_reset(),
get_ms(), or an equivalent function is called. This means that the timing code will conflict
with other code that uses Timer2. However, the functions here are compatible with the other
uses of Timer2 within the Pololu library.
Reference
C++ methods are shown in red.
C/C++ functions are shown in green.
This section of the library makes uses of pin-change interrupts to quickly detect and record
each transition on the encoder.
For a higher level overview of this library and example programs that show how this
library can be used, please see Section 6.n of the Pololu AVR C/C++ Library User’s
Guide [http://www.pololu.com/docs/0J20].
Reference
C++ and Arduino methods are shown in red.
C functions are shown in green.
Using this library will automatically configure Timer2, which will cause it to conflict with
other libraries that use Timer2. See Section 7 (Motors) and Section 14 (Sensors) for more
information.
For a higher level overview of this library and programs that show how this library can be
used, please see the Pololu 3pi Robot User’s Guide [http://www.pololu.com/docs/0J21].
The functions that read values from the sensors all take an argument readMode, which
specifies the kind of read that will be performed. Several options are defined:
IR_EMITTERS_OFF 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; IR_EMITTERS_ON specifies that the emitters should be turned on for the reading,
which results in a measure of reflectance; and IR_EMITTERS_ON_AND_OFF specifies that
a reading should be made in both the on and off states. The values returned when the
IR_EMITTERS_ON_AND_OFF option is used are given by on + max – off, where on is
the reading with the emitters on, off is the reading with the emitters off, and max 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.
Example usage:
unsigned int sensor_values[5];
read_line_sensors(sensor_values);
void Pololu3pi::emittersOn()
void emitters_on()
Turn the IR LEDs on. This is mainly for use by read_line_sensors(), and calling this
function before or after the reading the sensors will have no effect on the readings, but
you may wish to use it for testing purposes.
void Pololu3pi::emittersOff()
void emitters_off()
Turn the IR LEDs off. This is mainly for use by read_line_sensors(), and calling this
function before or after the reading the sensors will have no effect on the readings, but
you may wish to use it for testing purposes.
As long as your sensors aren’t spaced too far apart relative to the line, this returned value
will 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, its line position will continue to indicate the direction you need to go to reacquire
the line. For example, since sensor 4 is your rightmost sensor, if you end up completely off
the line to the left, this function will continue to return 4000.
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 whiteLine to true or
call read_line_white(). In this case, each sensor value will be replaced by the maximum
possible value minus its actual value before the averaging.