Skip to content

Instantly share code, notes, and snippets.

@keriszafir
Last active November 8, 2023 10:40
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keriszafir/37d598d6501214da58e0 to your computer and use it in GitHub Desktop.
Save keriszafir/37d598d6501214da58e0 to your computer and use it in GitHub Desktop.
gpio-interrupt - C routine for handling interrupts generated on GPIO
/* Demonstration C GPIO interrupt handling routine for Raspberry Pi
This is a modified code found at https://github.com/phil-lavin/raspberry-pi-gpio-interrupt
The program displays a notice whenever you:
-turn on the Raspberry Pi's pin 11 (apply 3.3V),
-turn the pin off.
This routine uses wiringPi library (follow the installation instructions at wiringpi.com),
and should be compiled with a command:
gcc source_filename -o executable_filename -lwiringPi
You must have root privileges to run it - I don't know any workaround yet:
sudo ./executable_filename
Then the program displays a notice whenever you turn the GPIO pin 11 on and off.
It runs as an infinite loop and you can cancel it by pressing ctrl-C.
*/
#include <stdio.h>
#include <sys/time.h>
#include <wiringPi.h>
// Which GPIO pin we're using. For this program we'll use physical pin numbers.
#define PIN 11
// How much time a change must be since the last in order to count as a change
// (in microseconds); allows to avoid generating interrupts on contact bouncing etc.
#define IGNORE_CHANGE_BELOW_USEC 10000
// Current state of the pin
static volatile int state;
// Time of last change
struct timeval last_change;
// Handler for interrupt
void handle(void) {
struct timeval now;
unsigned long diff;
gettimeofday(&now, NULL);
// Time difference in microseconds
diff = (now.tv_sec * 1000000 + now.tv_usec) - (last_change.tv_sec * 1000000 + last_change.tv_usec);
// Filter any changes in intervals shorter than diff (like contact bouncing etc.):
if (diff > IGNORE_CHANGE_BELOW_USEC) {
// Check whether the last state was on or off:
if (state) {
// Print info to console:
printf("Input goes off\n");
// You can add some code to do when input goes off here...
}
else {
// Print info to console:
printf("Input goes on\n");
// Add code to do when input goes on here...
}
// Change the "state" variable value:
state = !state;
}
// Store the time for last state change:
last_change = now;
}
int main(void) {
// Init -- use the physical pin number on RPi P1 connector
wiringPiSetupPhys();
// Set pin to input in case it's not
pinMode(PIN, INPUT);
// Time now
gettimeofday(&last_change, NULL);
// Bind to interrupt
wiringPiISR(PIN, INT_EDGE_BOTH, &handle);
// Get initial state of pin
state = digitalRead(PIN);
// Feedback for user that the program has started, depending on input state:
if (state) {
printf("Started! Initial state is on\n");
}
else {
printf("Started! Initial state is off\n");
}
// Waste time but not CPU
for (;;) {
sleep(1);
}
}
@maniac-on-moon
Copy link

Sorry maybe I got it wrong, but why do I have to set OUTPUT @ line 76? I would have expected "INPUT". OK, it works, but I do not understand.

@keriszafir
Copy link
Author

Sorry maybe I got it wrong, but why do I have to set OUTPUT @ line 76? I would have expected "INPUT". OK, it works, but I do not understand.

Must have been just a brain fart on my part... Thanks for noticing :)

@maniac-on-moon
Copy link

};-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment