19. 3pi Robot Functions

This section of the library provides convenient access for 3pi-specific hardware. Currently, it only provides access for the 5 QTR-based line sensors that are included in the 3pi. That is, the QTR functions described in Section 16 do not need to be used for the 3pi. The functions described below are enabled by including one of the 3pi files:

#include <pololu/3pi.h>        // use this line for C
#include <pololu/Pololu3pi.h>  // use this line for C++

The necessary Orangutan include files will be included automatically.

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 16 (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.

static unsigned char Pololu3pi::init(unsigned int line_sensor_timeout = 1000, unsigned char disable_emitter_pin = 0)

unsigned char pololu_3pi_init(unsigned int line_sensor_timeout)

unsigned char pololu_3pi_init_disable_emitter_pin(unsigned int line_sensor_timeout)

Initializes the 3pi robot. This sets up the line sensors, turns the IR emitters off to save power, and resets the system timer (except within the Arduino environment). The parameter line_sensor_timeout specifies the timeout in Timer2 counts. This number should be the length of time in Timer2 counts beyond which you consider the sensor reading completely black. It is recommended that you set timeout to be between 500 and 3000 us, depending on factors like the ambient lighting. This allows you to shorten the duration of a sensor-reading cycle while maintaining useful measurements of reflectance. For the 3pi, you can convert Timer2 counts to microseconds by dividing by 2.5 or multiplying by 0.4 (2000 us = 5000 Timer2 counts = line_sensor_timeout of 5000). Setting disable_emitter_pin to 1 (C++) or calling the function pololu_3pi_init_disable_emitter_pin() causes pin PC5 to not be used at all by the library, so that you can use it for something else.

void Pololu3pi::readLineSensors(unsigned int *sensorValues, unsigned char readMode = IR_EMITTERS_ON)

void read_line_sensors(unsigned int *sensorValues, unsigned char readMode)

Reads the raw sensor values into an array. There MUST be space for five unsigned int values in the array. The values returned are a measure of the reflectance, between 0 and the line_sensor_timeout argument provided in to the init() function.

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.

void Pololu3pi::calibrate(unsigned char readMode = IR_EMITTERS_ON)

void calibrate_line_sensors(unsigned char readMode)

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 readLineSensorsCalibrated() method.

void Pololu3pi::readLineSensorsCalibrated(unsigned int *sensorValues, unsigned char readMode = IR_EMITTERS_ON)

void read_line_sensors_calibrated(unsigned int *sensorValues, unsigned char readMode)

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 calibrate() 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.

unsigned int Pololu3pi::readLine(unsigned int *sensorValues, unsigned char readMode = IR_EMITTERS_ON, unsigned char whiteLine = 0)

unsigned int read_line(unsigned int *sensorValues, unsigned char readMode)

unsigned int read_line_white(unsigned int *sensorValues, unsigned char readMode)

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 2000, etc. Intermediate values indicate that the line is between two sensors. The formula is:

 0*value0 + 1000*value1 + 2000*value2 + ...
--------------------------------------------
     value0  +  value1  +  value2 + ...

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.

unsigned int* Pololu3pi::getLineSensorsCalibratedMinimumOn()

unsigned int* get_line_sensors_calibrated_minimum_on()

The calibrated minumum values measured for each sensor, with emitters on. The pointers are unallocated and set to 0 until calibrate() 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. You can use them for your own calculations and do things like saving the values to EEPROM, performing sanity checking, etc.

unsigned int* PololuQTRSensors::getLineSensorsCalibratedMaximumOn()

unsigned int* get_line_sensors_calibrated_maximum_on()

The calibrated maximum values measured for each sensor, with emitters on.

unsigned int* PololuQTRSensors::getLineSensorsCalibratedMinimumOff()

unsigned int* get_line_sensors_calibrated_minimum_off()

The calibrated minimum values measured for each sensor, with emitters off.

unsigned int* PololuQTRSensors::getLineSensorsCalibratedMaximumOff()

unsigned int* get_line_sensors_calibrated_maximum_off()

The calibrated maximum values measured for each sensor, with emitters off.