Last active
January 22, 2025 16:09
-
-
Save keriszafir/37d598d6501214da58e0 to your computer and use it in GitHub Desktop.
gpio-interrupt - C routine for handling interrupts generated on GPIO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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); | |
} | |
} |
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 :)
};-)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.