SHOW:
|
|
- or go back to the newest paste.
| 1 | /* Modified HSI Knobs Sketch for Falcon BMS / DCS / FSX | |
| 2 | * with additional 3rd Rotary Encoder (Z Axis) | |
| 3 | - | * *(coming next: a 3-way Toggle Switch add-on) |
| 3 | + | * also with a 3-way Toggle Switch as buttons |
| 4 | - | * for Arduino Micro/Leonardo / Sparkfun Pro Micro or equiv. clones |
| 4 | + | * for Arduino Leonardo or equiv. clones |
| 5 | - | * by SemlerPDX Aug2019 |
| 5 | + | * by SemlerPDX Sep2019 |
| 6 | * VETERANS-GAMING.COM | |
| 7 | * ( in response to reply at: | |
| 8 | - | * http://veterans-gaming.com/index.php?/blogs/entry/32-diy-custom-game-controller-2-dial-hsi-course-and-heading-knobs/ ) |
| 8 | + | * https://veterans-gaming.com/index.php?/blogs/entry/32-diy-custom-game-controller-2-dial-hsi-course-and-heading-knobs/ ) |
| 9 | * | |
| 10 | * Rotary Encoders need 2 Intterupt Pins Each - Choose a board that has enough like Arduino Leonardo (or clones) | |
| 11 | * info on Interrupts: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/ | |
| 12 | * | |
| 13 | * Pins: | |
| 14 | * Rotary Encoder 1 - (OUTA-OUTB-SW) = Arduino Pins (0,1,15) | |
| 15 | * Rotary Encoder 2 - (OUTA-OUTB-SW) = Arduino Pins (2,3,6) | |
| 16 | - | * http://www.pjrc.com/teensy/td_libs_Encoder.html |
| 16 | + | |
| 17 | - | * |
| 17 | + | |
| 18 | - | * Joystick Library |
| 18 | + | * Three-Way Toggle - (Center Post) = Analog Input (A1) |
| 19 | * | |
| 20 | * Three-Way Toggle Switch Wiring Example: | |
| 21 | * https://veterans-gaming.com/uploads/monthly_2019_09/three_way_toggle_wiring_arduino.png.1524289e8f56690c7ff6d9f321904de9.png | |
| 22 | * | |
| 23 | * Encoder Library | |
| 24 | * https://www.pjrc.com/teensy/td_libs_Encoder.html | |
| 25 | * | |
| 26 | * Joystick Library | |
| 27 | * by Matthew Heironimus | |
| 28 | * https://github.com/MHeironimus/ArduinoJoystickLibrary | |
| 29 | - | Encoder axisXRotation(0, 1); |
| 29 | + | |
| 30 | - | Encoder axisYRotation(2, 3); |
| 30 | + | |
| 31 | - | Encoder axisZRotation(9, 10); |
| 31 | + | |
| 32 | #include <Encoder.h> | |
| 33 | #include <Joystick.h> | |
| 34 | ||
| 35 | //Three Way Toggle Init | |
| 36 | #define TOGGLE_PIN A1 | |
| 37 | int previousState; | |
| 38 | bool aToggled; | |
| 39 | ||
| 40 | //Rotary Encoder Push Button Pins | |
| 41 | - | int EncoderPin4 = 9; |
| 41 | + | // *further buttons added must increment after these (these are 0,1,2) (buttons 1,2 and 3 on controller) |
| 42 | - | int EncoderPin5 = 10; |
| 42 | + | |
| 43 | ||
| 44 | //Set Toggle Positions as Buttons* (buttons start at 0,1,2,3,4,5 for 6 buttons) | |
| 45 | int ToggleButton1 = 3; //button 4 on controller | |
| 46 | int ToggleButton2 = 4; //button 5 on controller | |
| 47 | int ToggleButton3 = 5; //button 6 on controller | |
| 48 | ||
| 49 | //Rotary Encoder Interrupt Pins | |
| 50 | int EncoderPin0 = 0; | |
| 51 | int EncoderPin1 = 1; | |
| 52 | int EncoderPin2 = 2; | |
| 53 | int EncoderPin3 = 3; | |
| 54 | int EncoderPin4 = 9; //*Must have board with 6 total interrupt pins | |
| 55 | int EncoderPin5 = 10; //*Must have board with 6 total interrupt pins | |
| 56 | ||
| 57 | //Tell the Encoder Library which pins have encoders | |
| 58 | Encoder axisXRotation(EncoderPin0, EncoderPin1); | |
| 59 | - | //Set generic joystick with id 42 with 3 buttons and 3 axes |
| 59 | + | Encoder axisYRotation(EncoderPin2, EncoderPin3); |
| 60 | Encoder axisZRotation(EncoderPin4, EncoderPin5); | |
| 61 | - | 0x04, 3, 0, |
| 61 | + | |
| 62 | //Delay Time between loops | |
| 63 | int debounceDelay = 260; | |
| 64 | ||
| 65 | //Delay Time before button release | |
| 66 | int toggleDebounce = 10; | |
| 67 | ||
| 68 | - | //Set Encoder Pins as Pullups |
| 68 | + | |
| 69 | - | pinMode(EncoderPin0, INPUT_PULLUP); |
| 69 | + | |
| 70 | - | pinMode(EncoderPin1, INPUT_PULLUP); |
| 70 | + | |
| 71 | - | pinMode(EncoderPin2, INPUT_PULLUP); |
| 71 | + | |
| 72 | - | pinMode(EncoderPin3, INPUT_PULLUP); |
| 72 | + | //Set generic joystick with id 42 with 6 buttons and 3 axes |
| 73 | - | pinMode(EncoderPin4, INPUT_PULLUP); |
| 73 | + | |
| 74 | - | pinMode(EncoderPin5, INPUT_PULLUP); |
| 74 | + | 0x04, 6, 0, |
| 75 | false, false, false, true, true, true, | |
| 76 | false, false, false, false, false); | |
| 77 | - | for(int x = 0; x < sizeof(buttonArray); x++) {
|
| 77 | + | |
| 78 | //Variables to compare current to old values | |
| 79 | int oldX = 0; | |
| 80 | int oldY = 0; | |
| 81 | int oldZ = 0; | |
| 82 | int RxAxis_Value = 1; | |
| 83 | int RyAxis_Value = 1; | |
| 84 | int RzAxis_Value = 1; | |
| 85 | ||
| 86 | ||
| 87 | //Function to translate Three-way Toggle Analog Value | |
| 88 | int getToggleState(int aVal) {
| |
| 89 | if (aVal < 100) {
| |
| 90 | aVal = ToggleButton1; | |
| 91 | }else if (aVal < 900) {
| |
| 92 | aVal = ToggleButton3; | |
| 93 | }else{
| |
| 94 | aVal = ToggleButton2; | |
| 95 | } | |
| 96 | return aVal; | |
| 97 | } | |
| 98 | ||
| 99 | //Function to set Rotation value adjusted for the turning speed | |
| 100 | int speedVal(int dif, int val, int dir) {
| |
| 101 | int increment = 1; | |
| 102 | if (dif >= WarpSpeed) {
| |
| 103 | increment = WarpSpeed; | |
| 104 | }else if (dif >= JumpSpeed) {
| |
| 105 | increment = JumpSpeed; | |
| 106 | } | |
| 107 | if (dir == 1) {
| |
| 108 | val = val + increment; | |
| 109 | }else{
| |
| 110 | val = val - increment; | |
| 111 | } | |
| 112 | //Correct Rotation within 360 deg. | |
| 113 | if (val < 0) {
| |
| 114 | val = val + 360; | |
| 115 | }else if (val >= 360) {
| |
| 116 | val = val - 360; | |
| 117 | } | |
| 118 | return val; | |
| 119 | } | |
| 120 | ||
| 121 | ||
| 122 | void setup() {
| |
| 123 | ||
| 124 | //Toggle Switch Setup | |
| 125 | previousState = 1000; | |
| 126 | aToggled = false; | |
| 127 | ||
| 128 | //Loop through Encoder Pins and set them as Pullups | |
| 129 | for (int x = 0; x < 6; x++) {
| |
| 130 | pinMode(EncoderPin[x], INPUT_PULLUP); | |
| 131 | } | |
| 132 | ||
| 133 | //Loop through buttons and set them as Pullups | |
| 134 | for (int x = 0; x < sizeof(buttonArray); x++) {
| |
| 135 | pinMode(buttonArray[x], INPUT_PULLUP); | |
| 136 | } | |
| 137 | ||
| 138 | //Set Range of custom Axes | |
| 139 | Joystick.setRxAxisRange(0, 359); | |
| 140 | Joystick.setRyAxisRange(0, 359); | |
| 141 | Joystick.setRzAxisRange(0, 359); | |
| 142 | ||
| 143 | // Initialize Joystick Library | |
| 144 | Joystick.begin(false); | |
| 145 | ||
| 146 | } | |
| 147 | ||
| 148 | ||
| 149 | void loop() {
| |
| 150 | ||
| 151 | // Loop through button pin values & set to Joystick | |
| 152 | for (int x = 0; x < sizeof(buttonArray); x++) {
| |
| 153 | byte currentButtonState = !digitalRead(buttonArray[x]); | |
| 154 | Joystick.setButton(x, currentButtonState); | |
| 155 | } | |
| 156 | ||
| 157 | ||
| 158 | //Read Three Way Toggle | |
| 159 | int analogValue = analogRead(TOGGLE_PIN); | |
| 160 | int actualState = getToggleState(analogValue); | |
| 161 | if (previousState != actualState) {
| |
| 162 | //Set Toggle Switch input as Button Press | |
| 163 | Joystick.setButton(actualState, 1); | |
| 164 | previousState = actualState; | |
| 165 | aToggled = true; | |
| 166 | ||
| 167 | }else{
| |
| 168 | - | int speedVal(int dif, int val, int dir){
|
| 168 | + | //Reset button(s) to unpressed state |
| 169 | if (aToggled) {
| |
| 170 | - | if (dir == 1) {
|
| 170 | + | aToggled = false; |
| 171 | - | val = val + WarpSpeed; |
| 171 | + | delay (toggleDebounce); |
| 172 | - | }else{
|
| 172 | + | for (int a = 3; a < 6; a++) {
|
| 173 | - | val = val - WarpSpeed; |
| 173 | + | Joystick.setButton(a, 0); |
| 174 | } | |
| 175 | } | |
| 176 | - | if (dir == 1) {
|
| 176 | + | |
| 177 | - | val = val + JumpSpeed; |
| 177 | + | |
| 178 | - | }else{
|
| 178 | + | |
| 179 | - | val = val - JumpSpeed; |
| 179 | + | |
| 180 | int newX = axisXRotation.read(); | |
| 181 | if (newX > oldX) {
| |
| 182 | - | if (dir == 1) {
|
| 182 | + | |
| 183 | - | val = val + 1; |
| 183 | + | |
| 184 | - | }else{
|
| 184 | + | |
| 185 | - | val = val - 1; |
| 185 | + | |
| 186 | axisXRotation.write(newX); | |
| 187 | oldX = newX; | |
| 188 | ||
| 189 | }else if (newX < oldX) {
| |
| 190 | //Determine speed of decrement & set output | |
| 191 | int difX = oldX - newX; | |
| 192 | RxAxis_Value = speedVal(difX, RxAxis_Value, 0); | |
| 193 | Joystick.setRxAxis(RxAxis_Value); | |
| 194 | axisXRotation.write(newX); | |
| 195 | oldX = newX; | |
| 196 | } | |
| 197 | ||
| 198 | ||
| 199 | // Read "Course" Y Axis Rotation Encoder Knob | |
| 200 | int newY = axisYRotation.read(); | |
| 201 | if (newY > oldY) {
| |
| 202 | //Determine speed of increment & set output | |
| 203 | int difY = newY - oldY; | |
| 204 | RyAxis_Value = speedVal(difY, RyAxis_Value, 1); | |
| 205 | Joystick.setRyAxis(RyAxis_Value); | |
| 206 | axisYRotation.write(newY); | |
| 207 | oldY = newY; | |
| 208 | ||
| 209 | }else if (newY < oldY) {
| |
| 210 | //Determine speed of decrement & set output | |
| 211 | int difY = oldY - newY; | |
| 212 | RyAxis_Value = speedVal(difY, RyAxis_Value, 0); | |
| 213 | Joystick.setRyAxis(RyAxis_Value); | |
| 214 | axisYRotation.write(newY); | |
| 215 | oldY = newY; | |
| 216 | } | |
| 217 | ||
| 218 | ||
| 219 | // Read "QNH" Z Axis Rotation Encoder Knob | |
| 220 | int newZ = axisZRotation.read(); | |
| 221 | if (newZ > oldZ) {
| |
| 222 | //Determine speed of increment & set output | |
| 223 | int difZ = newZ - oldZ; | |
| 224 | RzAxis_Value = speedVal(difZ, RzAxis_Value, 1); | |
| 225 | Joystick.setRzAxis(RzAxis_Value); | |
| 226 | axisZRotation.write(newZ); | |
| 227 | oldZ = newZ; | |
| 228 | ||
| 229 | }else if (newZ < oldZ) {
| |
| 230 | //Determine speed of decrement & set output | |
| 231 | int difZ = oldZ - newZ; | |
| 232 | RzAxis_Value = speedVal(difZ, RzAxis_Value, 0); | |
| 233 | Joystick.setRzAxis(RzAxis_Value); | |
| 234 | axisZRotation.write(newZ); | |
| 235 | oldZ = newZ; | |
| 236 | } | |
| 237 | ||
| 238 | ||
| 239 | //Send Joystick info through USB | |
| 240 | Joystick.sendState(); | |
| 241 | delay(debounceDelay); | |
| 242 | } |