Guest User

Untitled

a guest
Oct 2nd, 2020
48
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <Joystick.h>
  2. #include <jled.h>
  3.  
  4. Joystick_ Joystick;
  5.  
  6.  
  7.  
  8. enum PinAssigments { // rotary encoder pins
  9.   encoderPinA = 2,
  10.   encoderPinB = 3,
  11.  
  12. };
  13. #define rotaryBtn 4 // rotary button pin
  14.  
  15.  
  16. static boolean rotating = false;
  17. boolean A_set = false;
  18. boolean B_set = false;
  19. volatile int rotationPos = 0;
  20.  
  21. boolean isRotary = false;
  22.  
  23. #define ap_buttons A3 // define the pin where the AP buttons are connected to
  24.  
  25. // LED for testing
  26. 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!
  27. auto led = JLed(RXLED).Blink(500, 200).Forever();
  28.  
  29. int rotary_mode_positive = 20; // standard button for rotary+
  30. int rotary_mode_negative = 21; // standard button for rotary-
  31. bool rotaryBtn_pressed = false;
  32. int rotary_apBtn = 99; // standard value of rotary_apBtn is set to 99 because it's not existant when pressing any button
  33.  
  34. unsigned long startTime = 0;
  35. unsigned long endTime = 0;
  36. const int waitTime = 3000;
  37.  
  38. int ap_currentbtn = 99;
  39. int ap_old_btn = 99;
  40. int ap_no_btn = 99;
  41. int ap_btn_pressed = 0;
  42. int ap_result = 0;
  43.  
  44. void setup() {
  45.   Serial.begin(9600); // serial monitor, comment out when not needed
  46.   pinMode(ap_buttons, INPUT_PULLUP);
  47.   pinMode(rotaryBtn, INPUT_PULLUP);
  48.   pinMode(encoderPinA, INPUT);
  49.   pinMode(encoderPinB, INPUT);
  50.   digitalWrite(encoderPinA, HIGH);
  51.   digitalWrite(encoderPinB, HIGH);
  52.   attachInterrupt(0, doEncoderA, CHANGE);
  53.   attachInterrupt(1, doEncoderB, CHANGE);
  54.  
  55.   digitalWrite(rotaryBtn, HIGH); // set initial button state for Rotary Button to HIGH
  56.   Joystick.begin(); // begin Joystick library
  57.  
  58. }
  59.  
  60. void pinChange() {
  61.   rotating = true;
  62.  
  63.   if ( rotationPos == -1 ) {
  64.     Joystick.pressButton(rotary_mode_positive);
  65.     delay(50);
  66.     Joystick.releaseButton(rotary_mode_positive);
  67.     rotationPos = 0;
  68.   }
  69.   if ( rotationPos == 1 ) {
  70.     Joystick.pressButton(rotary_mode_negative);
  71.     delay(50);
  72.     Joystick.releaseButton(rotary_mode_negative);
  73.     rotationPos = 0;
  74.   }
  75. }
  76.  
  77. int readButtons_ap(int pin_ap) {
  78.   // function for understanding the buttons on analog pin A3 -  this is for the AP panel
  79.   // 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.
  80.   // 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!
  81.   int ap_value = analogRead(ap_buttons);
  82.  
  83.   if ( ap_value > 1000 ) {
  84.     ap_result = 99;
  85.   } else if ( ( ap_value >= 10 ) && ( ap_value < 20 ) ) { // if the value is between 10 and 20...
  86.     ap_result = 0;  // set the result to 0 (0 is the first button of Joystick!)
  87.  
  88.   } else if ( ( ap_value > 550 ) && ( ap_value < 560 ) ) {
  89.     ap_result = 1;
  90.      
  91.   } else if ( ( ap_value > 717 ) && ( ap_value < 726 ) ) {
  92.     ap_result = 2;
  93.      
  94.   } else if ( ( ap_value > 794 ) && ( ap_value < 804 ) ) {
  95.     ap_result = 3;
  96.      
  97.   } else if ( ( ap_value > 840 ) && ( ap_value < 850 ) ) {
  98.     ap_result = 4;
  99.    
  100.   } else if ( ( ap_value > 871 ) && ( ap_value < 881 ) ) {
  101.     ap_result = 5;
  102.          
  103.   } else if ( ( ap_value > 892 ) && ( ap_value < 902 ) ) {
  104.     ap_result = 6;
  105.    
  106.   } else if ( ( ap_value > 908 ) && ( ap_value < 918 ) ) {
  107.     ap_result = 7;
  108.  
  109.   } else if ( ( ap_value > 920 ) && ( ap_value < 930 ) ) {
  110.     ap_result = 8;
  111.  
  112.   } else if ( ( ap_value > 930 ) && ( ap_value < 940 ) ) {
  113.     ap_result = 9;
  114.  
  115.   } else if ( ( ap_value > 940 ) && ( ap_value < 948 ) ) {
  116.     ap_result = 10;
  117.  
  118.    
  119.   } return ap_result; // return the result value
  120. }
  121.  
  122. // Reading the pressed buttons on the AP panel and convert them to Joystick buttons
  123. void ap_panel() {
  124.   ap_btn_pressed = readButtons_ap(11); // set the ap_ptn_pressed variable to the result from readButtons_ap
  125.  
  126.   if ( ap_btn_pressed != ap_old_btn ) { // if the value of ap_btn_pressed changed...
  127.      Joystick.setButton(ap_btn_pressed, 1); // set the Joystick button (same number as ap_btn_pressed) to 1
  128.     }
  129.     if ( ap_btn_pressed < 99 ) { // if the value is smaller than 99 store the button value
  130.       ap_currentbtn = ap_btn_pressed;
  131.     } else if ( ap_btn_pressed == ap_no_btn ) { // if the button value is the same as ap_no_btn (99)...
  132.     Joystick.releaseButton(ap_currentbtn); // ... release the last pressed button
  133.   }
  134.   ap_old_btn = ap_btn_pressed; // store previous value for the next loop
  135. }
  136.  
  137. // Rotary encoder for changing AP settings. Stock are HDG, ALT, VS, CRS/NAV, SPD and BARO (read below for BARO).
  138. // The rotary encoder works like + and - buttons, turning it right triggers the Joystick button for + and left the Joystick button for -.
  139. // 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.
  140. void rotary_mode() {
  141.   startTime = millis(); // starting millis() timer
  142.   rotary_apBtn = readButtons_ap(11);
  143.   if ( ( digitalRead(rotaryBtn) == LOW ) && ( rotaryBtn_pressed == false ) ) {  // if the rotary encoder button is pressed and wasn't before...
  144.     rotaryBtn_pressed = true; // mark the button as pressed
  145.     endTime = startTime; // start the timer
  146.  
  147.   }
  148.  
  149.   if ( ( rotaryBtn_pressed == true ) && ( startTime - endTime <= waitTime ) ) { // if the button was pressed and the time is below waitTime (stock 3000ms, 3sec)...
  150.       led.Update(); // start the JLED Blinker, defined on top of this code
  151.       isRotary = true;
  152.     if ( rotary_apBtn == 2 ) { // read the pressed button from readButtons_ap
  153.       rotary_mode_positive = 20; // and change the Joystick button for each rotary direction
  154.       rotary_mode_negative = 21;
  155.       digitalWrite(RXLED, HIGH);
  156.       isRotary = false;
  157.       } else if ( rotary_apBtn == 3 ) {
  158.         rotary_mode_positive = 22;
  159.         rotary_mode_negative = 23;
  160.         digitalWrite(RXLED, HIGH);
  161.         isRotary = false;
  162.        } else if ( rotary_apBtn == 4 ) {
  163.         rotary_mode_positive = 24;
  164.         rotary_mode_negative = 25;
  165.         digitalWrite(RXLED, HIGH);
  166.         isRotary = false;
  167.        } else if ( rotary_apBtn == 5 ) {
  168.         rotary_mode_positive = 26;
  169.         rotary_mode_negative = 27;
  170.         digitalWrite(RXLED, HIGH);
  171.         isRotary = false;
  172.       } else if ( rotary_apBtn == 9 ) {
  173.         rotary_mode_positive = 28;
  174.         rotary_mode_negative = 29;
  175.         digitalWrite(RXLED, HIGH);
  176.         isRotary = false;
  177.       } else if ( rotary_apBtn == 10 ) { // 10 is normally for FLC but used for BARO for testing instead!
  178.         rotary_mode_positive = 30;
  179.         rotary_mode_negative = 31;
  180.         digitalWrite(RXLED, HIGH);
  181.         isRotary = false;
  182.       }  
  183.        
  184.   }
  185.   if ( isRotary == false ) {
  186.     rotaryBtn_pressed = false;
  187.   }
  188.   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.
  189.      rotaryBtn_pressed = false;    
  190.      isRotary = false;
  191.      }  
  192. }
  193.  
  194. void loop() {
  195.   rotary_mode();
  196.   pinChange();
  197.   ap_panel();
  198.  
  199.   delay(15); // small delay is needed
  200.  
  201. }
  202.  
  203.  
  204.  
  205. void doEncoderA() {
  206.   // debounce
  207.   if ( rotating ) delay (1);  // wait a little until the bouncing is done
  208.  
  209.   // Test transition, did things really change?
  210.   if ( digitalRead(encoderPinA) != A_set ) { // debounce once more
  211.     A_set = !A_set;
  212.  
  213.     // adjust counter + if A leads B
  214.     if ( A_set && !B_set )
  215.       // encoderPos += 1;
  216.       rotationPos = 1;
  217.  
  218.     rotating = false;  // no more debouncing until loop() hits again
  219.   }
  220. }
  221.  
  222. // Interrupt on B changing state, same as A above
  223. void doEncoderB() {
  224.   if ( rotating ) delay (1);
  225.   if ( digitalRead(encoderPinB) != B_set ) {
  226.     B_set = !B_set;
  227.     //  adjust counter - 1 if B leads A
  228.     if ( B_set && !A_set )
  229.       //encoderPos -= 1;
  230.       rotationPos = -1;
  231.  
  232.     rotating = false;
  233.   }
  234. }
RAW Paste Data Copied