I am doing a little reading around before beginning a project and looking to use Prolog for a control system.
Does SWI-Prolog give you access to the GPIO pins on a Raspberry Pi? Is it possible to initiate Prolog searches by a GPIO input and produce a signal on a pin as the result of a rule?
I don’t think you can access the pin directly from Prolog but if there exists a c based library to access the pins, then the FFI package could possibly be used.
Perhaps its possible to use a setup that is combined with Python. Python accessess the pins and forwards the values to Prolog --with Prolog embedded or called from Python.
A quick Google search leads me to How to Control GPIO Hardware from C or C++ | ICS, which tells me that the GPIO pins are simply controlled through the filesystem. Translating the code there gives something like below. Not tested (I have a Pi, but nothing
to connect to the GPIO pins directly ready ).
I tried to see if reading from the file system would then be reading input – and i guess the approach is polling driven … to identify a change in input.
A more complete overview of the fs API is at GPIO Programming: Using the sysfs Interface | ICS. Seems you can read '/sys/class/gpio/gpioNN/value' and get a 0 or a 1. That seems to be a polling interface I don’t see what you need to poll again, i.e., do you have to go through the open/close or maybe you can use seek/4 to go back to the start and try again. One needs better docs or a Pi to tell
Easy enough to build a nice library and submit as a pack. Someone?
The new kernel inteface is through a character device that can be easily accessible using libgpiod. It is easy enough to use by calling the executables included with libgpiod or it can be called directly from C with ffi.
One of the nice executables provided by libgpiod (besides gpioget and gpioset) is called gpiomon. It allows monitoring rising edges, falling edges and even setup pull down or pull up biases, printing to stdout as events happen:
NAME
lt-gpiomon - manual page for lt-gpiomon v1.6.3
SYNOPSIS
lt-gpiomon [OPTIONS] <chip name/number> <offset 1> <offset 2> ...
DESCRIPTION
Wait for events on GPIO lines and print them to standard output
OPTIONS
-h, --help:
display this message and exit
-v, --version:
display the version and exit
-l, --active-low:
set the line active state to low
-B, --bias=[as-is|disable|pull-down|pull-up] (defaults to 'as-is'):
set the line bias
-n, --num-events=NUM: exit after processing NUM events
-s, --silent:
don't print event info
-r, --rising-edge:
only process rising edge events
-f, --falling-edge:
only process falling edge events
-b, --line-buffered:
set standard output as line buffered
-F, --format=FMT
specify custom output format
Biases:
as-is: leave bias unchanged
disable:
disable bias
pull-up:
enable pull-up
pull-down:
enable pull-down
[...]
Here is an article showing why libgpiod is much better than sysfs.
It has a simple example to call the statfs libc function:
:- use_module(library(ffi)).
:- use_module(library(cerror)).
:- c_import("#include <sys/vfs.h>", % include file where C functions are found
[ libc ], % dynamic library(ies) to load
[ statfs(string, -struct(statfs), [int]) % function(s) to import, and description
% of parameters and return value
]).
statfs(File, FsStat) :- % regular prolog predicate
statfs(File, FsStat, Status), % now we call the C function
posix_status(Status, statfs, file, File). % covert posix errors to prolog exception
Possibly simply opening, reading and writing to this character device is easier than using libgpio? Sometimes it is … The advantage of using a library is than mostly that if the kernel interface changes again, the library is probably changed to deal with that. Usually, kernel interfaces are pretty stable though.
The advantage of using libgpiod, instead of the character device directly, is that libgpiod provides for managing for simultaneous access to the gpio from several processes/threads. As it says in the linux docs:
For structured and managed applications, we recommend that you make use of the libgpiod library. This provides helper abstractions, command line utlities and arbitration for multiple simultaneous consumers on the same GPIO chip.
Fixed. Also updated version and pushed a new version with the issue solved for Nicos using this package on the Raspberry pi using Ubuntu 21.04 (variation in ldconfig output and deal with systems where char is by default unsigned). The library now provides a primitive type schar next to uchar and char, where schar is explicitly signed and char does what the compiler does by default.