#363 v3.16 ISR docu english / deutsch

This commit is contained in:
mstroh76
2025-06-06 18:29:56 +02:00
parent 9924265347
commit 30cbdf9373
2 changed files with 271 additions and 58 deletions

View File

@@ -283,7 +283,7 @@ if (value==HIGH)
## Interrupts ## Interrupts
### wiringPiISR (klassische Version) ### wiringPiISR
Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwechsel ausgeführt wird. Registriert eine Interrupt Service Routine (ISR) bzw. Funktion die bei Flankenwechsel ausgeführt wird.
Es werden bei dieser klassischen Version keine Parameter and die ISR übergeben. Es werden bei dieser klassischen Version keine Parameter and die ISR übergeben.
@@ -304,6 +304,7 @@ int wiringPiISR(int pin, int mode, void (*function)(void));
> 0 ... Erfolgreich > 0 ... Erfolgreich
<!-- > <>0 ... Fehler, zur Zeit nicht implementiert --> <!-- > <>0 ... Fehler, zur Zeit nicht implementiert -->
Beispiel siehe [wiringPiISRStop](#wiringPiISRStop).
### wiringPiISR2 ### wiringPiISR2
@@ -317,28 +318,30 @@ int wiringPiISR2(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfi
``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer).
``edgeMode``: Auslösende Flankenmodus ``edgeMode``: Auslösender Flankenmodus
- INT_EDGE_RISING ... Steigende Flanke - INT_EDGE_RISING ... Steigende Flanke
- INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_FALLING ... Fallende Flanke
- INT_EDGE_BOTH ... Steigende und fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke
``*function``: Funktionspointer für ISR mit Parameter struct WPIWfiStatus und einem Pointer: ``*function``: Funktionspointer für ISR mit Parameter struct WPIWfiStatus und einem Pointer:
```C ```C
struct WPIWfiStatus { struct WPIWfiStatus {
int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed
unsigned int pinBCM; // gpio as BCM pin unsigned int pinBCM; // gpio as BCM pin
int edge; // INT_EDGE_FALLING or INT_EDGE_RISING int edge; // INT_EDGE_FALLING or INT_EDGE_RISING
long long int timeStamp_us; // time stamp in microseconds long long int timeStamp_us; // time stamp in microseconds
}; };
``` ```
``debounce_period_us``: Entprellzeit in Microsekunden, 0 ms schaltet das Entprellen ab ``debounce_period_us``: Entprellzeit in Microsekunden, 0 schaltet das Entprellen ab
``userdata``: Pointer der beim Aufruf der ISR übergeben wird ``userdata``: Pointer der beim Aufruf der ISR übergeben wird
``Rückgabewert``: ``Rückgabewert``:
> 0 ... Erfolgreich > 0 ... Erfolgreich
<!-- > <>0 ... Fehler, zur Zeit nicht implementiert --> <!-- > <>0 ... Fehler, zur Zeit nicht implementiert -->
Beispiel siehe [waitForInterrupt2](#waitForInterrupt2).
### wiringPiISRStop ### wiringPiISRStop
@@ -346,15 +349,40 @@ Deregistriert die Interrupt Service Routine (ISR) auf einem Pin.
>>> >>>
```C ```C
int wiringPiISRStop (int pin) int wiringPiISRStop (int pin);
``` ```
``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer). ``pin``: Der gewünschte Pin (BCM-, WiringPi- oder Pin-Nummer).
``Rückgabewert``: ``Rückgabewert``:
> 0 ... Erfolgreich > 0 ... Erfolgreich
<!-- > <>0 ... Fehler, zur Zeit nicht implementiert --> <!-- > <>0 ... Fehler, zur Zeit nicht implementiert -->
**Beispiel:**
>>>
```C
static volatile int edgeCounter;
static void isr(void) {
edgeCounter++;
}
int main (void) {
wiringPiSetupPinType(WPI_PIN_BCM);
edgeCounter = 0;
wiringPiISR(17, INT_EDGE_RISING, &isr);
Sleep(1000);
printf("%d rising edges\n", edgeCounter);
wiringPiISRStop(17);
}
```
### waitForInterrupt ### waitForInterrupt
Funktion ist nicht mehr verfügbar, es wird nur noch die ``waitForInterrupt2`` unterstützt! Funktion ist nicht mehr verfügbar, es wird nur noch die ``waitForInterrupt2`` unterstützt!
@@ -372,21 +400,21 @@ struct WPIWfiStatus wfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, u
``` ```
``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer). ``pin``: Der gewünschte Pin (BCM\-, WiringPi\- oder Pin\-Nummer).
``edgeMode``: Auslösender Flankenmodus
``edgeMode``: Auslösende Flankenmodus
- INT_EDGE_RISING ... Steigende Flanke - INT_EDGE_RISING ... Steigende Flanke
- INT_EDGE_FALLING ... Fallende Flanke - INT_EDGE_FALLING ... Fallende Flanke
- INT_EDGE_BOTH ... Steigende und fallende Flanke - INT_EDGE_BOTH ... Steigende und fallende Flanke
``mS``: Timeout in Milisekunden. ``ms``: Timeout in Milisekunden.
- \-1 warten ohne timeout - \-1 ... Warten ohne Timeout
- 0 wartet nicht - 0 ... Wartet nicht
- 1...n wartet maximal n Millisekunden - 1...n ... Wartet maximal n Millisekunden
``debounce_period_us``: Entprellzeit in Microsekunden, 0 schaltet Entprellen ab. ``debounce_period_us``: Entprellzeit in Microsekunden, 0 schaltet Entprellen ab.
``Rückgabewert``: ``Rückgabewert``:
```C ```C
struct WPIWfiStatus { struct WPIWfiStatus {
int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed
unsigned int pinBCM; // gpio as BCM pin unsigned int pinBCM; // gpio as BCM pin
@@ -395,8 +423,9 @@ struct WPIWfiStatus {
}; };
``` ```
### Beispiel **Beispiel:**
```C
```C
/* /*
* isr_debounce.c: * isr_debounce.c:
* Wait for Interrupt test program WiringPi >=3.16 - ISR2 method * Wait for Interrupt test program WiringPi >=3.16 - ISR2 method
@@ -421,21 +450,21 @@ struct WPIWfiStatus {
// OUTpin : connected to a LED with 470 Ohm resistor in series to GND. Toggles LED with every push button pressed. // OUTpin : connected to a LED with 470 Ohm resistor in series to GND. Toggles LED with every push button pressed.
//************************************* //*************************************
#define IRQpin 16 #define IRQpin 16
#define OUTpin 12 #define OUTpin 12
int toggle = 0; int toggle = 0;
static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) { static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) {
// struct timeval now; // struct timeval now;
long long int timenow, diff; long long int timenow, diff;
struct timespec curr; struct timespec curr;
char *edgeType; char *edgeType;
if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) { if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) {
printf("clock_gettime error"); printf("clock_gettime error");
return; return;
} }
timenow = curr.tv_sec * 1000000LL + curr.tv_nsec/1000L; // convert to microseconds timenow = curr.tv_sec * 1000000LL + curr.tv_nsec/1000L; // convert to microseconds
diff = timenow - wfiStatus.timeStamp_us; diff = timenow - wfiStatus.timeStamp_us;
if (wfiStatus.edge == INT_EDGE_RISING) if (wfiStatus.edge == INT_EDGE_RISING)
@@ -446,11 +475,11 @@ static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) {
edgeType = "none"; edgeType = "none";
printf("gpio BCM = %d, IRQ edge = %s, timestamp = %lld microseconds, timenow = %lld, diff = %lld\n", wfiStatus.gpioPin, edgeType, wfiStatus.timeStamp_us, timenow, diff); printf("gpio BCM = %d, IRQ edge = %s, timestamp = %lld microseconds, timenow = %lld, diff = %lld\n", wfiStatus.gpioPin, edgeType, wfiStatus.timeStamp_us, timenow, diff);
if (toggle == 0) { if (toggle == 0) {
digitalWrite (OUTpin, HIGH) ; digitalWrite (OUTpin, HIGH);
toggle = 1; toggle = 1;
} }
else { else {
digitalWrite (OUTpin, LOW) ; digitalWrite (OUTpin, LOW);
toggle = 0; toggle = 0;
} }
} }
@@ -459,55 +488,50 @@ static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) {
int main (void) int main (void)
{ {
int major, minor; int major, minor;
wiringPiVersion(&major, &minor); wiringPiVersion(&major, &minor);
printf("\nISR debounce test (WiringPi %d.%d)\n\n", major, minor); printf("\nISR debounce test (WiringPi %d.%d)\n\n", major, minor);
wiringPiSetupGpio() ;
wiringPiSetupGpio();
pinMode(IRQpin, INPUT); pinMode(IRQpin, INPUT);
// pull up/down mode (PUD_OFF, PUD_UP, PUD_DOWN) => down // pull up/down mode (PUD_OFF, PUD_UP, PUD_DOWN) => down
pullUpDnControl(IRQpin, PUD_UP); pullUpDnControl(IRQpin, PUD_UP);
pinMode(OUTpin, OUTPUT); pinMode(OUTpin, OUTPUT);
digitalWrite (OUTpin, LOW) ; digitalWrite (OUTpin, LOW) ;
printf("Testing waitForInterrupt on both edges IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT); printf("Testing waitForInterrupt on both edges IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT);
struct WPIWfiStatus wfiStatus = waitForInterrupt2(IRQpin, INT_EDGE_BOTH, TIMEOUT, BOUNCETIME_WFI); struct WPIWfiStatus wfiStatus = waitForInterrupt2(IRQpin, INT_EDGE_BOTH, TIMEOUT, BOUNCETIME_WFI);
if (wfiStatus.status < 0) { if (wfiStatus.status < 0) {
printf("waitForInterrupt returned error\n"); printf("waitForInterrupt returned error\n");
pinMode(OUTpin, INPUT); pinMode(OUTpin, INPUT);
return 0; return 0;
} }
else if (wfiStatus.status == 0) { else if (wfiStatus.status == 0) {
printf("waitForInterrupt timed out\n\n"); printf("waitForInterrupt timed out\n\n");
} }
else { else {
if (wfiStatus.edge == INT_EDGE_FALLING) if (wfiStatus.edge == INT_EDGE_FALLING)
printf("waitForInterrupt: GPIO pin %d falling edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); printf("waitForInterrupt: GPIO pin %d falling edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us);
else else
printf("waitForInterrupt: GPIO pin %d rising edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us); printf("waitForInterrupt: GPIO pin %d rising edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us);
} }
printf("Testing IRQ @ GPIO%d on both edges and bouncetime %d microseconds. Toggle LED @ GPIO%d on IRQ.\n\n", IRQpin, BOUNCETIME, OUTpin); printf("Testing IRQ @ GPIO%d on both edges and bouncetime %d microseconds. Toggle LED @ GPIO%d on IRQ.\n\n", IRQpin, BOUNCETIME, OUTpin);
printf("To stop program hit return key\n\n"); printf("To stop program hit return key\n\n");
wiringPiISR2(IRQpin, INT_EDGE_BOTH, &wfi, BOUNCETIME, NULL) ; wiringPiISR2(IRQpin, INT_EDGE_BOTH, &wfi, BOUNCETIME, NULL);
getc(stdin); getc(stdin);
wiringPiISRStop (IRQpin) ; wiringPiISRStop (IRQpin);
pinMode(OUTpin, INPUT); pinMode(OUTpin, INPUT);
return 0 ; return 0;
} }
``` ```
Augabe am Terminal: Ausgabe am Terminal:
``` ```
pi@RaspberryPi:~/wiringpi-test-v3.16 $ gcc -o isr_debounce isr_debounce.c -l wiringPi pi@RaspberryPi:~/wiringpi-test-v3.16 $ gcc -o isr_debounce isr_debounce.c -l wiringPi
pi@RaspberryPi:~/wiringpi-test-v3.16 $ ./isr_debounce pi@RaspberryPi:~/wiringpi-test-v3.16 $ ./isr_debounce
@@ -533,7 +557,7 @@ gpio BCM = 16, IRQ edge = falling, timestamp = 256543320012 microseconds, timeno
gpio BCM = 16, IRQ edge = rising, timestamp = 256544092021 microseconds, timenow = 256544092029, diff = 8 gpio BCM = 16, IRQ edge = rising, timestamp = 256544092021 microseconds, timenow = 256544092029, diff = 8
^C ^C
pi@RaspberryPi:~/wiringpi-test-v3.16 $ pi@RaspberryPi:~/wiringpi-test-v3.16 $
``` ```
## Hardware PWM (Pulsweitenmodulation) ## Hardware PWM (Pulsweitenmodulation)

View File

@@ -120,11 +120,10 @@ Outdated functions (no longer use):
**Since Version 3.4:** **Since Version 3.4:**
``wiringPiSetupPinType`` decides whether WiringPi, BCM or physical PIN numbering is now used, based on the parameter pinType. So it combines the first 3 setup functions together. ``wiringPiSetupPinType`` decides whether WiringPi, BCM or physical pin numbering is used, based on the parameter pinType. So it combines the first 3 setup functions together.
``wiringPiSetupGpioDevice`` is the successor to the ``wiringPiSetupSys`` function and now uses "GPIO Character Device Userspace API" in version 1 (from kernel 5.10). More information can be found at [docs.kernel.org/driver-api/gpio/driver.html](https://docs.kernel.org/driver-api/gpio/driver.html) on the parameter pintype, it is again decided which pin numbering is used. ``wiringPiSetupGpioDevice`` is the successor to the ``wiringPiSetupSys`` function and now uses "GPIO Character Device Userspace API" in version 2 (WiringPi version 3.16 or higher). More information can be found at [docs.kernel.org/driver-api/gpio/driver.html](https://docs.kernel.org/driver-api/gpio/driver.html) on the parameter pintype, it is again decided which pin numbering is used.
In this variant, there is no direct access to the GPIO memory (DMA) but rather through a kernel interface that is available with user permissions. The disadvantage is the limited functionality and low performance. In this variant, there is no direct access to the GPIO memory (DMA) but rather through a kernel interface that is available with user permissions. The disadvantage is the limited functionality and low performance.
<!-- Attention code that uses the nine functions is no longer compatible with the older library version 2! -->
### wiringPiSetup V2 (outdated) ### wiringPiSetup V2 (outdated)
@@ -294,14 +293,15 @@ if (value == HIGH)
### wiringPiISR ### wiringPiISR
Registers an Interrupt Service Routine (ISR) / function that is executed on edge detection. Registers an Interrupt Service Routine (ISR) / function that is executed on edge detection.
In this classic version, no parameters are passed to the ISR.
```C ```C
int wiringPiISR(int pin, int mode, void (*function)(void)); int wiringPiISR(int pin, int mode, void (*function)(void));
``` ```
``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number). ``pin``: The desired pin (BCM-, WiringPi-, or Pin-number).
``mode``: Triggering edge mode... ``mode``: Triggering edge mode
- `INT_EDGE_RISING` ... Rising edge - `INT_EDGE_RISING` ... Rising edge
- `INT_EDGE_FALLING` ... Falling edge - `INT_EDGE_FALLING` ... Falling edge
@@ -311,14 +311,50 @@ int wiringPiISR(int pin, int mode, void (*function)(void));
``Return Value``: ``Return Value``:
> 0 ... Successful > 0 ... Successful
<!-- > <>0 ... Error not implemented at the moment. --> <!-- > <>0 ... Error not implemented at the moment. -->
For example see **[wiringPiISRStop](#wiringpiisrstop)**. For example see [wiringPiISRStop](#wiringPiISRStop).
### wiringPiISR2
Registers an Interrupt Service Routine (ISR) / function that is executed on edge detection.
Extended parameters are passed to the ISR.
>>>
```C
int wiringPiISR2(int pin, int edgeMode, void (*function)(struct WPIWfiStatus wfiStatus, void* userdata), unsigned long debounce_period_us, void* userdata);
```
``pin``: The desired pin (BCM-, WiringPi-, or Pin-number).
``edgeMode``: Triggering edge mode
- `INT_EDGE_RISING` ... Rising edge
- `INT_EDGE_FALLING` ... Falling edge
- `INT_EDGE_BOTH` ... Rising and falling edge
``*function``: Function pointer for ISR with the parameter struct WPIWfiStatus and a pointer.
```C
struct WPIWfiStatus {
int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed
unsigned int pinBCM; // gpio as BCM pin
int edge; // INT_EDGE_FALLING or INT_EDGE_RISING
long long int timeStamp_us; // time stamp in microseconds
};
```
``debounce_period_us``: Debounce time in microseconds, 0 disables debouncing.
``userdata``: Pointer that is passed when calling the ISR.
``Return Value``:
> 0 ... Successful
For example see [waitForInterrupt2](#waitForInterrupt2).
### wiringPiISRStop ### wiringPiISRStop
Deregisters the Interrupt Service Routine (ISR) on a Pin. Deregisters the Interrupt Service Routine (ISR) on a pin.
```C ```C
int wiringPiISRStop (int pin); int wiringPiISRStop (int pin);
@@ -344,7 +380,7 @@ int main (void) {
wiringPiSetupPinType(WPI_PIN_BCM); wiringPiSetupPinType(WPI_PIN_BCM);
edgeCounter = 0; edgeCounter = 0;
wiringPiISR (17, INT_EDGE_RISING, &isr); wiringPiISR(17, INT_EDGE_RISING, &isr);
Sleep(1000); Sleep(1000);
printf("%d rising edges\n", edgeCounter); printf("%d rising edges\n", edgeCounter);
@@ -355,18 +391,171 @@ int main (void) {
### waitForInterrupt ### waitForInterrupt
Waits for a previously defined interrupt ([wiringPiISR](#wiringpiisr)) on the GPIO pin. This function should not be used. The function is no longer available, only ``waitForInterrupt2``!
### waitForInterrupt2
Waits for a call to the Interrupt Service Routine (ISR) with a timeout and debounce time in microseconds. Blocks the program until the triggering edge occurs or the timeout expires.
```C ```C
int waitForInterrupt (int pin, int mS); struct WPIWfiStatus wfiStatus waitForInterrupt2(int pin, int edgeMode, int ms, unsigned long debounce_period_us)
``` ```
``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number). ``pin``: The desired Pin (BCM-, WiringPi-, or Pin-number).
``mS``: Timeout in milliseconds. ``ms``: Timeout in milliseconds.
``Return Value``: Error - \-1 ... Wait without timeout
> 0 ... Successful - 0 ... No wait
> -1 ... GPIO Device Chip not successfully opened - 1...n ... Waits for a maximum of n milliseconds
> -2 ... ISR was not registered (WiringPiISR must be called)
``debounce_period_us``: Debounce time in microseconds, 0 disables debouncing.
``Return Value``:
```C
struct WPIWfiStatus {
int statusOK; // -1: error (return of 'poll' command), 0: timeout, 1: irq processed, next data values are valid if needed
unsigned int pinBCM; // gpio as BCM pin
int edge; // INT_EDGE_FALLING or INT_EDGE_RISING
long long int timeStamp_us; // time stamp in microseconds
};
```
**Example:**
```C
/*
* isr_debounce.c:
* Wait for Interrupt test program WiringPi >=3.16 - ISR2 method
*
*
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiringPi.h>
#include <time.h>
#define BOUNCETIME 3000 // microseconds
#define BOUNCETIME_WFI 300
#define TIMEOUT 10000
//*************************************
// BCM pins
// IRQpin : setup as input with internal pullup. Connected with push button to GND with 1K resistor in series.
// OUTpin : connected to a LED with 470 Ohm resistor in series to GND. Toggles LED with every push button pressed.
//*************************************
#define IRQpin 16
#define OUTpin 12
int toggle = 0;
static void wfi(struct WPIWfiStatus wfiStatus, void* userdata) {
// struct timeval now;
long long int timenow, diff;
struct timespec curr;
char *edgeType;
if (clock_gettime(CLOCK_MONOTONIC, &curr) == -1) {
printf("clock_gettime error");
return;
}
timenow = curr.tv_sec * 1000000LL + curr.tv_nsec/1000L; // convert to microseconds
diff = timenow - wfiStatus.timeStamp_us;
if (wfiStatus.edge == INT_EDGE_RISING)
edgeType = "rising";
else if (wfiStatus.edge == INT_EDGE_FALLING)
edgeType = "falling";
else
edgeType = "none";
printf("gpio BCM = %d, IRQ edge = %s, timestamp = %lld microseconds, timenow = %lld, diff = %lld\n", wfiStatus.gpioPin, edgeType, wfiStatus.timeStamp_us, timenow, diff);
if (toggle == 0) {
digitalWrite (OUTpin, HIGH);
toggle = 1;
}
else {
digitalWrite (OUTpin, LOW);
toggle = 0;
}
}
int main (void)
{
int major, minor;
wiringPiVersion(&major, &minor);
printf("\nISR debounce test (WiringPi %d.%d)\n\n", major, minor);
wiringPiSetupGpio();
pinMode(IRQpin, INPUT);
// pull up/down mode (PUD_OFF, PUD_UP, PUD_DOWN) => down
pullUpDnControl(IRQpin, PUD_UP);
pinMode(OUTpin, OUTPUT);
digitalWrite (OUTpin, LOW) ;
printf("Testing waitForInterrupt on both edges IRQ @ GPIO%d, timeout is %d\n", IRQpin, TIMEOUT);
struct WPIWfiStatus wfiStatus = waitForInterrupt2(IRQpin, INT_EDGE_BOTH, TIMEOUT, BOUNCETIME_WFI);
if (wfiStatus.status < 0) {
printf("waitForInterrupt returned error\n");
pinMode(OUTpin, INPUT);
return 0;
}
else if (wfiStatus.status == 0) {
printf("waitForInterrupt timed out\n\n");
}
else {
if (wfiStatus.edge == INT_EDGE_FALLING)
printf("waitForInterrupt: GPIO pin %d falling edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us);
else
printf("waitForInterrupt: GPIO pin %d rising edge fired at %lld microseconds\n\n", wfiStatus.gpioPin, wfiStatus.timeStamp_us);
}
printf("Testing IRQ @ GPIO%d on both edges and bouncetime %d microseconds. Toggle LED @ GPIO%d on IRQ.\n\n", IRQpin, BOUNCETIME, OUTpin);
printf("To stop program hit return key\n\n");
wiringPiISR2(IRQpin, INT_EDGE_BOTH, &wfi, BOUNCETIME, NULL);
getc(stdin);
wiringPiISRStop (IRQpin);
pinMode(OUTpin, INPUT);
return 0;
}
```
Output on terminal:
```
pi@RaspberryPi:~/wiringpi-test-v3.16 $ gcc -o isr_debounce isr_debounce.c -l wiringPi
pi@RaspberryPi:~/wiringpi-test-v3.16 $ ./isr_debounce
ISR debounce test (WiringPi 3.16)
Testing waitForInterrupt on both edges IRQ @ GPIO16, timeout is 10000
waitForInterrupt: GPIO pin 16 falling edge fired at 256522528012 microseconds
Testing IRQ @ GPIO16 on both edges and bouncetime 3000 microseconds. Toggle LED @ GPIO12 on IRQ.
To stop program hit return key
gpio BCM = 16, IRQ edge = rising, timestamp = 256522668010 microseconds, timenow = 256522668017, diff = 7
gpio BCM = 16, IRQ edge = falling, timestamp = 256536364014 microseconds, timenow = 256536364021, diff = 7
gpio BCM = 16, IRQ edge = rising, timestamp = 256536952011 microseconds, timenow = 256536952018, diff = 7
gpio BCM = 16, IRQ edge = falling, timestamp = 256537856010 microseconds, timenow = 256537856016, diff = 6
gpio BCM = 16, IRQ edge = rising, timestamp = 256538744011 microseconds, timenow = 256538744018, diff = 7
gpio BCM = 16, IRQ edge = falling, timestamp = 256539664010 microseconds, timenow = 256539664017, diff = 7
gpio BCM = 16, IRQ edge = rising, timestamp = 256540516010 microseconds, timenow = 256540516016, diff = 6
gpio BCM = 16, IRQ edge = falling, timestamp = 256541560013 microseconds, timenow = 256541560022, diff = 9
gpio BCM = 16, IRQ edge = rising, timestamp = 256542360010 microseconds, timenow = 256542360016, diff = 6
gpio BCM = 16, IRQ edge = falling, timestamp = 256543320012 microseconds, timenow = 256543320020, diff = 8
gpio BCM = 16, IRQ edge = rising, timestamp = 256544092021 microseconds, timenow = 256544092029, diff = 8
^C
pi@RaspberryPi:~/wiringpi-test-v3.16 $
```
## Hardware Pulse Width Modulation (PWM) ## Hardware Pulse Width Modulation (PWM)