Bits and Droids logo
Mail icon

DIY Concorde servo panel

3/30/2024 | by Bits and Droids

Used in this project:

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

Tools used:

Multiposition switches

There are an enormous number of different multiposition switches available. The ones I've bought are humongous, but smaller versions are also available. We will focus on the switch, as seen below.

Multi position switch

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.

Multi position 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 ->0121 -> 2xx3 -> 4x5 -> 6x7 -> 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 a single check to see if we are in the first state.

cpp
//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 push buttons).

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 on either side (all the even or all the uneven terminals) to the same ground line. Whichever side you choose doesn't matter. The 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.

Even though the multiposition switches I've used are massive, they behave the same way as a latching push button. That is why I've opted to illustrate the diagram above.

Events used

.I've used three custom commands to send commands to the game. The connector, which can be downloaded from my downloads page., can be used to add these to the event file

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:

cpp
#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; } }