Skip to content

Instantly share code, notes, and snippets.

@zouppen
Last active April 10, 2022 22:32
Show Gist options
  • Save zouppen/7e8e77f7787f691d97997bfd108594d9 to your computer and use it in GitHub Desktop.
Save zouppen/7e8e77f7787f691d97997bfd108594d9 to your computer and use it in GitHub Desktop.
GPIO state change tool for scripting.

GPIO interrupt polling

This useful little tool checks for changes in GPIO state without periodic polling by using the interrupt interface provided by Linux. It's useful in scripts to wait for a state change with Raspberry Pi, but works with any hardware with GPIOs.

Public domain.

To make this work, you need to export the pin and then enable interrupts. For example:

echo 24 >/sys/class/gpio/export
echo both >/sys/class/gpio/gpio24/edge

Then just run gpio_wait 24 0 to wait for the state to turn to LOW state (or 1 for HIGH).

Compiling

gcc -Wall -O2 -o gpio_wait gpio_wait.c
#define _GNU_SOURCE
#include <stdio.h>
#include <poll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdlib.h>
#include <err.h>
#include <unistd.h>
int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "Usage: %s GPIO value\n", argv[0]);
return 1;
}
struct pollfd pf;
char target = *argv[2];
{
char *filename = NULL;
asprintf(&filename, "/sys/class/gpio/gpio%s/value", argv[1]);
int fd = open(filename, O_RDONLY);
if (fd == -1) err(1, "Unable to open %s", filename);
printf("Polling %s for value %c\n", filename, target);
free(filename);
// Populate struct
pf.fd = fd;
pf.events = POLLPRI;
}
while (true) {
int ret = poll(&pf, 1, -1);
if (ret < 1) err(2, "Unable to poll");
// Wait once after interrupts occur, for debouncing
if (usleep(10000) == -1) err(2, "Unable to sleep");
if (!(pf.revents & POLLPRI)) continue;
// Seeking to start and getting the current value
if (lseek(pf.fd, 0, SEEK_SET) == -1) err(3, "Unable to seek");
char state;
if (read(pf.fd, &state, 1) == -1) err(3, "Unable to read");
// Ending processing if we get end condition
if (state == target) {
printf("Reached state %c\n", state);
return 0;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment