4. Orangutan Digital I/O

This section of the library provides commands for using the AVR’s pins as generic digital inputs and outputs. The code is all inline, which lets it compile to very small, fast, efficient assembly code if you use constants as your arguments. For example, the line:

set_digital_output(IO_D3, HIGH);  // set pin PD3 as driving high output
//in C++: OrangutanDigital::setOutput(IO_D3, HIGH);

compiles to the assembly:

sbi 0x0b, 3  ;i.e. PORTD |= 1 << 3; (PD3 high)
sbi 0x0a, 3  ;i.e. DDRD  |= 1 << 3; (PD3 set as output)

If your function arguments are constants, you can use this library in place of raw digital I/O register manipulation without worrying about any significantly increased overhead or processing time. Using variables as function arguments can increase overhead and processing time, but the functions in this library allow for simpler programmatic approaches to working with digital I/O, since you no longer have to deal with a multitude of pin-specific registers.

The digital pins on the AVR default to high-impedance inputs after a power-up or reset.

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 3.c of the Pololu AVR C/C++ Library User’s Guide.

The pin argument

All of the functions in this section of the library take a pin number as their first argument. On the ATmegaxx8-based Orangutans (LV, SV, and Baby) and 3pi robot, these pin numbers are consistent with the Arduino pin numbering system. However, the library defines keywords that you can use instead of remembering the numbers. The keywords have the form IO_LN where L is the port letter and N is the pin number. For example, the keyword IO_D1 refers to pin PD1.

This library also defines:

#define INPUT            0
#define OUTPUT           1
#define LOW              0
#define HIGH             1
#define TOGGLE           0xFF
#define HIGH_IMPEDANCE   0
#define PULL_UP_ENABLED  1


C++ and Arduino methods are shown in red.

C functions are shown in green.

static void OrangutanDigital::setOutput(unsigned char pin, unsigned char outputState);

void set_digital_output(unsigned char pin, unsigned char output_state);

Sets the specified pin as an output. The pin argument should be one of the IO_* keywords (e.g. IO_D1 for pin PD1). The output_state argument should either be LOW (to drive the line low), HIGH (to drive the line high), or TOGGLE (to toggle between high and low).

static void OrangutanDigital::setInput(unsigned char pin, unsigned char inputState);

void set_digital_input(unsigned char pin, unsigned char input_state);

Sets the specified pin as an input. The pin argument should be one of the IO_* keywords (e.g. IO_D1 for pin PD1). The input_state argument should either be HIGH_IMPEDANCE (to disable the pull-up resistor) or PULL_UP_ENABLED (to enable the pull-up resistor).

static unsigned char OrangutanDigital::isInputHigh(unsigned char pin);

unsigned char is_digital_input_high(unsigned char pin);

Reads the input value of the specified pin. The pin argument should be one of the IO_* keywords (e.g. IO_D1 for pin PD1). If the reading is low (0 V), this method will return 0. If the reading is high (5 V), it will return a non-zero number that depends on the pin number. This function returns the value of the pin regardless of whether it is configured as an input or an output. If you want the pin to be an input, you must first call set_digital_input() to make the pin an input.