analog_joystick.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "analog_joystick.h"
  17. #include "analog.h"
  18. #include "gpio.h"
  19. #include "wait.h"
  20. #include "timer.h"
  21. #include <stdlib.h>
  22. // Set Parameters
  23. uint16_t minAxisValue = ANALOG_JOYSTICK_AXIS_MIN;
  24. uint16_t maxAxisValue = ANALOG_JOYSTICK_AXIS_MAX;
  25. uint8_t maxCursorSpeed = ANALOG_JOYSTICK_SPEED_MAX;
  26. uint8_t speedRegulator = ANALOG_JOYSTICK_SPEED_REGULATOR; // Lower Values Create Faster Movement
  27. int16_t xOrigin, yOrigin;
  28. uint16_t lastCursor = 0;
  29. int16_t axisCoordinate(pin_t pin, uint16_t origin) {
  30. int8_t direction;
  31. int16_t distanceFromOrigin;
  32. int16_t range;
  33. int16_t position = analogReadPin(pin);
  34. if (origin == position) {
  35. return 0;
  36. } else if (origin > position) {
  37. distanceFromOrigin = origin - position;
  38. range = origin - minAxisValue;
  39. direction = -1;
  40. } else {
  41. distanceFromOrigin = position - origin;
  42. range = maxAxisValue - origin;
  43. direction = 1;
  44. }
  45. float percent = (float)distanceFromOrigin / range;
  46. int16_t coordinate = (int16_t)(percent * 100);
  47. if (coordinate < 0) {
  48. return 0;
  49. } else if (coordinate > 100) {
  50. return 100 * direction;
  51. } else {
  52. return coordinate * direction;
  53. }
  54. }
  55. int8_t axisToMouseComponent(pin_t pin, int16_t origin, uint8_t maxSpeed) {
  56. int16_t coordinate = axisCoordinate(pin, origin);
  57. if (coordinate != 0) {
  58. float percent = (float)coordinate / 100;
  59. return percent * maxCursorSpeed * (abs(coordinate) / speedRegulator);
  60. } else {
  61. return 0;
  62. }
  63. }
  64. report_analog_joystick_t analog_joystick_read(void) {
  65. report_analog_joystick_t report = {0};
  66. if (timer_elapsed(lastCursor) > ANALOG_JOYSTICK_READ_INTERVAL) {
  67. lastCursor = timer_read();
  68. report.x = axisToMouseComponent(ANALOG_JOYSTICK_X_AXIS_PIN, xOrigin, maxCursorSpeed);
  69. report.y = axisToMouseComponent(ANALOG_JOYSTICK_Y_AXIS_PIN, yOrigin, maxCursorSpeed);
  70. }
  71. #ifdef ANALOG_JOYSTICK_CLICK_PIN
  72. report.button = !readPin(ANALOG_JOYSTICK_CLICK_PIN);
  73. #endif
  74. return report;
  75. }
  76. void analog_joystick_init(void) {
  77. #ifdef ANALOG_JOYSTICK_CLICK_PIN
  78. setPinInputHigh(ANALOG_JOYSTICK_CLICK_PIN);
  79. #endif
  80. // Account for drift
  81. xOrigin = analogReadPin(ANALOG_JOYSTICK_X_AXIS_PIN);
  82. yOrigin = analogReadPin(ANALOG_JOYSTICK_Y_AXIS_PIN);
  83. }