Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Joystick.h>
- #include <jled.h>
- Joystick_ Joystick;
- enum PinAssigments { // rotary encoder pins
- encoderPinA = 2,
- encoderPinB = 3,
- };
- #define rotaryBtn 4 // rotary button pin
- static boolean rotating = false;
- boolean A_set = false;
- boolean B_set = false;
- volatile int rotationPos = 0;
- boolean isRotary = false;
- #define ap_buttons A3 // define the pin where the AP buttons are connected to
- // LED for testing
- int RXLED = 17; //RXLED is on Pin 17, TXLED can be called by using TXLED1 and TXLED0. RXLED is ON on LOW and OFF on HIGH!
- auto led = JLed(RXLED).Blink(500, 200).Forever();
- int rotary_mode_positive = 20; // standard button for rotary+
- int rotary_mode_negative = 21; // standard button for rotary-
- bool rotaryBtn_pressed = false;
- int rotary_apBtn = 99; // standard value of rotary_apBtn is set to 99 because it's not existant when pressing any button
- unsigned long startTime = 0;
- unsigned long endTime = 0;
- const int waitTime = 3000;
- int ap_currentbtn = 99;
- int ap_old_btn = 99;
- int ap_no_btn = 99;
- int ap_btn_pressed = 0;
- int ap_result = 0;
- void setup() {
- Serial.begin(9600); // serial monitor, comment out when not needed
- pinMode(ap_buttons, INPUT_PULLUP);
- pinMode(rotaryBtn, INPUT_PULLUP);
- pinMode(encoderPinA, INPUT);
- pinMode(encoderPinB, INPUT);
- digitalWrite(encoderPinA, HIGH);
- digitalWrite(encoderPinB, HIGH);
- attachInterrupt(0, doEncoderA, CHANGE);
- attachInterrupt(1, doEncoderB, CHANGE);
- digitalWrite(rotaryBtn, HIGH); // set initial button state for Rotary Button to HIGH
- Joystick.begin(); // begin Joystick library
- }
- void pinChange() {
- rotating = true;
- if ( rotationPos == -1 ) {
- Joystick.pressButton(rotary_mode_positive);
- delay(50);
- Joystick.releaseButton(rotary_mode_positive);
- rotationPos = 0;
- }
- if ( rotationPos == 1 ) {
- Joystick.pressButton(rotary_mode_negative);
- delay(50);
- Joystick.releaseButton(rotary_mode_negative);
- rotationPos = 0;
- }
- }
- int readButtons_ap(int pin_ap) {
- // function for understanding the buttons on analog pin A3 - this is for the AP panel
- // NOTE: The values for ap_result equals the button number of Joystick, beginning with 0!. Using 99 as "no button" is just because button 98 doesn't exist.
- // The ap_value values are the voltages reading on A3 caused by the voltage divider with the resistors on each button. To find out which voltages you have, flash button_tester first!
- int ap_value = analogRead(ap_buttons);
- if ( ap_value > 1000 ) {
- ap_result = 99;
- } else if ( ( ap_value >= 10 ) && ( ap_value < 20 ) ) { // if the value is between 10 and 20...
- ap_result = 0; // set the result to 0 (0 is the first button of Joystick!)
- } else if ( ( ap_value > 550 ) && ( ap_value < 560 ) ) {
- ap_result = 1;
- } else if ( ( ap_value > 717 ) && ( ap_value < 726 ) ) {
- ap_result = 2;
- } else if ( ( ap_value > 794 ) && ( ap_value < 804 ) ) {
- ap_result = 3;
- } else if ( ( ap_value > 840 ) && ( ap_value < 850 ) ) {
- ap_result = 4;
- } else if ( ( ap_value > 871 ) && ( ap_value < 881 ) ) {
- ap_result = 5;
- } else if ( ( ap_value > 892 ) && ( ap_value < 902 ) ) {
- ap_result = 6;
- } else if ( ( ap_value > 908 ) && ( ap_value < 918 ) ) {
- ap_result = 7;
- } else if ( ( ap_value > 920 ) && ( ap_value < 930 ) ) {
- ap_result = 8;
- } else if ( ( ap_value > 930 ) && ( ap_value < 940 ) ) {
- ap_result = 9;
- } else if ( ( ap_value > 940 ) && ( ap_value < 948 ) ) {
- ap_result = 10;
- } return ap_result; // return the result value
- }
- // Reading the pressed buttons on the AP panel and convert them to Joystick buttons
- void ap_panel() {
- ap_btn_pressed = readButtons_ap(11); // set the ap_ptn_pressed variable to the result from readButtons_ap
- if ( ap_btn_pressed != ap_old_btn ) { // if the value of ap_btn_pressed changed...
- Joystick.setButton(ap_btn_pressed, 1); // set the Joystick button (same number as ap_btn_pressed) to 1
- }
- if ( ap_btn_pressed < 99 ) { // if the value is smaller than 99 store the button value
- ap_currentbtn = ap_btn_pressed;
- } else if ( ap_btn_pressed == ap_no_btn ) { // if the button value is the same as ap_no_btn (99)...
- Joystick.releaseButton(ap_currentbtn); // ... release the last pressed button
- }
- ap_old_btn = ap_btn_pressed; // store previous value for the next loop
- }
- // Rotary encoder for changing AP settings. Stock are HDG, ALT, VS, CRS/NAV, SPD and BARO (read below for BARO).
- // The rotary encoder works like + and - buttons, turning it right triggers the Joystick button for + and left the Joystick button for -.
- // Pressing the rotary encoder will start a timer (defined by waitTime) to wait for input, after the timer the last value will be used again automatically.
- void rotary_mode() {
- startTime = millis(); // starting millis() timer
- rotary_apBtn = readButtons_ap(11);
- if ( ( digitalRead(rotaryBtn) == LOW ) && ( rotaryBtn_pressed == false ) ) { // if the rotary encoder button is pressed and wasn't before...
- rotaryBtn_pressed = true; // mark the button as pressed
- endTime = startTime; // start the timer
- }
- if ( ( rotaryBtn_pressed == true ) && ( startTime - endTime <= waitTime ) ) { // if the button was pressed and the time is below waitTime (stock 3000ms, 3sec)...
- led.Update(); // start the JLED Blinker, defined on top of this code
- isRotary = true;
- if ( rotary_apBtn == 2 ) { // read the pressed button from readButtons_ap
- rotary_mode_positive = 20; // and change the Joystick button for each rotary direction
- rotary_mode_negative = 21;
- digitalWrite(RXLED, HIGH);
- isRotary = false;
- } else if ( rotary_apBtn == 3 ) {
- rotary_mode_positive = 22;
- rotary_mode_negative = 23;
- digitalWrite(RXLED, HIGH);
- isRotary = false;
- } else if ( rotary_apBtn == 4 ) {
- rotary_mode_positive = 24;
- rotary_mode_negative = 25;
- digitalWrite(RXLED, HIGH);
- isRotary = false;
- } else if ( rotary_apBtn == 5 ) {
- rotary_mode_positive = 26;
- rotary_mode_negative = 27;
- digitalWrite(RXLED, HIGH);
- isRotary = false;
- } else if ( rotary_apBtn == 9 ) {
- rotary_mode_positive = 28;
- rotary_mode_negative = 29;
- digitalWrite(RXLED, HIGH);
- isRotary = false;
- } else if ( rotary_apBtn == 10 ) { // 10 is normally for FLC but used for BARO for testing instead!
- rotary_mode_positive = 30;
- rotary_mode_negative = 31;
- digitalWrite(RXLED, HIGH);
- isRotary = false;
- }
- }
- if ( isRotary == false ) {
- rotaryBtn_pressed = false;
- }
- if ( ( rotaryBtn_pressed == true ) && ( startTime - endTime >= waitTime ) ) { // if the button is marked as pressed and the waitTime is over, mark the button as unpressed again to stop the wait-for-input timer.
- rotaryBtn_pressed = false;
- isRotary = false;
- }
- }
- void loop() {
- rotary_mode();
- pinChange();
- ap_panel();
- delay(15); // small delay is needed
- }
- void doEncoderA() {
- // debounce
- if ( rotating ) delay (1); // wait a little until the bouncing is done
- // Test transition, did things really change?
- if ( digitalRead(encoderPinA) != A_set ) { // debounce once more
- A_set = !A_set;
- // adjust counter + if A leads B
- if ( A_set && !B_set )
- // encoderPos += 1;
- rotationPos = 1;
- rotating = false; // no more debouncing until loop() hits again
- }
- }
- // Interrupt on B changing state, same as A above
- void doEncoderB() {
- if ( rotating ) delay (1);
- if ( digitalRead(encoderPinB) != B_set ) {
- B_set = !B_set;
- // adjust counter - 1 if B leads A
- if ( B_set && !A_set )
- //encoderPos -= 1;
- rotationPos = -1;
- rotating = false;
- }
- }
RAW Paste Data
Copied