2.9. 3pi API

The 3pi API was developed by Pololu to simplify the interaction with the robot's components. The header which needs to be included is pololu/3pi.h

 #include <pololu/3pi.h> 

Functions used to initialize the robot

Before explaining some of the functions used to interact with other components the robot needs to be initialized.

 unsigned char pololu_3pi_init(unsigned int line_sensor_timeout) 

The purpose of the function is to:

  • turn the IR emitters off to save power
  • reset the system timer
  • set the line of sensors

The parameter represents the amount of time beyond which the reading of one sensor will be considered black; 2000 is the value that works for almost all the cases.

Functions used to interact with analog components

To easily read the values provided by analog components (e.g. the value of the potentiometer, battery voltage, various sensors), 3pi API library provides several functions:

 void set_analog_mode(unsigned char mode) 

The above function is used to set the number of bits available to store the result of the analog_read(unsigned char channel) function. The user can set the mode of the conversion to:

  • MODE_8_BIT - results will be between 0 – 255 for voltages from 0 to 5V
  • MODE_10_BIT - results will be between 0 – 1023 for voltages from 0 to 5V

The default mode on the 3pi is MODE_10_BIT.

 unsigned int analog_read(unsigned char channel) 

The function performs on the specified channel a conversion from analog to digital returning the computed value.

During the conversion the program execution will be occupied - i.e. you can’t do anything else until the conversion is completed. Usually a conversion takes about 100 microseconds.

If the mode was set to 8 bits the result will vary between 0 and 255. If the mode was set to 10 bits the result will vary between 0 and 1023. 10 bit mode is set by default.

The parameter – channel – should be a number or a keyword (e.g. number 7 is the ADC7 pin and has the keyword TRIMPOT). You can find a table with all the values here: http://www.pololu.com/docs/0J18/2#channels.

 unsigned int analog_read_millivolts(unsigned char channel) 

This function is almost identical with analog_read (unsigned char channel), but instead of returning a value between 0 and 255 (8 bit mode) / 1023 (10 bit mode) it returns the result in millivolts (e.g. if the function returns 4300 that indicates a voltage of 4.3 Volts).

 unsigned int analog_read_average(unsigned char channel, unsigned int numSamples) 

The difference between this function and the analog_read(unsigned char channel) is that this function automatically performs numSamples conversions and returns the average value of the readings.

Buzzer control functions

void play(const char* sequence)

The robot can play a series of notes specified using parameter sequence.

Notes are specified by characters C, D, E, F, G, A, B. The notes are played as “quarter notes” each note having a length of 500 milliseconds ⇒ a tempo of 120 bpm. The user can specify other note durations by putting a number after the note (e.g. “D8”: note played is D and the duration is 1/8 note, which is half the duration of a quarter note). To shift the note one octave up you have to use “>” before the note. To shift it down use “<” before the note. E.g. if the sequence played is “cdefgabc” on the speaker you will hear the C major range.

void stop_playing()

This method will immediately silence the buzzer.

Functions used to control Digital Input / Output Pins

How can we identify on our AVR microcontroller a digital I/O pin? Every pin that starts with the letter P followed by another letter (A/B/C/D/E – representing the port) and a number, can be configured to be a digital pin(e.g. PD1, PC5, PA7 etc.).

Pin state can be changed during program execution, i.e. you can change the state from digital output pin to a digital input pin and then back to digital output.

Pin configuration:

  1. digital output pin:
    • A pin configured as a digital output pin has two states:
      1. LOW which is equivalent to a logic “0” and has a strong connection to GND (0 V)
      2. HIGH which is equivalent to a logic “1” and has a strong connection to VCC (5V in our case)
  2. digital input pin:
    • When the microcontroller performs a reading on the pin the result will always be either LOW or HIGH
    • In other words, if on that pin the voltage is near:
      1. 0 V the microcontroller will consider the state of that pin LOW
      2. 5V the microcontroller will consider the state of that pin HIGH

Using a digital output pin we are able to send data to other devices or supply a small amount of power (e.g. we can light up an LED). We use input pins to read data from peripherals or from sensors.

Every I/O pin has a built-in internal pull-up resistor which can be enabled or disabled. The pull-up resistor is a resistor which is connected between VCC and a pin. Its role is to provide a well-known state when no other component is interacting with that pin.

By default when the microcontroller powers up or resets, the I/O pins are configured as inputs with the pull-up resistors disabled.

For all the functions available below, the parameter pin is defined as: * IO_LN – where L is a letter and N a number(e.g. if we choose pin PD0 the value for the parameter should be IO_D0)

 void set_digital_output(unsigned char pin, unsigned char output_state) 

This function is used to configure the pin as a digital output pin. The first parameter – pin – represents the pin which we want to configure. The second parameter represents the output state and can be set to:

  • LOW – drives the pin low
  • HIGH – drives the pin high
  • TOGGLE – toggles between high and low
 void set_digital_input(unsigned char pin, unsigned char input_state)  

This function is used to configure a pin as a digital input pin. The first parameter – pin – represents the pin which we want to configure. The second parameter should be set to PULL_UP_ENABLED

 unsigned char is_digital_input_high(unsigned char pin) 

This function is used to read the pin’s input value and returns:

  • 0 if the pin is low
  • 1 if the pin is high

Functions used to control the LCD

The LCD is an 8×2 character display (i.e. you have two lines and eight columns on each line) and can be considered an essential tool for debugging and user interface.

 void clear(); 

This function clears the display and positions the cursor at row 0 and column 0.

 void lcd_goto_xy(int col, int row) 

This function allows cursor moving on the LCD. The first parameter – col – represents the column on the LCD. The second parameter – row – represents the row on the LCD.

For this LCD in particular the values set should be:

  1. row
    • 0 – first line of the LCD
    • 1 – second line of the LCD
  2. column
    • between 0 and 7, where 0 represents the first column and 7 the last one

E.g. If you want to move the cursor at the beginning of the second line:


If you want to see where the cursor is positioned you can use:

 void lcd_show_cursor(unsigned char cursorType) 

The parameter – cursorType – can be set to:

 void lcd_hide_cursor() 

The above function is used to hide the cursor.

Now that we know how to show / hide / move the cursor on the LCD we can continue with the printing functions.

 void print(const char *str) 

This function prints the parameter on the current cursor position. Because the LCD has only 8 columns and the function does not wrap the word you should pay attention to the word's length which should be maximum eight. If the parameter’s length is greater than eight you will be able to see on the LCD only the first eight characters.

 void print_long(long value) 

This function prints the parameter – value – on the LCD at the current cursor position.

Functions used to interact with user LEDs

On the bottom side of the PCB (Printed Circuit Board) are two user LEDs:

  • green LED on the left side
  • red LED on the right side

An additional LED can be soldered on top of the PCB in parallel with the red / green LED for easier viewing.

void red_led(unsigned char state)
void green_led(unsigned char state)

The value of the parameter – state – can be set to:

  • ON – turns the LED on (numeric value 1)
  • OFF – turns the LED off (numeric value 0)
  • TOGGLE – toggles the LED (numeric value 255)

Motor control functions

Both motors are controlled using four hardware PWM (Pulse Width Modulation) outputs. The outputs are controlled by two timers Timer0 and Timer2.

Motors can be controlled simultaneously using:

 void set_motors(int m1Speed, int m2Speed)

Or you can control them individually using:

 void set_m1_speed(int speed) /* used to control the first motor */ 
 void set_m2_speed(int speed) /* used to control the second motor */

The role of each parameter – speed / m1Speed / m2Speed – is to set the speed and direction according to the following rules:

  1. The direction of the motor depends on the parameter’s sign:
    • if the parameter is positive, the motor will rotate forwards
    • if the parameter is negative, the motor will rotate backwards
  2. The speed of the motor depends on the value of the parameter and can vary from 0 to 255 where:
    • 0 means full break
    • 255 means full speed

If the value of the parameter is greater than 255, the speed will be set to 255.

Function used to interact with buttons

On the 3pi robot we can find three buttons: A, B, C.

 unsigned char button_is_pressed(unsigned char buttons) 

The value of the parameter can be set to:


Buttons can be combined using operator | or +.

The function will return:

  • 0 if no button was pressed
  • the ID of the button

Because the function doesn’t take care of button debouncing, the user has to take some standard debouncing precautions.

What’s bouncing? Because of the mechanical effect, when you press a button several continuous ON/OFF signals are produced. That signal can become steady after a few milliseconds.

We can debounce that signal using software debouncing. That can be done by adding:

 unsigned char wait_for_button_press(unsigned char buttons)

This function waits until the button specified in the parameter is pressed. Also, the function takes care of button debouncing.

unsigned char wait_for_button_release(unsigned char buttons)

This function waits until the button specified in the parameter is released.


roboticsisfun/chapter2/ch2_9_3pi_api.txt · Last modified: 2012/11/12 02:32 by liviu.radoi