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.

Saitek-X52-PPM.ino 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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 <hid.h>
  13. #include <hiduniversal.h>
  14. #include <usbhub.h>
  15. #include <avr/wdt.h>
  16. #include "events.h"
  17. #include "parser.h"
  18. #include "x52.h"
  19. #include "cppm.h"
  20. #include "frsky.h"
  21. #define ENABLE_SERIAL_PORT
  22. //#define DEBUG_OUTPUT Serial
  23. //#define DEBUG_MFD_UPTIME
  24. USB usb;
  25. USBHub hub(&usb);
  26. HIDUniversal hid(&usb);
  27. X52 x52(&usb, &hid);
  28. JoystickEventsCPPM joyCPPM;
  29. JoystickEventsButtons joyButtons((JoystickEvents*)&joyCPPM);
  30. JoystickEventsDeadZone joyDeadZone((JoystickEvents*)&joyButtons);
  31. JoystickReportParser joy(&joyDeadZone);
  32. FrSky frsky(&Serial);
  33. static void stringHelper(String& a, String& b, char delim, uint8_t line) {
  34. String s = a + delim;
  35. for (uint8_t i = 0; i < (14 - a.length() - b.length()); i++) {
  36. s += ' ';
  37. }
  38. s += b + delim;
  39. x52.setMFDText(line, s.c_str());
  40. }
  41. void statusCallback(uint8_t a1, uint8_t a2, uint8_t q1, uint8_t q2) {
  42. x52.setMFDText(0, "Telemetry Status");
  43. uint16_t l1 = q1 * 100 / 255, l2 = q2 * 100 / 255;
  44. String link1(l1), link2(l2);
  45. stringHelper(link1, link2, '%', 1);
  46. uint32_t v1 = a1 * 330 / 255;
  47. uint32_t v1hundred = v1 / 100;
  48. uint32_t v1ten = v1 % 100;
  49. String volt1 = String(v1hundred) + '.' + (v1ten);
  50. uint32_t v2 = a2 * 330 / 255;
  51. uint32_t v2hundred = v2 / 100;
  52. uint32_t v2ten = v2 % 100;
  53. String volt2 = String(v2hundred) + '.' + (v2ten);
  54. stringHelper(volt1, volt2, 'V', 2);
  55. }
  56. void setup() {
  57. #ifdef ENABLE_SERIAL_PORT
  58. Serial.begin(115200);
  59. #endif
  60. #ifdef DEBUG_OUTPUT
  61. DEBUG_OUTPUT.println("Start");
  62. #endif
  63. pinMode(13, OUTPUT);
  64. digitalWrite(13, LOW);
  65. if (usb.Init() == -1) {
  66. digitalWrite(13, HIGH);
  67. #ifdef DEBUG_OUTPUT
  68. DEBUG_OUTPUT.println("OSC did not start.");
  69. #endif
  70. }
  71. if (!hid.SetReportParser(0, &joy)) {
  72. digitalWrite(13, HIGH);
  73. #ifdef DEBUG_OUTPUT
  74. DEBUG_OUTPUT.println("Error adding report parser.");
  75. #endif
  76. }
  77. CPPM::instance().init();
  78. frsky.setDataHandler(&statusCallback);
  79. wdt_enable(WDTO_500MS);
  80. }
  81. void init_joystick() {
  82. x52.initialize();
  83. statusCallback(0, 0, 0, 0);
  84. // Sometimes the first message is lost, so send again
  85. if (joyButtons.getCurrentMode() == 1) {
  86. x52.setLEDBrightness(2);
  87. x52.setMFDBrightness(2);
  88. } else if (joyButtons.getCurrentMode() == 2) {
  89. x52.setLEDBrightness(1);
  90. x52.setMFDBrightness(1);
  91. } else if (joyButtons.getCurrentMode() == 3) {
  92. x52.setLEDBrightness(0);
  93. x52.setMFDBrightness(0);
  94. }
  95. }
  96. void loop() {
  97. wdt_reset();
  98. usb.Task();
  99. frsky.poll();
  100. static unsigned long lastTime = 0;
  101. static uint8_t initialized = 0;
  102. if ((millis() - lastTime) >= 1000) {
  103. lastTime = millis();
  104. if (initialized == 0) {
  105. initialized = 1;
  106. } else if (initialized == 1) {
  107. init_joystick();
  108. initialized = 2;
  109. }
  110. #ifdef DEBUG_MFD_UPTIME
  111. String text = "Uptime: " + String(millis() / 1000) + "s";
  112. x52.setMFDText(2, text.c_str());
  113. #endif
  114. }
  115. }