Results 1 to 9 of 9
  1. #1
    75+ Posting Member
    Join Date
    Nov 2011
    Location
    UK
    Posts
    77
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Can't figure this out!

    Hey guys, really struggling to figure this out.

    I have been focusing on getting all my coding for my extractions figures out. I have done my gear and my flaps. See here https://www.youtube.com/watch?v=pdEKTgIFn5s

    I am working on a GA cockpit so only have around 34ish LED's to light. Other than warning annunciators most of them are associated with a button or switch press for example start light, NAV1 ident or autopilot master. I am really struggling to figure it out. I thought I would start with just 1 button. So I am testing with a nano board with a push button in pin 2 and a LED in pin 5. I have adapted Jim's lights code. What happens is the push button works when it feels like it (I've tested it with other scripts so I'm sure its not a dud). So when I select it with the mouse the led comes on but when I switch it off the LED stays on until I switch it on and then off again.

    Here is the code I am using if anyone has any thoughts I would be most grateful.

    Code:
    int CodeIn;// used on all serial reads
    int KpinNo; 
    int Koutpin;
    
    
    String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
    
    
    void setup() {
     Kstringoldstate = "1111111111111111111111111111111111111111111111111111111111111";
      
      for (int KoutPin = 2; KoutPin < 4; KoutPin++)
     {
        pinMode(KoutPin, INPUT);
        digitalWrite(KoutPin, HIGH);  
      }
    
    
      {
        pinMode(5, OUTPUT);
       
      }
      
     Serial.begin(115200);   
    }
    
    
    void loop() {
     {KEYS();} //Check the "keys" section
      if (Serial.available()) {
        CodeIn = getChar();
         if (CodeIn == '=') {EQUALS();} // The first identifier is "="
    
    
    }
    }
    
    
    char getChar()// Get a character from the serial buffer
    {
      while(Serial.available() == 0);// wait for data
      return((char)Serial.read());// Thanks Doug
    }
    
    
    void EQUALS(){    // The first identifier was "<"
    CodeIn = getChar(); // Get another character
      switch(CodeIn) {// Now lets find what to do with it
        case 'P':
        for (int KpinNo = 5; KpinNo <10; KpinNo++){//The 10 LED's to indicate lights status
        int start = getChar();
          if (start == '1'){digitalWrite(KpinNo, HIGH);}else{digitalWrite(KpinNo, LOW);} 
        }   
         }
    }
    void KEYS() 
    {
      Kstringnewstate = "";
      for (int KpinNo = 2; KpinNo < 5; KpinNo++){
        KpinStateSTR = String(digitalRead(KpinNo)); 
        KoldpinStateSTR = String(Kstringoldstate.charAt(KpinNo - 2));
        if (KpinStateSTR != KoldpinStateSTR)
        {
          if (KpinNo == 2){if (KpinStateSTR == "1" ){Serial.println ("A48");}
         
        }
        Kstringnewstate += KpinStateSTR;
      }
      Kstringoldstate = Kstringnewstate;
      }
    }

  2. Dislikes SimSupervisor disliked this post
  3. #2
    75+ Posting Member
    Join Date
    Aug 2015
    Location
    Montreal
    Posts
    106
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Can't figure this out!

    If your light state change only when pressing the button, not when unpressing it, then you are not handling your states right. But I am not sure I understand what it is you are trying to do with this code...
    Why do you keep state of your objects in strings? Have you ever learned about booleans? Arrays? it sure would make your code more legible, and likely easier to debug. Just saying.

    That being said, if the button only works from time to time, you might have to debounce it.



    you are reading leds on Link2FS input =Pxxx - ain't that the input value for NAV Sound Active?

    Your code talks about 10 leds, but you start at 5. You do know that it won't skip 5 characters, and your index 5 will be the first of the train of characters, right?

    You are comparing your new state at index KpinNo with the old state at index (KpinNo - 2) - this is NOT the same index, so NOT the same state - what is the relation between KpinNo and (KpinNo - 2)? I trust you know what you are doing, but to me this makes little sense for a comparison. Straight here could cause your issue of working once every two times.

    Is your LED being set by the flight sim software and received by serial? That why you send A48 to the software? A48 is "toggle NavId" - this is a toggle. If you send it when you press, it will change state. If you want it to change state again when you release the button, then you need to send A48 again for that event. I see you only do it when kPinStateSte == "1" - so only when its ON. When will it toggle back to off?



    I notice you sometimes put your brackets at the end of the line, sometimes at the beginning of the next line. You should decide what coding standard you want to use, and use only that; it makes the code a lot more readable... unreadable code is undebugable. Just saying.

  4. #3
    150+ Forum Groupie
    Join Date
    Nov 2013
    Location
    Evansville, Indiana
    Posts
    243
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Can't figure this out!

    Marc1980,

    Don't use Pin 2.
    On the Nano, it is used in the USB communication with the computer.

    Regarding your Switch Case...
    But first up at the top with variable declarations...
    Add this line.
    Code:
    String Digit;
    Then down in the switch case....

    Code:
    case 'P':    // For NAV1 sound active
            Digit = "";
            Digit += getChar(); 
            if (Digit == "1")
            {
                digitalWrite(5, HIGH);
            }
            else
            {
                digitalWrite(5, LOW);
            }
     break;
    
    case 'M':    //For COM1 sound active
                    Digit = "";
            Digit += getChar(); 
            if (Digit == "1")
            {
                digitalWrite(6, HIGH);  //Assuming you use pin 6 for that LED
            }
            else
            {
                digitalWrite(6, LOW);
            }
      break;
    Then Rinse repeat...



    ~Fess
    I will only ever be, half the Geek that I wished I was.
    TheGeekForge.Com

  5. #4
    75+ Posting Member
    Join Date
    Nov 2011
    Location
    UK
    Posts
    77
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Can't figure this out!

    Thanks guys for taking the time to respond. To be honest I have very little clue what I am doing. I have only been playing with arduino and link2fs for a short time so am still trying to get my head around some of the basics, so I need all the help I can get.

    What is it I am trying to do? Using switches & buttons, send commands to FSX and get an LED to light up. Most of the LED's I need can be handles through the extractions.

    Am I right in thinking that you cannot use the same code for a switch and a button because of the different way in which they work.

    Looking at the Simconnect inputs I will probably se switches as on/off commands and use buttons as toggle commands.

    With the code I am unsure as to what it all means.

    Code:
    String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
    - I am thinking this is used to compare states but am not sure how it works and how I should use it.

    Code:
    for (int KoutPin = 22; KoutPin < 70; KoutPin++)// Get these pins ready as inputs 
    {
    pinMode(KoutPin, INPUT);
    digitalWrite(KoutPin, HIGH);
    Does this mean that from pin 22 and all pins less that 70 will be set up as inputs?

    In the void keys section here

    Code:
      Kstringnewstate = "";
      for (int KpinNo = 2; KpinNo < 5; KpinNo++){
        KpinStateSTR = String(digitalRead(KpinNo)); 
        KoldpinStateSTR = String(Kstringoldstate.charAt(KpinNo - 2));
        if (KpinStateSTR != KoldpinStateSTR)
    I'm not sure what is happening here, what is being compared to what?
    What is a string used for?

    I understand that I have a lot of questions. If you have time to answer that would be great, if not perhaps you know of some learning resources. I have looked on the arduino website and it helps...a bit.

    Kind regards
    Marc

  6. #5
    150+ Forum Groupie


    BushPilotWannabe's Avatar
    Join Date
    Jan 2014
    Location
    Alberta, Canada
    Posts
    176
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Can't figure this out!

    Thanks guys for taking the time to respond. To be honest I have very little clue what I am doing. I have only been playing with arduino and link2fs for a short time so am still trying to get my head around some of the basics, so I need all the help I can get.

    What is it I am trying to do? Using switches & buttons, send commands to FSX and get an LED to light up. Most of the LED's I need can be handles through the extractions.

    Am I right in thinking that you cannot use the same code for a switch and a button because of the different way in which they work.

    Looking at the Simconnect inputs I will probably se switches as on/off commands and use buttons as toggle commands.

    With the code I am unsure as to what it all means.

    Code:
    String KoldpinStateSTR, KpinStateSTR,  Kstringnewstate,Kstringoldstate;
    - I am thinking this is used to compare states but am not sure how it works and how I should use it.

    Kstringnewstate This is a register in string form records the pin level (+or-) of scanned pins on THIS pass through the function. It starts empty "=" and adds one character with every pin scanned.

    Kstringoldstate This is a register in string form that recorded the pin level (+or-) of scanned pins on the LAST pass through the function.

    KpinStateSTR This is the pin level (+or-) of the current scanned pin in string (or "char" if you must) form. It must be in this form to compare to the corresponding character of the string register in order to determine change in pin level.

    KoldpinStateSTR This is the character extracted from Kstringoldstate which holds the pin level of the pin being scanned on the last pass.

    Don't confuse the physical pin numbers which start at "1" with the chip pin description eg A6 or D9 which start with 0 (zero). Don't use physical pins 1 & 2 which are D0 & D1. Read the Arduino Nano data sheet at least once.

    Code:
    for (int KoutPin = 22; KoutPin < 70; KoutPin++)// Get these pins ready as inputs 
    {
    pinMode(KoutPin, INPUT);
    digitalWrite(KoutPin, HIGH);
    Does this mean that from pin 22 and all pins less that 70 will be set up as inputs?

    Yup! But this applies to the Arduino MEGA. The Arduino Nano only goes up to digital pin D19 (A5). A6 & A7 are analog input only. I think I had confirmed this. This is no problem. Treat the analog input as digital. Digital LOW = analogRead(pin) <150 and digital HIGH = analogRead(pin) > 875.


    In the void keys section here

    1
    Code:
      Kstringnewstate = "";
    2   for (int KpinNo = 2; KpinNo < 5; KpinNo++){
    3   KpinStateSTR = String(digitalRead(KpinNo)); 
    4   KoldpinStateSTR = String(Kstringoldstate.charAt(KpinNo - 2));
    5   if (KpinStateSTR != KoldpinStateSTR)
    I'm not sure what is happening here, what is being compared to what?
    What is a string used for?


    Simple registers are 8 to 32 bits long, limited by the hosting computers. Somebody says the Mac can use 64 bits. And you need 68 bits to archive all digital pins on the MEGA so Jim.NZ used strings which without manipulation can be up to 255 or 256 characters long.


    line 1. Make sure the string is empty when you start
    line 2. The KEYS function is tasked with looking at digital pins D2 through D4 individually in a loop.
    line 3. Read the level of the pin and convert it into String form (char)
    line 4. Extract the archived level of the pin being scanned from the OLD register of scanned pins. The tricky bit is that the first char of a string is char(0) and you begin scanning with digital pin D2 (counter value 2). Subtract 2 from the counter to compare oranges with oranges.
    line 5. If the level of the digital pin has changed, execute the code that follows. That is - string value of current pin read IS NOT (!=) the same as it was last time through.


    I understand that I have a lot of questions. If you have time to answer that would be great, if not perhaps you know of some learning resources. I have looked on the arduino website and it helps...a bit.


    No problem Marc. A lot is happening here in a few lines compounded by employing more advanced use of code which eliminates some steps present in all code tutorials.

    For example KpinStateSTR = String(digitalRead(KpinNo));

    for beginners
    // KpinNo is pin being scanned
    int KpinState;
    KpinState = digitalRead(KpinNo);
    KpinStateSTR = String(KpinState)

    SOMEBODY should post something like this as a sticky with a warning that there is GREAT learning value in this function if you noodle it out for yourself. Hold onto something for there might be nested else statements to come.

    Kind regards
    Marc[/QUOTE]
    ---CYXD ----- TWR --- GND ------ Closed
    ILS-- NDB -- 119.1 -- 121.9 ---- 11/2013

  7. #6
    150+ Forum Groupie
    Join Date
    Nov 2013
    Location
    Evansville, Indiana
    Posts
    243
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Can't figure this out!

    I changed some variable names in Jim's code examples for my own understanding and then remarked it for instruction.
    This example is from my MCP autopilot which uses an Arduino MEGA that uses input pins 22 to 54.
    Read it carefully and more than once and I think you will start to understand.

    EDIT: Ok this looks like crap in the code box.
    Go get NotePad++ https://notepad-plus-plus.org/ its a free download Code Editor.
    Copy and paste the code below into an editor and it will be much more readable to help you understand.

    Code:
    void INPUTPINS()// All of the Encoders, Buttons and Switches are checked for changes
    {
        all_pins_state = ""; // Clear this before the "for" loop because we will recreate it at the bottom, one pin at a time
        for (int current_pin = 22; current_pin <=54; current_pin++) // going to cycle thru all input pins 22 - 54      
        {
            current_pin_state = String(digitalRead(current_pin));     // get the state of the current pin and make it a string format
            current_pin_old_state = String(all_pins_old_state.charAt(current_pin - 22));  // acquire the previous state of the current pin
            // *** Explanation *** The previous state of the current pin is acquired by reading a single character in the string "all_pins_old_state" 
            // *** Explanation *** All of the pins, previous states are stored as individual characters in the string "all_pins_old_state" as a "0" or a "1".
            // *** Explanation *** We treat the individual characters as being numbered 0,1,2,3,4,...
            // *** Explanation *** If the current_pin is 25, "all_pins_old_state.charAt(current_pin - 22)" takes (25-22) which = 3. 
            // *** Explanation *** ".charAt" gets the character at position 3 in the string "all_pins_old_state"
            // *** Explanation *** Now we have the current pin's previous state and we can compare it to the current pin's "current" state.        
            if (current_pin_state != current_pin_old_state)            // compare the state of the current pin to its previous state
            {                                                                              // if its diff from the last time, then go find it below and do that
    
                            // This section would have many of these "if" statement blocks, one for each input pin. I show two for example.
                            // *******************************************************************************************
                // ALT HOLD Button
                if (current_pin == 35)
                {
                    if  (digitalRead(35) == LOW) 
                    { 
                        Serial.println ("B05");
                    }
                }
                // *******************************************************************************************
                // APP Button
                if (current_pin == 38)
                {
                    if  (digitalRead(38) == LOW) 
                    { 
                        Serial.println ("B08");
                    }
                }
    
                // *******************************************************************************************
    
    
            }   // End of IF Current Pin State Check
            all_pins_state += current_pin_state; // Constructs what will become the all_pins_old_state after the "for" loop is done
        }   // End of 'for' loop
        all_pins_old_state = all_pins_state;// all_pins_old_state is updated for the next trip thru the "for" loop
    }    // End of INPUTPINS() Function
    ~Fess
    I will only ever be, half the Geek that I wished I was.
    TheGeekForge.Com

  8. #7
    150+ Forum Groupie
    Join Date
    Nov 2013
    Location
    Evansville, Indiana
    Posts
    243
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Can't figure this out!

    I should have added this to my previous post because I changed some variable names.

    Code:
    String current_pin_state;       // The state of an individual pin being processed 
    String current_pin_old_state;    // The previous state of an individual pin being processed for comparison
    String all_pins_state;          // The state of all of the pins that we are using for Encoders, Buttons, and Switches
    String all_pins_old_state;      // The previous state of all of the pins that we are using for Encoders, Buttons, and Switches for comparison
    This next part is in, void setup()
    Code:
        all_pins_old_state = "111111111111111111111111111111111111111111111111111111111111111111111"; // Setting a starting point for comparison.
        // *** Explanation *** All of the pins previous states are stored as individual characters in the string "all_pins_old_state" as a "0" or a "1".
        // *** Explanation *** We give it a starting point by making it all ones... Further explanation is down in the INPUTPINS() Function.
        
        for (current_pin = 22; current_pin <= 54; current_pin++)    // Get all the pins ready as inputs 
        {
            pinMode(current_pin, INPUT_PULLUP);     // By setting the pins as INPUT_PULLUP it makes them all "HIGH"
                                                    // This lets us use buttons without the need for a "pull up" resistor.
        }
    ~Fess
    I will only ever be, half the Geek that I wished I was.
    TheGeekForge.Com

  9. #8
    75+ Posting Member
    Join Date
    Nov 2011
    Location
    UK
    Posts
    77
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Can't figure this out!

    Thanks guys for your detailed responses, I do appreciate the time that you took to do that. I'm starting to get how it works now, but a couple of questions. What does this line mean?

    Code:
    current_pin_old_state = String(all_pins_old_state.charAt(current_pin - 22))
    What is the charAT and why pin 22?

    Finally, I have been looking at some of Jim's demos. I have been looking at the lights demo and the multi gear keys simconnect demo.
    When you look at the void INPUTS at the bottom on each demo why on one is the
    KpinStateSTR == "0" and on the other KpinStateSTR == "1".?
    What is the difference between doing it the way Jim does it and using a digitalRead function?

    As I play some more later and am sure I will have one or two more questions?

    Thanks again
    Marc

  10. #9
    150+ Forum Groupie
    Join Date
    Nov 2013
    Location
    Evansville, Indiana
    Posts
    243
    Contribute If you enjoy reading the
    content here, click the below
    image to support MyCockpit site.
    Click Here To Contribute To Our Site

    Re: Can't figure this out!

    Quote Originally Posted by Marc1980 View Post
    Thanks guys for your detailed responses, I do appreciate the time that you took to do that. I'm starting to get how it works now, but a couple of questions. What does this line mean?

    Code:
    current_pin_old_state = String(all_pins_old_state.charAt(current_pin - 22))
    What is the charAT and why pin 22?

    Finally, I have been looking at some of Jim's demos. I have been looking at the lights demo and the multi gear keys simconnect demo.
    When you look at the void INPUTS at the bottom on each demo why on one is the
    KpinStateSTR == "0" and on the other KpinStateSTR == "1".?
    What is the difference between doing it the way Jim does it and using a digitalRead function?

    As I play some more later and am sure I will have one or two more questions?

    Thanks again
    Marc
    The current_pin_old_state is number 0 or 1 in string format.
    all_pins_old_state.charAt(current_pin - 22)
    "all_pins_old_state" is the string of 0s or 1s that stores the previous states of all the pins.
    We started our input pins at pin 22.
    So, the state of pin 22 is stored in the first character, in the string "all_pins_old_state".
    Characters in a string are numbered 0,1,2,3....
    So to read the first character we take the "current_pin" (from the for loop) and subtract 22.
    pin 22 -22 = position 0 in the string.
    The second pin state(pin 23) is at string position 1.
    So current_pin is 23 - 22 = position 1, in the string "all_pins_old_state".

    ~Fess
    I will only ever be, half the Geek that I wished I was.
    TheGeekForge.Com