SemlerPDX icon

Modified HSI+QNH+3xToggle Arduino Sketch for Falcon BMS / DCS / FSX

SemlerPDX | PRO | 06/04/22 05:35:27 AM UTC (Edited) | 0 ⭐ | 953 👁️ | Never ⏰ | []
Arduino |

6.74 KB

|

None

|

0 👍

/

0 👎

/* Modified HSI Knobs Sketch for Falcon BMS / DCS / FSX
 *  with additional 3rd Rotary Encoder (Z Axis)
 *    also with a 3-way Toggle Switch as buttons
 *  for Arduino Leonardo or equiv. clones
 * by SemlerPDX Sep2019
 * VETERANS-GAMING.COM
 * ( in response to reply at:
 *    https://veterans-gaming.com/index.php?/blogs/entry/32-diy-custom-game-controller-2-dial-hsi-course-and-heading-knobs/ )
 *  
 *  Rotary Encoders need 2 Intterupt Pins Each - Choose a board that has enough like Arduino Leonardo (or clones)
 *    info on Interrupts: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
 *  
 *  Pins:
 *  Rotary Encoder 1 - (OUTA-OUTB-SW) = Arduino Pins (0,1,15)
 *  Rotary Encoder 2 - (OUTA-OUTB-SW) = Arduino Pins (2,3,6)
 *  Rotary Encoder 3 - (OUTA-OUTB-SW) = Arduino Pins (9,10,7)
 *  
 *  Three-Way Toggle - (Center Post)  = Analog Input (A1)
 *  
 *  Three-Way Toggle Switch Wiring Example:
 * https://veterans-gaming.com/uploads/monthly_2019_09/three_way_toggle_wiring_arduino.png.1524289e8f56690c7ff6d9f321904de9.png
 *  
 *  Encoder Library
 * https://www.pjrc.com/teensy/td_libs_Encoder.html
 *
 *  Joystick Library
 * by Matthew Heironimus
 * https://github.com/MHeironimus/ArduinoJoystickLibrary
 */
#define ENCODER_USE_INTERRUPTS
#define ENCODER_OPTIMIZE_INTERRUPTS
#include <Encoder.h>
#include <Joystick.h>
 
//Three Way Toggle Init
#define TOGGLE_PIN A1
int previousState;
bool aToggled;
 
//Rotary Encoder Push Button Pins
//  *further buttons added must increment after these (these are 0,1,2) (buttons 1,2 and 3 on controller)
int buttonArray[3] = {15, 6, 7};
 
//Set Toggle Positions as Buttons* (buttons start at 0,1,2,3,4,5 for 6 buttons)
int ToggleButton1 = 3; //button 4 on controller
int ToggleButton2 = 4; //button 5 on controller
int ToggleButton3 = 5; //button 6 on controller
 
//Rotary Encoder Interrupt Pins
int EncoderPin0 = 0;
int EncoderPin1 = 1;
int EncoderPin2 = 2;
int EncoderPin3 = 3;
int EncoderPin4 = 9;   //*Must have board with 6 total interrupt pins
int EncoderPin5 = 10;  //*Must have board with 6 total interrupt pins
 
//Tell the Encoder Library which pins have encoders
Encoder axisXRotation(EncoderPin0, EncoderPin1);
Encoder axisYRotation(EncoderPin2, EncoderPin3);
Encoder axisZRotation(EncoderPin4, EncoderPin5);
 
//Delay Time between loops
int debounceDelay = 260;
 
//Delay Time before button release
int toggleDebounce = 10;
 
//Intervals for Jump/Warp Speed Rotations
int JumpSpeed = 18;
int WarpSpeed = 30;
 
//Set generic joystick with id 42 with 6 buttons and 3 axes
Joystick_ Joystick(0x42, 
  0x04, 6, 0,
  false, false, false, true, true, true,
  false, false, false, false, false);  
 
//Variables to compare current to old values
int oldX = 0;
int oldY = 0;
int oldZ = 0;
int RxAxis_Value = 1;
int RyAxis_Value = 1;
int RzAxis_Value = 1;
 
 
//Function to translate Three-way Toggle Analog Value
int getToggleState(int aVal) {
  if (aVal < 100) {
    aVal = ToggleButton1;
  }else if (aVal < 900) {
    aVal = ToggleButton3;
  }else{
    aVal = ToggleButton2;
  }
  return aVal;
}
 
//Function to set Rotation value adjusted for the turning speed
int speedVal(int dif, int val, int dir) {
  int increment = 1;
  if (dif >= WarpSpeed) {
    increment = WarpSpeed;
  }else if (dif >= JumpSpeed) {
    increment = JumpSpeed;
  }
  if (dir == 1) {
    val = val + increment;
  }else{
    val = val - increment;
  }
  //Correct Rotation within 360 deg.
  if (val < 0) {
    val = val + 360;
  }else if (val >= 360) {        
    val = val - 360;
  }
  return val;
}
 
 
void setup() { 
  
  //Toggle Switch Setup
  previousState = 1000;
  aToggled = false;
 
  //Loop through Encoder Pins and set them as Pullups
  for (int x = 0; x < 6; x++) {
    pinMode(EncoderPin[x], INPUT_PULLUP);
  }
 
  //Loop through buttons and set them as Pullups
  for (int x = 0; x < sizeof(buttonArray); x++) {
    pinMode(buttonArray[x], INPUT_PULLUP);
  }
 
  //Set Range of custom Axes
  Joystick.setRxAxisRange(0, 359);
  Joystick.setRyAxisRange(0, 359);
  Joystick.setRzAxisRange(0, 359);
  
  // Initialize Joystick Library
  Joystick.begin(false);
 
}
 
 
void loop() {
 
  // Loop through button pin values & set to Joystick
  for (int x = 0; x < sizeof(buttonArray); x++) {
    byte currentButtonState = !digitalRead(buttonArray[x]);
    Joystick.setButton(x, currentButtonState);
  }
 
 
  //Read Three Way Toggle
  int analogValue = analogRead(TOGGLE_PIN);
  int actualState = getToggleState(analogValue);
  if (previousState != actualState) {
    //Set Toggle Switch input as Button Press
    Joystick.setButton(actualState, 1);
    previousState = actualState;
    aToggled = true;
    
  }else{
    //Reset button(s) to unpressed state
    if (aToggled) {
      aToggled = false;
      delay (toggleDebounce);
      for (int a = 3; a < 6; a++) {
        Joystick.setButton(a, 0);
      }
    }
  }
  
 
  // Read "Heading" X Axis Rotation Encoder Knob
  int newX = axisXRotation.read();
  if (newX > oldX) {
    //Determine speed of increment & set output
    int difX = newX - oldX;
    RxAxis_Value = speedVal(difX, RxAxis_Value, 1);
    Joystick.setRxAxis(RxAxis_Value);
    axisXRotation.write(newX);
    oldX = newX;
 
  }else if (newX < oldX) {
    //Determine speed of decrement & set output
    int difX = oldX - newX;
    RxAxis_Value = speedVal(difX, RxAxis_Value, 0);
    Joystick.setRxAxis(RxAxis_Value);
    axisXRotation.write(newX);
    oldX = newX;
  }
 
 
  // Read "Course" Y Axis Rotation Encoder Knob
  int newY = axisYRotation.read();
  if (newY > oldY) {
    //Determine speed of increment & set output
    int difY = newY - oldY;
    RyAxis_Value = speedVal(difY, RyAxis_Value, 1);
    Joystick.setRyAxis(RyAxis_Value);
    axisYRotation.write(newY);
    oldY = newY;
 
  }else if (newY < oldY) {
    //Determine speed of decrement & set output
    int difY = oldY - newY;
    RyAxis_Value = speedVal(difY, RyAxis_Value, 0);
    Joystick.setRyAxis(RyAxis_Value);
    axisYRotation.write(newY);
    oldY = newY;
  }
 
 
  // Read "QNH" Z Axis Rotation Encoder Knob
  int newZ = axisZRotation.read();
  if (newZ > oldZ) {
    //Determine speed of increment & set output
    int difZ = newZ - oldZ;
    RzAxis_Value = speedVal(difZ, RzAxis_Value, 1);
    Joystick.setRzAxis(RzAxis_Value);
    axisZRotation.write(newZ);
    oldZ = newZ;
 
  }else if (newZ < oldZ) {
    //Determine speed of decrement & set output
    int difZ = oldZ - newZ;
    RzAxis_Value = speedVal(difZ, RzAxis_Value, 0);
    Joystick.setRzAxis(RzAxis_Value);
    axisZRotation.write(newZ);
    oldZ = newZ;
  }
 
 
  //Send Joystick info through USB
  Joystick.sendState();
  delay(debounceDelay);
}

Comments