AP_Button.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. #include "AP_Button.h"
  14. #include <GCS_MAVLink/GCS_MAVLink.h>
  15. #include <GCS_MAVLink/GCS.h>
  16. extern const AP_HAL::HAL& hal;
  17. const AP_Param::GroupInfo AP_Button::var_info[] = {
  18. // @Param: ENABLE
  19. // @DisplayName: Enable button reporting
  20. // @Description: This enables the button checking module. When this is disabled the parameters for setting button inputs are not visible
  21. // @Values: 0:Disabled, 1:Enabled
  22. // @User: Advanced
  23. AP_GROUPINFO_FLAGS("ENABLE", 0, AP_Button, enable, 0, AP_PARAM_FLAG_ENABLE),
  24. // @Param: PIN1
  25. // @DisplayName: First button Pin
  26. // @Description: Digital pin number for first button input.
  27. // @User: Standard
  28. // @Values: -1:Disabled,50:AUXOUT1,51:AUXOUT2,52:AUXOUT3,53:AUXOUT4,54:AUXOUT5,55:AUXOUT6
  29. AP_GROUPINFO("PIN1", 1, AP_Button, pin[0], -1),
  30. // @Param: PIN2
  31. // @DisplayName: Second button Pin
  32. // @Description: Digital pin number for second button input.
  33. // @User: Standard
  34. // @Values: -1:Disabled,50:AUXOUT1,51:AUXOUT2,52:AUXOUT3,53:AUXOUT4,54:AUXOUT5,55:AUXOUT6
  35. AP_GROUPINFO("PIN2", 2, AP_Button, pin[1], -1),
  36. // @Param: PIN3
  37. // @DisplayName: Third button Pin
  38. // @Description: Digital pin number for third button input.
  39. // @User: Standard
  40. // @Values: -1:Disabled,50:AUXOUT1,51:AUXOUT2,52:AUXOUT3,53:AUXOUT4,54:AUXOUT5,55:AUXOUT6
  41. AP_GROUPINFO("PIN3", 3, AP_Button, pin[2], -1),
  42. // @Param: PIN4
  43. // @DisplayName: Fourth button Pin
  44. // @Description: Digital pin number for fourth button input.
  45. // @User: Standard
  46. // @Values: -1:Disabled,50:AUXOUT1,51:AUXOUT2,52:AUXOUT3,53:AUXOUT4,54:AUXOUT5,55:AUXOUT6
  47. AP_GROUPINFO("PIN4", 4, AP_Button, pin[3], -1),
  48. // @Param: REPORT_SEND
  49. // @DisplayName: Report send time
  50. // @Description: The duration in seconds that a BUTTON_CHANGE report is repeatedly sent to the GCS regarding a button changing state. Note that the BUTTON_CHANGE message is MAVLink2 only.
  51. // @User: Standard
  52. // @Range: 0 3600
  53. AP_GROUPINFO("REPORT_SEND", 5, AP_Button, report_send_time, 10),
  54. AP_GROUPEND
  55. };
  56. // constructor
  57. AP_Button::AP_Button(void)
  58. {
  59. AP_Param::setup_object_defaults(this, var_info);
  60. }
  61. /*
  62. update and report, called from main loop
  63. */
  64. void AP_Button::update(void)
  65. {
  66. if (!enable) {
  67. return;
  68. }
  69. // call setup pins at update rate (5Hz) to allow for runtime parameter change of pins
  70. setup_pins();
  71. if (!initialised) {
  72. initialised = true;
  73. // get initial mask
  74. last_mask = get_mask();
  75. // register 1kHz timer callback
  76. hal.scheduler->register_timer_process(FUNCTOR_BIND_MEMBER(&AP_Button::timer_update, void));
  77. }
  78. if (last_change_time_ms != 0 &&
  79. (AP_HAL::millis() - last_report_ms) > AP_BUTTON_REPORT_PERIOD_MS &&
  80. (AP_HAL::millis64() - last_change_time_ms) < report_send_time*1000ULL) {
  81. // send a change report
  82. last_report_ms = AP_HAL::millis();
  83. // send a report to GCS
  84. send_report();
  85. }
  86. }
  87. /*
  88. get current mask
  89. */
  90. uint8_t AP_Button::get_mask(void)
  91. {
  92. uint8_t mask = 0;
  93. for (uint8_t i=0; i<AP_BUTTON_NUM_PINS; i++) {
  94. if (pin[i] == -1) {
  95. continue;
  96. }
  97. mask |= hal.gpio->read(pin[i]) << i;
  98. }
  99. return mask;
  100. }
  101. /*
  102. called at 1kHz to check for button state change
  103. */
  104. void AP_Button::timer_update(void)
  105. {
  106. if (!enable) {
  107. return;
  108. }
  109. uint8_t mask = get_mask();
  110. if (mask != last_mask) {
  111. last_mask = mask;
  112. last_change_time_ms = AP_HAL::millis64();
  113. }
  114. }
  115. /*
  116. send a BUTTON_CHANGE report to the GCS
  117. */
  118. void AP_Button::send_report(void)
  119. {
  120. const mavlink_button_change_t packet{
  121. time_boot_ms: AP_HAL::millis(),
  122. last_change_ms: uint32_t(last_change_time_ms),
  123. state: last_mask
  124. };
  125. gcs().send_to_active_channels(MAVLINK_MSG_ID_BUTTON_CHANGE,
  126. (const char *)&packet);
  127. }
  128. /*
  129. setup the pins as input with pullup. We need pullup to give reliable
  130. input with a pulldown button
  131. */
  132. void AP_Button::setup_pins(void)
  133. {
  134. for (uint8_t i=0; i<AP_BUTTON_NUM_PINS; i++) {
  135. if (pin[i] == -1) {
  136. continue;
  137. }
  138. hal.gpio->pinMode(pin[i], HAL_GPIO_INPUT);
  139. // setup pullup
  140. hal.gpio->write(pin[i], 1);
  141. }
  142. }