DIO
Introduction
This tutorial will present how to control digital input/output pins (generally called GPIO or General-Purpose Input/Output) using the 'dio' library.
The DIO library allows controlling the GPIO pins on the ioNode. This library can also be used with most AVR microcontrollers - check DIO pin matching when not using an ioNode.
What can you do with this?
GPIO pins can be used in two ways:
- output - this allows 'controlling' the value of a GPIO from your code, setting it to logical 0 (0V) or 1 (3.3V).
- input - this allows 'reading' the value that is being applied to a GPIO pin.
We will explore both uses in detail below.
How to use
First, we need to add the 'dio' library to our dependencies in dfe.conf:
name: example_app type: app mmcu: atmega1284p freq: 10000000 deps: - dio
Direction (in / out)
Let's have a quick look at how to configure the direction (input or output) of these pins.
Pins are configured as inputs or outputs with the 'dio_input' and 'dio_output' functions:
#include <dio/dio.h> void main() { // Set pin 3 as input dio_input(3); // Set pin 5 as output dio_output(5); // ... }
Internal pull-ups
When a pin is configured as input, we can choose to enable something called an 'internal pull-up resistor'.
A pull-up is a resistor that is placed between a digital signal and 'VCC' (the '+' of the power supply). Doing this will ensure that the signal "defaults" to a stable logical '1' when the signal is not asserted by anything (signal is in high-Z state).
This has many uses, for example when connecting a push button (tactile switch) to an input pin. The button, when pressed, will assert '0' on the input by connecting it to the ground (the '-' of the power supply). When the button is not pressed, nothing is "setting" the input - reading the pin's value will give random results. To solve this we can enable the internal pull-up resistor on this input pin to make sure it's always either '0' (when button is pressed) or '1' (when not pressed).
To enable the internal pull-up on a pin that has been configured as input, we actually write to it as if it were an output pin:
#include <dio/dio.h> void main() { // Set pin 3 as input dio_input(3); // Enable internal pull-up on pin 3 dio_hi(3); // ... // Disable internal pull-up on pin 3 dio_lo(3); // ... }
Output
Once a pin is configured as output, we can set its value:
#include <dio/dio.h> void main() { // Set pin 5 as output dio_output(5); // Set pin 5 to '1' dio_hi(5); // ... // Set pin 5 to '0' dio_lo(5); // ... }
Input
When a pin is configured as input, we can read its value as follows:
#include <dio/dio.h> void main() { // Set pin 3 as input dio_input(3); // Enable internal pull-up on pin 3 dio_hi(3); // Read pin value if(dio_rd(3)) { /* pin is HIGH (1) */ } else { /* pin is LOW (0) */ } // ... }