3 way toggle switch

Hi all,

I am really quite new to the world of Arduino and am using it to build a flightsim cockpit. I am enjoying the challenge and the learning curve that Arduino provides. I have a history in aeronautical engineering but have no background in programming or electronics.

One thing I am trying to do is to use a 3 way toggle switch to control the aircrafts flaps. I am using a programme called link2fs which acts as an interface between arduino and flight simulator. I have the switch wired into D11 & D12. The idea is that when in the top position the flaps are up and a Serial.println is sent to link2fs and when the switch is in the middle/off position ie both pins are LOW another Serial.println is sent for approach flaps and when the switch is in the bottom position another Serial.println is sent to send the flaps fully down.

Although I can get the flaps fully up and fully down I am struggling to get the middle positions sorted.

The thing I am finding tricky is to, and to be honest am not sure if it is possible.

Any help would be great
Kind regards
Marc

Hi,
If you need up, neutral and down, and you have a single pole-double throw-centre off switch.
With pull up resistors on.

  • The switch UP will gnd D11, so you have D11 LOW and D12 HIGH.
  • The switch CENTRE so you have D11 HIGH and D12 HIGH.
  • The switch DOWN will gnd D12, so you have D11 HIGH and D12 LOW.

And so you have your three flap states from one DPDT-Centre OFF switch.

Tom… :slight_smile:

dpdt-c.jpg

You need to read the D11 and D12 inputs within the loop of your program and to ensure the program loops at least say 10 times per second. Record the position of the flaps in a variable: with integer values say zero for flaps-up, one for approach and two for fully-down. After reading the D11 and D12, using the value of your variable check to see if there has been a change in switch position; if so send the necessary Serial.println. You will probably need to initially set the flaps to a specific position in the 'setup' portion of your program, setting the value of your variable at the same time. I suggest the variable is made 'global' by declaring it above the 'setup' portion of your program.

Thank for the prompt reply. I have had a bit of a play but the closest thing I can get to working is the code I already have which gives me the first and last setting but Im not sure what to do with it to give me the middle setting. I will attach it below, have a look at the void INPUTS section towards the bottom. I did not write this code only tweaked it to suit me so am not completely sure of what it all means. It also includes outputs for LED indications which all work nicely. It’s just this middle switch. If anyone has any ideas of what could be changed with this that would be great.

Thanks again

Marc

*/


int CodeIn;// used on all serial reads
int KpinNo; 
int Koutpin;
String flaps;

String KoldpinStateSTR, KpinStateSTR, Kstringnewstate,Kstringoldstate;
String gearN,gearL,gearR;
int gearNi,gearLi,gearRi;

void setup() 
{
  Kstringoldstate = "111111111111111111111111111111111111111111111111111111111111111111111";
  
  for (int KoutPin = 9; KoutPin < 14; KoutPin++)// Get all the pins ready for simconnect codes and "Keys"(all inputs)  
  {
    pinMode(KoutPin, INPUT);
    digitalWrite(KoutPin, HIGH);  
  }
  pinMode(2, OUTPUT); // Flaps are in transition LED
  pinMode(3, OUTPUT); // Flaps are down 1st position LED
  pinMode(4, OUTPUT); // Flaps are down 2nd position LED
  pinMode(5, OUTPUT); // gear nose LED
  pinMode(6, OUTPUT); // gear left LED
  pinMode(7, OUTPUT); // gear right LED
  pinMode(8, OUTPUT); // gear in transition LED
 Serial.begin(115200);   
}

void loop() {
  {INPUTS();} //Check the Simconnect and "keys" section
  {OTHER();}// Check for "Other" things to do. (Non extraction stuff)
  if (Serial.available()) {
    CodeIn = getChar();
    if (CodeIn == '=') {EQUALS();} // The first identifier is "="
    if (CodeIn == '<') {LESSTHAN();}// The first identifier is "<"
    if (CodeIn == '?') {QUESTION();}// The first identifier is "?"
    if (CodeIn == '/') {SLASH();}// The first identifier is "/" (Annunciators)
  }

}

char getChar()// Get a character from the serial buffer
{
  while(Serial.available() == 0);// wait for data
  return((char)Serial.read());// Thanks Doug
}
void OTHER(){
/* In here you would put code that uses other data that
cant be put into an "extraction void" that references something else.
Also in here you would put code to do something that was not
relying on a current extraction trigger.
*/

//Sort out the gear "in transition" LED
int gearTot = (gearNi + gearLi + gearRi);
if (gearTot == 300){digitalWrite(8, LOW);} 
else if (gearTot < 1){digitalWrite(8, LOW);}
else {digitalWrite(8, HIGH);}
}

void EQUALS(){      // The first identifier was "="
 CodeIn = getChar(); // Get the second identifier
  switch(CodeIn) {// Now lets find what to do with it
    case 'A'://Found the second identifier
       //Do something
    break;
     
    case 'B':
       //Do something
    break;
     
    case 'C':
       //Do something
    break;
    
         //etc etc etc
     }
}

void LESSTHAN(){    // The first identifier was "<"
CodeIn = getChar(); // Get the second identifier
  switch(CodeIn) {// Now lets find what to do with it
    case 'A'://Found the second identifier "GearN"
      gearN = "";
      gearN += getChar();
      gearN += getChar();
      gearN += getChar();
      gearNi = gearN.toInt(); // convert it to an integer (Thanks Phill)
      if (gearNi > 99){digitalWrite(5, HIGH);}else{digitalWrite(5, LOW);}
      // See "OTHER" for more uses of gearni
    break;
     
    case 'B':
      gearL = "";
      gearL += getChar();
      gearL += getChar();
      gearL += getChar();
      gearLi = gearL.toInt(); // convert it to an integer (Thanks Phill)
      if (gearLi > 99){digitalWrite(6, HIGH);}else{digitalWrite(6, LOW);}
      // See "OTHER" for more uses of gearLi
    break;
     
    case 'C':
        gearR = "";
      gearR += getChar();
      gearR += getChar();
      gearR += getChar();
      gearRi = gearR.toInt(); // convert it to an integer (Thanks Phill)
      if (gearRi > 99){digitalWrite(7, HIGH);}else{digitalWrite(7, LOW);}
      // See "OTHER" for more uses of gearRi
    break;

    case 'G'://Found the second identifier ("G" Flaps position)
      flaps = "";
      flaps += getChar();
      flaps += getChar();
      flaps += getChar();
      int flapsInt = flaps.toInt(); // convert it to an integer (Thanks Phill)
      if (flapsInt > 0 && flapsInt < 29) {digitalWrite(2, HIGH);}
      else if (flapsInt >29 && flapsInt <57){digitalWrite(2,HIGH);}else {digitalWrite(2, LOW);}
      if (flapsInt == 29) {digitalWrite(3, HIGH);} else {digitalWrite(3, LOW);}
      if (flapsInt > 56) {digitalWrite(4, HIGH);} else {digitalWrite(4, LOW);}
       }
}

void QUESTION(){    // The first identifier was "?"
CodeIn = getChar(); // Get the second identifier
  switch(CodeIn) {// Now lets find what to do with it
    case 'A'://Found the second identifier
       //Do something
    break;
     
    case 'B':
       //Do something
    break;
     
    case 'C':
       //Do something
    break;
       
         //etc etc etc
     }
}
void SLASH(){    // The first identifier was "/" (Annunciator)
  //Do something
}
void INPUTS() // Simconnect codes and "Keys" section
{
  Kstringnewstate = "";
  for (int KpinNo = 9; KpinNo < 14; KpinNo++){ //set to the input pins. (pins 6 to 70 ,, change for Uno cards)
    KpinStateSTR = String(digitalRead(KpinNo)); 
    KoldpinStateSTR = String(Kstringoldstate.charAt(KpinNo - 9));// set to the first pin read (The 6)
    if (KpinStateSTR != KoldpinStateSTR)// checks if it's different to the last reading of that pinNo
    {
      if (KpinNo != 13){ // avoid using pin 13 as an input unless you know the tricks.
        if (KpinNo == 9 && KpinStateSTR == "0"){Serial.println ("C01");} //sets gear handle up
        if (KpinNo == 10 && KpinStateSTR == "0"){Serial.println ("C02");} //sets gear handle down
        if (KpinNo == 11 && KpinStateSTR == "0"){Serial.println ("C17000");} //Decrements flap handle position
        if (KpinNo == 12 && KpinStateSTR == "0"){Serial.println ("C17057");} //Increments flap handle position
        //  Add more here but remember to change the figure in the next line down. (the 12)
        if (KpinNo > 12){ //Change pinNo number to same as the highest one used for simconnect codes.(the 12)
        Serial.print ("D"); 
      if (KpinNo < 10) Serial.print ("0");
      Serial.print (KpinNo);
      Serial.println (KpinStateSTR);
        }//end of 'its pinNo is greater than 12' 
      }//end of 'its not pin 13'
    }//end of 'its different'       
    Kstringnewstate += KpinStateSTR;
  }//end of 'for' loop (read the pins)
  Kstringoldstate = Kstringnewstate;
}//end of INPUTS void

Hi,
The program seems to do what you need, its just that the rate of change of the flaps may be too high, or there is a delay between you selecting up or down flap movement.
What is the increment/decrement steps?
You may have to adjust those to get a better response.

Tom.... :slight_smile: