SemlerPDX

Game Controller - Rotary Encoders HSI Course & Heading Knobs

Jun 5th, 2019 (edited)
2,022
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* Simple HSI Knobs Sketch for Falcon BMS / DCS / FSX
  2.  *  for Arduino Micro/Leonardo / Sparkfun Pro Micro or equiv. clones
  3.  * by SemlerPDX June2019
  4.  * VETERANS-GAMING.COM
  5.  * ( https://veterans-gaming.com/blogs/entry/32-diy-custom-game-controller-2-dial-hsi-course-and-heading-knobs/ )
  6.  *  
  7.  *  Pins:
  8.  *  Rotary Encoder 1 - (OUTA-OUTB-SW) = Arduino Pins (0,1,15)
  9.  *  Rotary Encoder 2 - (OUTA-OUTB-SW) = Arduino Pins (2,3,6)
  10.  *  
  11.  *  Encoder Library
  12.  * http://www.pjrc.com/teensy/td_libs_Encoder.html
  13.  *
  14.  *  Joystick Library
  15.  * by Matthew Heironimus
  16.  * https://github.com/MHeironimus/ArduinoJoystickLibrary
  17.  */
  18.  
  19. #define ENCODER_USE_INTERRUPTS
  20. #define ENCODER_OPTIMIZE_INTERRUPTS
  21. #include <Encoder.h>
  22. #include <Joystick.h>
  23.  
  24. //Tell the Encoder Library which pins have encoders
  25. Encoder axisXRotation(0, 1);
  26. Encoder axisYRotation(2, 3);
  27.  
  28. //Rotary Encoder Push Button Pins
  29. int buttonArray[2] = {15, 6};
  30.  
  31. //Rotary Encoder Interrupt Pins
  32. int EncoderPin0 = 0;
  33. int EncoderPin1 = 1;
  34. int EncoderPin2 = 2;
  35. int EncoderPin3 = 3;
  36.  
  37. //Delay Time between loops
  38. int debounceDelay = 260;
  39.  
  40. //Variables to compare current to old values
  41. int oldX = 0;
  42. int oldY = 0;
  43. int RxAxis_Value = 1;
  44. int RyAxis_Value = 1;
  45.  
  46. //Intervals for Jump/Warp Speed Rotations
  47. int JumpSpeed = 18;
  48. int WarpSpeed = 30;
  49.  
  50. //Set generic joystick with id 42 with 2 buttons and 2 axes
  51. Joystick_ Joystick(0x42,
  52.   0x04, 2, 0,
  53.   false, false, false, true, true, false,
  54.   false, false, false, false, false);  
  55.  
  56.  
  57. void setup() {
  58.  
  59.   //Set Encoder Pins as Pullups
  60.   pinMode(EncoderPin0, INPUT_PULLUP);
  61.   pinMode(EncoderPin1, INPUT_PULLUP);
  62.   pinMode(EncoderPin2, INPUT_PULLUP);
  63.   pinMode(EncoderPin3, INPUT_PULLUP);
  64.  
  65.   //Loop through buttons and set them as Pullups
  66.   for (int x = 0; x < sizeof(buttonArray); x++) {
  67.     pinMode(buttonArray[x], INPUT_PULLUP);
  68.   }
  69.  
  70.   //Set Range of custom Axes
  71.   Joystick.setRxAxisRange(0, 359);
  72.   Joystick.setRyAxisRange(0, 359);
  73.  
  74.   // Initialize Joystick Library
  75.   Joystick.begin(false);
  76.  
  77. }
  78.  
  79.  
  80. void loop() {
  81.  
  82.   // Loop through button pin values & set to Joystick
  83.   for (int x = 0; x < sizeof(buttonArray); x++) {
  84.     byte currentButtonState = !digitalRead(buttonArray[x]);
  85.     Joystick.setButton(x, currentButtonState);
  86.   }
  87.  
  88.  
  89.   // Read "Heading" X Axis Rotation Encoder Knob
  90.   int newX = axisXRotation.read();
  91.   if (newX > oldX) {
  92.     //Determine speed of increment & set output
  93.     int difX = newX - oldX;
  94.     RxAxis_Value = speedVal(difX, RxAxis_Value, 1);
  95.     Joystick.setRxAxis(RxAxis_Value);
  96.     axisXRotation.write(newX);
  97.     oldX = newX;
  98.  
  99.   }else if (newX < oldX) {
  100.     //Determine speed of decrement & set output
  101.     int difX = oldX - newX;
  102.     RxAxis_Value = speedVal(difX, RxAxis_Value, 0);
  103.     Joystick.setRxAxis(RxAxis_Value);
  104.     axisXRotation.write(newX);
  105.     oldX = newX;
  106.   }
  107.  
  108.  
  109.   // Read "Course" Y Axis Rotation Encoder Knob
  110.   int newY = axisYRotation.read();
  111.   if (newY > oldY) {
  112.     //Determine speed of increment & set output
  113.     int difY = newY - oldY;
  114.     RyAxis_Value = speedVal(difY, RyAxis_Value, 1);
  115.     Joystick.setRyAxis(RyAxis_Value);
  116.     axisYRotation.write(newY);
  117.     oldY = newY;
  118.  
  119.   }else if (newY < oldY) {
  120.     //Determine speed of decrement & set output
  121.     int difY = oldY - newY;
  122.     RyAxis_Value = speedVal(difY, RyAxis_Value, 0);
  123.     Joystick.setRyAxis(RyAxis_Value);
  124.     axisYRotation.write(newY);
  125.     oldY = newY;
  126.   }
  127.  
  128.  
  129.   //Send Joystick info through USB
  130.   Joystick.sendState();
  131.   delay(debounceDelay);
  132. }
  133.  
  134.  
  135. //Function to set Rotation value adjusted for the turning speed
  136. int speedVal(int dif, int val, int dir) {
  137.   if (dif >= WarpSpeed) {
  138.     if (dir == 1) {
  139.       val = val + WarpSpeed;
  140.     }else{
  141.       val = val - WarpSpeed;
  142.     }
  143.   }else if (dif >= JumpSpeed) {
  144.     if (dir == 1) {
  145.       val = val + JumpSpeed;
  146.     }else{
  147.       val = val - JumpSpeed;
  148.     }
  149.   }else{
  150.     if (dir == 1) {
  151.       val = val + 1;
  152.     }else{
  153.       val = val - 1;
  154.     }
  155.   }
  156.   //Correct Rotation within 360 deg.
  157.   if (val < 0) {
  158.     val = val + 360;
  159.   }else if (val >= 360) {        
  160.     val = val - 360;
  161.   }
  162.   return val;
  163. }
Comments
  • SemlerPDX
    1 year
    # Arduino 0.49 KB | 0 0
    1. /* Figured I'd note here that a first draft used a different method for correcting rotation within 360 degrees,
    2.  * yet I changed it to a more readable form for folks newer to coding and Arduino, so they would better be able
    3.  * to understand the simple logic that is occuring in this snippet.  Therefore, it should also be noted that it
    4.  * can be expressed more concisely in a single line using a modulus operator like this:
    5. */
    6.  
    7.   //Correct Rotation within 360 deg.
    8.   val = (val % 360 + 360) % 360;
Add Comment
Please, Sign In to add comment