25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

198 lines
5.8 KiB

  1. /*
  2. * buttons4.c:
  3. * Multiple button handling with debounce.
  4. *
  5. ***********************************************************************
  6. * This file is part of wiringPi:
  7. * https://github.com/nuncio-bitis/WiringPi
  8. *
  9. * wiringPi is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Lesser General Public License as published
  11. *by the Free Software Foundation, either version 3 of the License, or (at your
  12. *option) any later version.
  13. *
  14. * wiringPi is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
  21. ***********************************************************************
  22. */
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <signal.h>
  27. #include <unistd.h>
  28. #include <errno.h>
  29. #include <pthread.h>
  30. #include <wiringPi.h>
  31. //**********************************************************************************************************************
  32. // Define the GPIOs (BCM) that buttons are attached to.
  33. // Button1, Button2, ... , ButtonN-1
  34. static const int buttonGpios[] = { 26, 16, 20, 21 };
  35. // Button flags: 1 = button was pressed.
  36. // @NOTE The size of this array must match the number of GPIOs specified in buttonGpios above
  37. static int buttons[4];
  38. static const int nButtons = (sizeof (buttonGpios) / sizeof (int));
  39. // Debounce time in mS
  40. #define DEBOUNCE_TIME 50
  41. static int terminate_process = 0;
  42. //**********************************************************************************************************************
  43. static void Signal_handler(int sig);
  44. //**********************************************************************************************************************
  45. /* debounce
  46. * Thread to monitor button GPIOs and debounce them.
  47. */
  48. static void *debounce (UNUSED void *arg)
  49. {
  50. int masks[nButtons];
  51. int button_times[nButtons];
  52. // Set the GPIOs as inputs
  53. // Also set up the gpio bank masks for each button
  54. for (int i = 0; i < nButtons; ++i)
  55. {
  56. pinMode (buttonGpios[i], INPUT);
  57. pullUpDnControl (buttonGpios[i], PUD_UP);
  58. // Set up GPIO masks for the GPIO bank
  59. masks[i] = (1 << buttonGpios[i]);
  60. // Clear button flags and counters
  61. buttons[i] = 0;
  62. button_times[i] = 0;
  63. }
  64. // --------------------------------
  65. // GPIO monitor & debounce loop
  66. uint32_t bank0 = 0;
  67. uint32_t prev_button_states[nButtons];
  68. while (!terminate_process)
  69. {
  70. usleep(5 * 1000);
  71. bank0 = digitalReadBank(0);
  72. for (int i=0; i < nButtons; ++i)
  73. {
  74. int buttonState = (bank0 & masks[i]);
  75. // If button changed state, reset its timer.
  76. if (buttonState != prev_button_states[i])
  77. {
  78. button_times[i] = millis();
  79. }
  80. if ((millis() - button_times[i]) >= DEBOUNCE_TIME)
  81. {
  82. // Pressed button = LOW = 0
  83. // Set the state to 1 if pressed, 0 if released.
  84. buttons[i] = !buttonState;
  85. }
  86. prev_button_states[i] = buttonState;
  87. }
  88. } // end while
  89. // --------------------------------
  90. printf("Debounce done.\n");
  91. return (void *)NULL;
  92. }
  93. //**********************************************************************************************************************
  94. static void Button_Wait (int pin)
  95. {
  96. printf(" %-2d %-2d %-2d %-2d\n", buttons[0], buttons[1], buttons[2], buttons[3]);
  97. }
  98. //**********************************************************************************************************************
  99. int main (int argc, char *argv[])
  100. {
  101. // Set the handler for SIGTERM (15)
  102. signal(SIGTERM, Signal_handler);
  103. signal(SIGHUP, Signal_handler);
  104. signal(SIGINT, Signal_handler);
  105. signal(SIGQUIT, Signal_handler);
  106. signal(SIGTRAP, Signal_handler);
  107. signal(SIGABRT, Signal_handler);
  108. signal(SIGALRM, Signal_handler);
  109. signal(SIGUSR1, Signal_handler);
  110. signal(SIGUSR2, Signal_handler);
  111. printf ("Raspberry Pi Button Test\n");
  112. // ----------------------------------------------------
  113. // Set up for BCM pin numbering
  114. wiringPiSetupGpio ();
  115. // ----------------------------------------------------
  116. // Set up the button debounce thread
  117. pthread_t debounceThreadId;
  118. pthread_create (&debounceThreadId, NULL, debounce, NULL) ;
  119. // ----------------------------------------------------
  120. // Set up a callback for when any of these buttons is pressed/released
  121. // The ISR will display the state of all buttons.
  122. if (wiringPiISRmulti ((int *)buttonGpios, nButtons, INT_EDGE_RISING, &Button_Wait) < 0)
  123. {
  124. fprintf (stderr, "%s: Unable to setup ISR: %s\n", argv[0], strerror(errno));
  125. return EXIT_FAILURE;
  126. }
  127. // ----------------------------------------------------
  128. printf("Buttons:\n");
  129. printf(" 1 2 3 4\n");
  130. printf("--- --- --- ---\n");
  131. while (!terminate_process)
  132. {
  133. delayMs(100);
  134. }
  135. // ----------------------------------------------------
  136. pthread_join(debounceThreadId, NULL);
  137. printf("%s done.\n", argv[0]);
  138. return EXIT_SUCCESS;
  139. }
  140. //**********************************************************************************************************************
  141. /**
  142. * Intercepts and handles signals from QNX
  143. * This function is called when the SIGTERM signal is raised by QNX
  144. */
  145. static void Signal_handler(int sig)
  146. {
  147. printf("Received signal %d\n", sig);
  148. // Signal process to exit.
  149. terminate_process = 1;
  150. }
  151. //**********************************************************************************************************************