An Erlang application for interfacing with GPIOs on Linux systems.
This GPIO application allows for reading and writing to GPIO pins as well as monitoring input GPIO pins.
You need to add gpio
as a dependency to your project. If you are using
rebar3
, you can add the following to your rebar.config
:
{deps, [
{gpio, "0.6.3"}
]}.
Also ensure that gpio
is added as a dependency to your application, by
updating your .app.src
file:
{application, my_app, [
{applications, [
kernel,
stdlib,
gpio % <- You need this in your applications list
]}
]}.
The following will open gpiochip2 (typically called GPIO3):
> {ok, Chip} = gpio:open_chip("/dev/gpiochip2").
{ok, #Ref<0.3061467712.2848194561.68326>}
Once the chip is open you need to either use gpio:open_lines/5
if you want
to read/write values to/from the lines, or gpio:open_line_events/5
if you want
to monitor a line.
The following will open a single line IO1
from the previously open
chip (typically this would be GPIO3_IO1
). The opened line is configured as an
output with a default value of 0
. The last parameter is used to communicate
to the kernel a description of the chip use. If debugfs
is enabled, this
information is visible in /sys/kernel/debug/gpio
.
> {ok, SingleLine} = gpio:open_lines(Chip, [1], [output], [0], "my-application").
{ok, #Ref<0.3061467712.2848194561.68334>}
To write a 0
to the GPIO line, you can use:
ok = gpio:write_lines(SingleLine, {0}).
Alternatively, to write a 1
to the GPIO line, you can use:
ok = gpio:write_lines(SingleLine, {1}).
The gpio:write_lines/2
function takes a tuple of 0
and 1
values. The arity
of this tuple must be equal to the width of the lines. Previously, we opened a
single line, which is why we use a single element tuple. If instead, we opened
2 lines, we would need to provide a 2 element tuple like below:
> {ok, MultiLines} = gpio:open_lines(Chip, [1, 2, 5], [output], [0, 0, 0], "my-application").
{ok, #Ref<0.3061467712.2848194561.68339>}
> ok = gpio:write_lines(MultiLines, {1, 1, 1}). % Set all pins to 1
ok
> ok = gpio:write_lines(MultiLines, {1, 0, 1}). % Set IO1 and IO5 to 1, IO2 is set to 0
ok
The following will monitor the pin IO10
(GPIO3_I10
) for rising values
(changes from 0 to 1).
> {ok, LineEvents} = gpio:open_line_events(Chip, 10, [], [rising_edge], "my-application").
{ok, {#Ref<0.3061467712.2848194561.68344>, <0.340.0>}}
The monitoring process will then receive messages like the following:
{gpio, LineEvents, {event, Timestamp, Type}}
Where Timestamp
is a system timestamp in nanosecond, and Type
is either
rising_edge
or falling_edge
.
In case of an error, the process might receive a message like the following:
{gpio, LineEvents, {error, Error}}