You're welcome!
Adding a third rotation axis is super simple, the joystick library actually has 3 rotation axes and we've only used 2 of them. It's just a matter of adding in that Z axis in the same way we handle the X and Y, and wiring it up to a pair of Interrupt Pins, and it's button to the buttons pin array. Adding a 3-way toggle switch should work just fine as buttons, but I don't have an example I can mash in right now, and so I'll have to look into it tomorrow or this weekend, but I'm sure I can toss something together for you.
You will want to learn how to wire up that 3-way switch and run an example sketch to test it, here's a simple lesson for that - his pics could be better, but you'll get the idea - I can't help you with your wiring, so you'll need to work through this to learn where to wire the resistors, ground, etc. : http://www.lucadentella.it/en/2014/08/01/interruttore-a-tre-posizioni-e-arduino/
For now, I have an example for you with the 3rd rotary encoder (Z axis), look it over and you'll see what I did to add it, it's pretty easy even for a novice because it's literally a copy of X and Y.
It does matter what board you are using, this is working example with all three rotary encoders, but not the 3-way switch yet -- this sketch assumes that on your board the 9 & 10 pins are Interrupt pins (refer to the pinout for your board if this sketch doesn't work out of the box). I didn't test it, so you can do that. https://pastebin.com/gEWNgm83
(click to reveal)
/* Modified HSI Knobs Sketch for Falcon BMS / DCS / FSX
* with additional 3rd Rotary Encoder (Z Axis)
* *(coming next: a 3-way Toggle Switch add-on)
* for Arduino Micro/Leonardo / Sparkfun Pro Micro or equiv. clones
* by SemlerPDX Aug2019
* VETERANS-GAMING.COM
* ( in response to reply at:
* http://veterans-gaming.com/index.php?/blogs/entry/32-diy-custom-game-controller-2-dial-hsi-course-and-heading-knobs/ )
*
* 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)
*
* Encoder Library
* http://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>
//Tell the Encoder Library which pins have encoders
Encoder axisXRotation(0, 1);
Encoder axisYRotation(2, 3);
Encoder axisZRotation(9, 10);
//Rotary Encoder Push Button Pins
int buttonArray[3] = {15, 6, 7};
//Rotary Encoder Interrupt Pins
int EncoderPin0 = 0;
int EncoderPin1 = 1;
int EncoderPin2 = 2;
int EncoderPin3 = 3;
int EncoderPin4 = 9;
int EncoderPin5 = 10;
//Delay Time between loops
int debounceDelay = 260;
//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;
//Intervals for Jump/Warp Speed Rotations
int JumpSpeed = 18;
int WarpSpeed = 30;
//Set generic joystick with id 42 with 3 buttons and 3 axes
Joystick_ Joystick(0x42,
0x04, 3, 0,
false, false, false, true, true, true,
false, false, false, false, false);
void setup() {
//Set Encoder Pins as Pullups
pinMode(EncoderPin0, INPUT_PULLUP);
pinMode(EncoderPin1, INPUT_PULLUP);
pinMode(EncoderPin2, INPUT_PULLUP);
pinMode(EncoderPin3, INPUT_PULLUP);
pinMode(EncoderPin4, INPUT_PULLUP);
pinMode(EncoderPin5, 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 "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);
}
//Function to set Rotation value adjusted for the turning speed
int speedVal(int dif, int val, int dir){
if (dif >= WarpSpeed) {
if (dir == 1) {
val = val + WarpSpeed;
}else{
val = val - WarpSpeed;
}
}else if (dif >= JumpSpeed) {
if (dir == 1) {
val = val + JumpSpeed;
}else{
val = val - JumpSpeed;
}
}else{
if (dir == 1) {
val = val + 1;
}else{
val = val - 1;
}
}
//Correct Rotation within 360 deg.
if (val < 0) {
val = val + 360;
}else if (val >= 360) {
val = val - 360;
}
return val;
}