I have been trying to create a switch panel for MSFS 2020 on Xbox Series X by using an arduino due with a sensor shield v2.0 and a code that works like a keyboard with 53 imputs to assign a switch to bu connecting it to a pin e.g pin 0 = A.
So far i haven't had any luck with it working as the console doesnt even recognise it so i cant assign anything.
tips, tricks? anything will help, thx.
#include <LiquidCrystal_I2C.h>
/* ================= Logic =================
Input state Action
HIGH → LOW One character sent
Held LOW Nothing
LOW → HIGH Nothing
Next press One character sent
- No key repeat
- No stuck keys
- One clean character per press
*/
#include <Arduino.h>
#include <Keyboard.h>
#include <Joystick.h>
/* ================= CONFIG ================= */
#define NUM_DIO_PINS 54
#define NUM_ANALOG 12
#define DEBOUNCE_MS 25
#define ANALOG_SMOOTH_SAMPLES 8
/* ===== HAT SWITCH PIN ASSIGNMENTS ===== */
#define HAT_UP_PIN 36
#define HAT_RIGHT_PIN 37
#define HAT_DOWN_PIN 38
#define HAT_LEFT_PIN 39
/* ===== KEYBOARD MAP (D0–D53) ===== */
/* Hat pins are ignored in keyboard logic */
const uint8_t keyMap[NUM_DIO_PINS] = {
// D0–D9
'a','b','c','d','e','f','g','h','i','j',
// D10–D19
'k','l','m','n','o','p','q','r','s','t',
// D20–D29
'u','v','w','x','y','z','1','2','3','4',
// D30–D39
'5','6','7','8','9','0',
KEY_F1, KEY_F2, KEY_F3, KEY_F4,
// D40–D49
KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9,
KEY_F10, KEY_F11, KEY_F12,
KEY_ESC, KEY_TAB,
// D50–D53
'[',']',';','\''
};
/* ================= STATE ================= */
uint8_t dioStable[NUM_DIO_PINS];
uint8_t dioLastRead[NUM_DIO_PINS];
uint32_t dioLastChange[NUM_DIO_PINS];
uint16_t analogBuf[NUM_ANALOG][ANALOG_SMOOTH_SAMPLES];
uint8_t analogIdx[NUM_ANALOG];
/* ================= JOYSTICK ================= */
Joystick_ Joystick(
JOYSTICK_DEFAULT_REPORT_ID,
JOYSTICK_TYPE_JOYSTICK,
0, // no joystick buttons
1, // ONE hat switch
true, true, true, true, true, true, true, true
);
/* ================= UTILS ================= */
bool isHatPin(uint8_t pin) {
return (pin == HAT_UP_PIN ||
pin == HAT_RIGHT_PIN ||
pin == HAT_DOWN_PIN ||
pin == HAT_LEFT_PIN);
}
/* ================= SETUP ================= */
void setup() {
for (int i = 0; i < NUM_DIO_PINS; i++) {
pinMode(i, INPUT_PULLUP);
dioStable[i] = digitalRead(i);
dioLastRead[i] = dioStable[i];
dioLastChange[i] = millis();
}
for (int i = 0; i < NUM_ANALOG; i++) {
for (int j = 0; j < ANALOG_SMOOTH_SAMPLES; j++)
analogBuf[i][j] = analogRead(A0 + i);
analogIdx[i] = 0;
}
Keyboard.begin();
Joystick.begin();
}
/* ================= LOOP ================= */
void loop() {
handleDigitalInputs();
handleHatSwitch();
handleAnalogInputs();
delay(1);
}
/* ================= DIGITAL INPUTS ================= */
void handleDigitalInputs() {
uint32_t now = millis();
for (int pin = 0; pin < NUM_DIO_PINS; pin++) {
uint8_t r = digitalRead(pin);
if (r != dioLastRead[pin]) {
dioLastRead[pin] = r;
dioLastChange[pin] = now;
}
if ((now - dioLastChange[pin]) > DEBOUNCE_MS) {
if (r != dioStable[pin]) {
// Store previous stable state
int prev = dioStable[pin];
dioStable[pin] = r;
if (!isHatPin(pin)) {
// Send character ONCE per HIGH -> LOW cycle
if (prev == HIGH && r == LOW) {
Keyboard.write(keyMap[pin]);
}
}
}
}
}
}
/* ================= HAT SWITCH ================= */
void handleHatSwitch() {
bool up = digitalRead(HAT_UP_PIN) == LOW;
bool right = digitalRead(HAT_RIGHT_PIN) == LOW;
bool down = digitalRead(HAT_DOWN_PIN) == LOW;
bool left = digitalRead(HAT_LEFT_PIN) == LOW;
uint8_t hat = 8; // Neutral
if (up && right) hat = 1;
else if (right && down) hat = 3;
else if (down && left) hat = 5;
else if (left && up) hat = 7;
else if (up) hat = 0;
else if (right) hat = 2;
else if (down) hat = 4;
else if (left) hat = 6;
Joystick.setHatSwitch(0, hat);
}
/* ================= ANALOG INPUTS ================= */
uint16_t smoothAnalog(uint8_t ch) {
analogBuf[ch][analogIdx[ch]] = analogRead(A0 + ch);
analogIdx[ch] = (analogIdx[ch] + 1) % ANALOG_SMOOTH_SAMPLES;
uint32_t sum = 0;
for (int i = 0; i < ANALOG_SMOOTH_SAMPLES; i++)
sum += analogBuf[ch][i];
return sum / ANALOG_SMOOTH_SAMPLES;
}
void handleAnalogInputs() {
int16_t axis[8];
for (int i = 0; i < 8; i++) {
axis[i] = map(
smoothAnalog(i),
0, 4095,
-32768, 32767
);
}
Joystick.setXAxis(axis[0]);
Joystick.setYAxis(axis[1]);
Joystick.setZAxis(axis[2]);
Joystick.setRxAxis(axis[3]);
Joystick.setRyAxis(axis[4]);
Joystick.setRzAxis(axis[5]);
Joystick.setThrottle(axis[6]);
Joystick.setRudder(axis[7]);
}