Home ยป DIY Concorde servo panel

DIY Concorde servo panel

by Bits and Droids
0 comment 117 views
multiposition switch wired up to an Arduino Mega

Used in this project:

(All links below are affiliate links that help support the channel)

Tools used:

Multiposition switches

There is an enormous amount of different multiposition switches available. The ones I’ve bought are humongous but smaller versions are also available. The switch we will be focussing on is the switch, as seen below.

multiposition switch wired up to an Arduino

Usually, the product’s store page will display a diagram or table explaining how to retrieve the current state. In this instance, they’ve provided a table referencing which pins are connected in each state.

momentary switch frontplate

When talking about states I’m refering to the positions as seen on the provided faceplate as seen on the image above

Terminals v Position ->012
1 -> 2xx
3 -> 4x
5 -> 6x
7 -> 8

The simplest thing we might conclude is that terminals 7 and 8 aren’t used at all. So we might as well ignore these terminals completely (in this instance, they are also missing pads, but your seller might provide different setups). In the 0 state, no terminals connect. If we wired these terminals up using the internal pull-up resistors of our Arduino, the 0 state would be active when all terminals read as a HIGH signal (or LOW if you use pull-down resistors). In all other instances, the first and second terminals connect. This leaves us with a single check to see if we are in the first state.

//pulup resistors
if(digitalRead(pinA) == HIGH){
  //The terminals at pinA aren't connected thus we are in state 0
}

//If using pull down resistors
//if(digitalRead(pinA) == LOW){
  //The terminals at pinA aren't connected thus we are in state 0
//}

We could then check whether or not the first state was set by checking if the 1 and 2 terminals are connected. The downside of this would be that in the second state, these terminals are connected as well. We could check if the first terminal is connected and if the third and fifth terminals are connected. But this would lead to unnecessary checks. It will be wiser to check if the third and fourth terminals are connected. We know for a fact that these terminals connect when we are in the second state.

//pulup resistors
if(digitalRead(pinC) == LOW){
  //The terminals at pinB are connected thus we are in state 2
}

//If using pull down resistors
//if(digitalRead(pinC) == HIGH){
  //The terminals at pinB are connected thus we are in state 2
//}

In theory, we could add a third check to see whether or not we are in the first state. But if we aren’t in state two, and we aren’t in state zero. The only thing that would be left is state 1. So in this instance, a simple else statement would suffice.

//pulup resistors
if(digitalRead(pinA) == HIGH){
  //The terminals at pinA aren't connected thus we are in state 0
}

//If using pull down resistors
//if(digitalRead(pinA) == LOW){
  //The terminals at pinA aren't connected thus we are in state 0
//}

//pulup resistors
if(digitalRead(pinC) == LOW){
  //The terminals at pinC are connected thus we are in state 2
}

//If using pull down resistors
//if(digitalRead(pinC) == HIGH){
  //The terminals at pinC are connected thus we are in state 2
//}

else{
  //Everything else has been checked so the only thing that is left is state 1
}

Wiring

These switches are pretty easy to wire up. You could use any pin you desire, but if you want to follow along with my code, I’d recommend using the same pins (if you use different pins, remember to change these pins everywhere in your code). The most effortless setup would be to use the internal pull-up resistors (for a full explanation of this approach, check out my article on pushbuttons).

The resistors will ensure that the signal stays HIGH when the terminals aren’t connected. Once they are connected, the power can flow towards the ground line. Therefore we could wire up all the terminals of either side (all the even or all the uneven terminals) to the same ground line. Whichever side you choose doesn’t matter. The end result will be the same. The other ends connect to three individual pins on your microcontroller. I went with pins 3,4, and 5 for the upper switch while using 6,7, and 8 for the lower switch.

momentary pushbutton wiring diagram

Even though the multiposition switches I’ve used are massive, they behave the same way as a latching pushbutton. That is why I’ve opted to show the diagram above as an illustration.

Events used

In order to send commands to the game, I’ve used three custom commands. These can be added to the event file through the connector which can be downloaded from my downloads page.

6013(>L:OVERHEAD_HYD_SELECTOR)Input with value
6014(>L:OVERHEAD_HYD_SELECTOR_2)Input with value
6015(>L:LIGHT_TEST, bool)Input with value

Code used:

#include <BitsAndDroidsFlightConnector.h>

BitsAndDroidsFlightConnector connector = BitsAndDroidsFlightConnector();

enum states {
  LEFT,
  UP,
  RIGHT
};

const byte testPin = 53;

const byte redLEDs[] = { 8, 9, 10, 11 };
const byte greenLEDs[] = { 12, 51, 50, 52 };

const byte upperSwitch[] = { 3, 4, 5 };
const byte lowerSwitch[] = { 6, 7, 8 };

byte oldLowerState;
byte oldUpperState;
byte oldTestState;

long timer0State = 0;

void setup() {
  Serial.begin(115200);

  for (auto& pin : redLEDs) {
    pinMode(pin, OUTPUT);
  }

  for (auto& pin : greenLEDs) {
    pinMode(pin, OUTPUT);
  }

  for (auto& pin : upperSwitch) {
    pinMode(pin, INPUT_PULLUP);
  }

  for (auto& pin : lowerSwitch) {
    pinMode(pin, INPUT_PULLUP);
  }

  pinMode(testPin, INPUT_PULLUP);
}

void loop() {
  connector.dataHandling();
  checkUpperSwitch();
  checkLowerSwitch();
  checkTestState();

}


void checkLowerSwitch() {
  //My top switch has 4 positions while the lower only has 3
  //I'd recommend to buy two 3 position switches to make your life easier.
  //Pos 0 == all off | pos 1 == 6 connected | pos 2 == 6,7,8 connected
  byte currentState;
  //6 is always on unless we are in position 0, this will be our first check
  if (digitalRead(lowerSwitch[0]) == HIGH && digitalRead(lowerSwitch[1]) == HIGH && digitalRead(lowerSwitch[2]) == HIGH) {
    //I've added a custom command to the connector with prefix 6013
    //0 is the switch state we want to set the ingame switch to
    currentState = LEFT;
  }
  //pin 8 will only be LOW if the switch is in position 2
  else if (digitalRead(lowerSwitch[2]) == LOW) {
     currentState = RIGHT;
  }
  //if we checked all these sentences we know for a fact the other state will be 1
  //(unless there would be an error in our wiring)
  else {
     currentState = UP;
  }
  if(currentState != oldLowerState){
    Serial.println("6013 " +  String(currentState));
    oldLowerState = currentState;
    delay(100);
    setGreenLightState();
  }
}

//The states differ between 3 and 4 position switches,
//that is why I've used 2 functions
void checkUpperSwitch() {
  //I use position 1,2 and 3. They all match 1 on 1 with their states. If they are LOW that position is set.
  byte currentState;

  if (digitalRead(upperSwitch[1]) == LOW) {
    currentState = RIGHT;
  } else if (digitalRead(upperSwitch[2]) == LOW) {
    currentState = UP;
  } else {
    if(timer0State==0){
      timer0State = millis();
    }
    currentState = LEFT;
  }

  //Because switchting states adds a gap where all states are HIGH I've added a timer
  //This filters out the incorrect readings for the 0 state when turning the dial
  long currentTime = millis();

  if(currentState != oldUpperState){
    if((currentState == 0 && abs(currentTime - timer0State) > 500) || currentState == 1 || currentState == 2){
      timer0State = 0;
      Serial.println("6012 " + String(currentState));
      oldUpperState = currentState;
      delay(200);
      setGreenLightState();
    }
  }
}

void setGreenLightState(){
 
  switch(oldLowerState){
    case LEFT:{
      digitalWrite(greenLEDs[3], HIGH);
      digitalWrite(greenLEDs[2], LOW);
      break;
    }
    case UP:{
      digitalWrite(greenLEDs[2], HIGH);
      digitalWrite(greenLEDs[3], HIGH);
      break;
    }
    case RIGHT:{
      digitalWrite(greenLEDs[2], HIGH);
      digitalWrite(greenLEDs[3], LOW);
      break;
    }
  }
   switch(oldUpperState){
    case LEFT:{
      digitalWrite(greenLEDs[0], HIGH);
      digitalWrite(greenLEDs[1], LOW);
      break;
    }
    case UP:{
      digitalWrite(greenLEDs[0], HIGH);
      digitalWrite(greenLEDs[1], HIGH);
      break;
    }
    case RIGHT:{
      digitalWrite(greenLEDs[1], HIGH);
      digitalWrite(greenLEDs[0], LOW);
      break;
    }
  }
  
}

void checkTestState(){
  byte currentState = digitalRead(testPin);
  if(currentState != oldTestState){
    if(currentState == LOW){
      for(auto & led : greenLEDs){
        digitalWrite(led, HIGH);
      }
      //The red lights are only in when the testSwitch is triggered
      //This makes it correspond with the ingame trigger without retrieving game data
      for(auto & led : redLEDs){
        digitalWrite(led, HIGH);
      }
      Serial.println("6015 1");
    } else{
      //Make sure to set the lights back to the correct state
      setGreenLightState();
       for(auto & led : redLEDs){
        digitalWrite(led, LOW);
      }
      Serial.println("6015 0");
    }
    
    oldTestState = currentState;
  } 
  
}

You may also like

Leave a Comment

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept