Control drones with a proper joystick
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

events_buttons.cpp 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Saitek X52 Arduino USB Host Shield Library.
  3. * Copyright 2016 by Thomas Buck <xythobuz@xythobuz.de>
  4. *
  5. * Based on the USB Host Library HID Joystick example
  6. * https://www.circuitsathome.com/mcu/hid-joystick-code-sample
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation, version 2.
  11. */
  12. #include <Arduino.h>
  13. #include "data.h"
  14. #include "x52.h"
  15. #include "cppm.h"
  16. #include "events.h"
  17. #define DEBUG_OUTPUT
  18. //#define DEBUG_BUTTON_MFD
  19. #define MENU_BUTTON_ENTER_1 29
  20. #define MENU_BUTTON_ENTER_2 26
  21. #define MENU_BUTTON_DOWN 27
  22. #define MENU_BUTTON_UP 28
  23. #define MODE_BUTTON_GREEN 23
  24. #define MODE_BUTTON_YELLOW 24
  25. #define MODE_BUTTON_RED 25
  26. JoystickEventsButtons::JoystickEventsButtons(X52* x, JoystickEvents* client)
  27. : JoystickEvents(client), x52(x), state(NONE), index(0), value(0) { }
  28. void JoystickEventsButtons::OnGamePadChanged(const GamePadEventData& evt) {
  29. if (client) {
  30. client->OnGamePadChanged(evt);
  31. }
  32. }
  33. void JoystickEventsButtons::OnHatSwitch(uint8_t hat) {
  34. #ifdef DEBUG_BUTTON_MFD
  35. String text = "Hat is " + String(hat);
  36. x52->setMFDText(1, text.c_str());
  37. #endif
  38. if (client) {
  39. client->OnHatSwitch(hat);
  40. }
  41. }
  42. void JoystickEventsButtons::OnButtonUp(uint8_t but_id) {
  43. #ifdef DEBUG_BUTTON_MFD
  44. String text = "Button " + String(but_id) + " up";
  45. x52->setMFDText(1, text.c_str());
  46. #endif
  47. if (client) {
  48. client->OnButtonUp(but_id);
  49. }
  50. }
  51. void JoystickEventsButtons::menuHelper(uint8_t count, const char** menu, const char* title) {
  52. if (index >= count) {
  53. index = count - 1;
  54. }
  55. uint8_t start = 0, line = 0;
  56. if (index > 1) {
  57. start = index - 1;
  58. }
  59. uint8_t end = start + 2;
  60. if (index == 0) {
  61. x52->setMFDText(0, title);
  62. line = 1;
  63. end = start + 1;
  64. }
  65. if (end >= count) {
  66. end = count - 1;
  67. }
  68. for (uint8_t i = start; i <= end; i++) {
  69. String tmp = (index == i) ? "-> " : " ";
  70. x52->setMFDText(line++, (tmp + menu[i]).c_str());
  71. }
  72. if (line == 2) {
  73. x52->setMFDText(2);
  74. }
  75. #ifdef DEBUG_OUTPUT
  76. Serial.print("menuHelper() state=");
  77. Serial.print(state);
  78. Serial.print(" index=");
  79. Serial.print(index);
  80. Serial.print(" start=");
  81. Serial.print(start);
  82. Serial.print(" end=");
  83. Serial.println(end);
  84. #endif
  85. }
  86. void JoystickEventsButtons::printMenu() {
  87. static const char* mainMenu[] = {
  88. "Channels", "Frame Length",
  89. "Pulse Length", "Invert"
  90. };
  91. static const uint8_t mainMenuCount = sizeof(mainMenu) / sizeof(mainMenu[0]);
  92. if (state == MAINMENU) {
  93. menuHelper(mainMenuCount, mainMenu, "Main Menu");
  94. } else if (state == EDIT_CHANNELS) {
  95. printValue(4, CHANNELS_MAX, mainMenu[0]);
  96. } else if (state == EDIT_FRAME_LENGTH) {
  97. printValue(10000, 30000, mainMenu[1]);
  98. } else if (state == EDIT_PULSE_LENGTH) {
  99. printValue(100, 1000, mainMenu[2]);
  100. } else if (state == EDIT_INVERT) {
  101. printValue(0, 1, mainMenu[3]);
  102. }
  103. }
  104. void JoystickEventsButtons::printValue(uint16_t min, uint16_t max, const char* title) {
  105. #ifdef DEBUG_OUTPUT
  106. Serial.print("printValue() state=");
  107. Serial.print(state);
  108. Serial.print(" index=");
  109. Serial.print(index);
  110. Serial.print(" min=");
  111. Serial.print(min);
  112. Serial.print(" max=");
  113. Serial.println(max);
  114. #endif
  115. if (value < min) {
  116. value = min;
  117. }
  118. if (value > max) {
  119. value = max;
  120. }
  121. x52->setMFDText(0, (String(title) + ":").c_str());
  122. x52->setMFDText(1, String(value).c_str());
  123. x52->setMFDText(2, "Press OK to save");
  124. }
  125. void JoystickEventsButtons::OnButtonDown(uint8_t but_id) {
  126. #ifdef DEBUG_BUTTON_MFD
  127. String text = "Button " + String(but_id) + " down";
  128. x52->setMFDText(1, text.c_str());
  129. #endif
  130. if (but_id == MODE_BUTTON_GREEN) {
  131. x52->setLEDBrightness(2);
  132. x52->setMFDBrightness(2);
  133. } else if (but_id == MODE_BUTTON_YELLOW) {
  134. x52->setLEDBrightness(1);
  135. x52->setMFDBrightness(1);
  136. } else if (but_id == MODE_BUTTON_RED) {
  137. x52->setLEDBrightness(0);
  138. x52->setMFDBrightness(0);
  139. } else if ((but_id == MENU_BUTTON_ENTER_1) || (but_id == MENU_BUTTON_ENTER_2)) {
  140. if (state == NONE) {
  141. state = MAINMENU;
  142. } else if (state == MAINMENU) {
  143. if (index == 0) {
  144. state = EDIT_CHANNELS;
  145. value = CPPM::instance().getChannels();
  146. } else if (index == 1) {
  147. state = EDIT_FRAME_LENGTH;
  148. value = CPPM::instance().getFrameLength();
  149. } else if (index == 2) {
  150. state = EDIT_PULSE_LENGTH;
  151. value = CPPM::instance().getPulseLength();
  152. } else if (index == 3) {
  153. state = EDIT_INVERT;
  154. value = CPPM::instance().getInvert();
  155. }
  156. } else if (state == EDIT_CHANNELS) {
  157. CPPM::instance().setChannels(value);
  158. state = MAINMENU;
  159. } else if (state == EDIT_FRAME_LENGTH) {
  160. CPPM::instance().setFrameLength(value);
  161. state = MAINMENU;
  162. } else if (state == EDIT_PULSE_LENGTH) {
  163. CPPM::instance().setPulseLength(value);
  164. state = MAINMENU;
  165. } else if (state == EDIT_INVERT) {
  166. CPPM::instance().setInvert(value);
  167. state = MAINMENU;
  168. }
  169. printMenu();
  170. } else if (but_id == MENU_BUTTON_DOWN) {
  171. if (state > STATES_EDIT) {
  172. if (value > 0) {
  173. value--;
  174. }
  175. } else if (state != NONE) {
  176. index++;
  177. }
  178. printMenu();
  179. } else if (but_id == MENU_BUTTON_UP) {
  180. if (state > STATES_EDIT) {
  181. if (value < 0xFFFF) {
  182. value++;
  183. }
  184. } else if (state != NONE) {
  185. if (index > 0) {
  186. index--;
  187. }
  188. }
  189. printMenu();
  190. }
  191. if (client) {
  192. client->OnButtonDown(but_id);
  193. }
  194. }
  195. void JoystickEventsButtons::OnMouseMoved(uint8_t x, uint8_t y) {
  196. if (client) {
  197. client->OnMouseMoved(x, y);
  198. }
  199. }