diff --git a/examples/Makefile b/examples/Makefile
index 679b707..b7847e8 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -40,7 +40,7 @@ LDLIBS = -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt
SRC = \
blink12.c blink12drcs.c blink6drcs.c blink8.c blink8-drcn.c blink.c blink-thread.c \
- buttons.c buttons2.c buttons3.c \
+ buttons.c buttons2.c buttons3.c buttons4.c \
clock.c \
delayTest.c \
ds1302.c \
diff --git a/examples/buttons4.c b/examples/buttons4.c
new file mode 100644
index 0000000..cf20c98
--- /dev/null
+++ b/examples/buttons4.c
@@ -0,0 +1,197 @@
+/*
+ * buttons4.c:
+ * Multiple button handling with debounce.
+ *
+ ***********************************************************************
+ * This file is part of wiringPi:
+ * https://github.com/nuncio-bitis/WiringPi
+ *
+ * wiringPi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ *by the Free Software Foundation, either version 3 of the License, or (at your
+ *option) any later version.
+ *
+ * wiringPi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with wiringPi. If not, see .
+ ***********************************************************************
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+//**********************************************************************************************************************
+
+// Define the GPIOs (BCM) that buttons are attached to.
+// Button1, Button2, ... , ButtonN-1
+static const int buttonGpios[] = { 26, 16, 20, 21 };
+
+// Button flags: 1 = button was pressed.
+// @NOTE The size of this array must match the number of GPIOs specified in buttonGpios above
+static int buttons[4];
+
+static const int nButtons = (sizeof (buttonGpios) / sizeof (int));
+
+// Debounce time in mS
+#define DEBOUNCE_TIME 50
+
+static int terminate_process = 0;
+
+//**********************************************************************************************************************
+
+static void Signal_handler(int sig);
+
+//**********************************************************************************************************************
+
+/* debounce
+ * Thread to monitor button GPIOs and debounce them.
+ */
+static void *debounce (UNUSED void *arg)
+{
+ int masks[nButtons];
+ int button_times[nButtons];
+
+ // Set the GPIOs as inputs
+ // Also set up the gpio bank masks for each button
+ for (int i = 0; i < nButtons; ++i)
+ {
+ pinMode (buttonGpios[i], INPUT);
+ pullUpDnControl (buttonGpios[i], PUD_UP);
+
+ // Set up GPIO masks for the GPIO bank
+ masks[i] = (1 << buttonGpios[i]);
+
+ // Clear button flags and counters
+ buttons[i] = 0;
+ button_times[i] = 0;
+ }
+
+ // --------------------------------
+ // GPIO monitor & debounce loop
+ uint32_t bank0 = 0;
+ uint32_t prev_button_states[nButtons];
+
+ while (!terminate_process)
+ {
+ usleep(5 * 1000);
+
+ bank0 = digitalReadBank(0);
+
+ for (int i=0; i < nButtons; ++i)
+ {
+ int buttonState = (bank0 & masks[i]);
+
+ // If button changed state, reset its timer.
+ if (buttonState != prev_button_states[i])
+ {
+ button_times[i] = millis();
+ }
+
+ if ((millis() - button_times[i]) >= DEBOUNCE_TIME)
+ {
+ // Pressed button = LOW = 0
+ // Set the state to 1 if pressed, 0 if released.
+ buttons[i] = !buttonState;
+ }
+
+ prev_button_states[i] = buttonState;
+ }
+ } // end while
+
+ // --------------------------------
+
+ printf("Debounce done.\n");
+
+ return (void *)NULL;
+}
+
+//**********************************************************************************************************************
+
+static void Button_Wait (int pin)
+{
+ printf(" %-2d %-2d %-2d %-2d\n", buttons[0], buttons[1], buttons[2], buttons[3]);
+}
+
+//**********************************************************************************************************************
+
+int main (int argc, char *argv[])
+{
+ // Set the handler for SIGTERM (15)
+ signal(SIGTERM, Signal_handler);
+ signal(SIGHUP, Signal_handler);
+ signal(SIGINT, Signal_handler);
+ signal(SIGQUIT, Signal_handler);
+ signal(SIGTRAP, Signal_handler);
+ signal(SIGABRT, Signal_handler);
+ signal(SIGALRM, Signal_handler);
+ signal(SIGUSR1, Signal_handler);
+ signal(SIGUSR2, Signal_handler);
+
+ printf ("Raspberry Pi Button Test\n");
+
+ // ----------------------------------------------------
+
+ // Set up for BCM pin numbering
+ wiringPiSetupGpio ();
+
+ // ----------------------------------------------------
+ // Set up the button debounce thread
+
+ pthread_t debounceThreadId;
+ pthread_create (&debounceThreadId, NULL, debounce, NULL) ;
+
+ // ----------------------------------------------------
+
+ // Set up a callback for when any of these buttons is pressed/released
+ // The ISR will display the state of all buttons.
+ if (wiringPiISRmulti ((int *)buttonGpios, nButtons, INT_EDGE_RISING, &Button_Wait) < 0)
+ {
+ fprintf (stderr, "%s: Unable to setup ISR: %s\n", argv[0], strerror(errno));
+ return EXIT_FAILURE;
+ }
+
+ // ----------------------------------------------------
+
+ printf("Buttons:\n");
+ printf(" 1 2 3 4\n");
+ printf("--- --- --- ---\n");
+ while (!terminate_process)
+ {
+ delayMs(100);
+ }
+
+ // ----------------------------------------------------
+
+ pthread_join(debounceThreadId, NULL);
+
+ printf("%s done.\n", argv[0]);
+
+ return EXIT_SUCCESS;
+}
+
+//**********************************************************************************************************************
+
+/**
+ * Intercepts and handles signals from QNX
+ * This function is called when the SIGTERM signal is raised by QNX
+ */
+static void Signal_handler(int sig)
+{
+ printf("Received signal %d\n", sig);
+
+ // Signal process to exit.
+ terminate_process = 1;
+}
+
+//**********************************************************************************************************************
diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h
index 7eff836..2d4f382 100644
--- a/wiringPi/wiringPi.h
+++ b/wiringPi/wiringPi.h
@@ -278,6 +278,7 @@ extern void digitalWriteByte2 (int value);
// Set up for a callback to be called when the specified pin changes according to mode.
// mode = INT_EDGE_SETUP, INT_EDGE_FALLING, INT_EDGE_RISING, INT_EDGE_BOTH
// Uses SYS mode, and also waitForInterrupt
+// @NOTE: This leaves gpios exported in /sys/class/gpio when the program ends.
extern int wiringPiISR (int pin, int mode, void (*function)(int));
// Same as wiringPiISR above, but takes a list of pins to wait for.
@@ -287,6 +288,7 @@ extern int wiringPiISRmulti (int pins[], int n_pins, int mode, void (*functi
// Internal-only (unless you know how to set up /sys/class/gpio)
// Wait for "interrupt" on a GPIO pin.
// Must be in SYS mode (wiringPiSetupSys was called for setup)
+// @NOTE: This leaves gpios exported in /sys/class/gpio when the program ends.
extern int waitForInterrupt (int pin, int mS);
// ----------------------------------------------------------------------------