Another of my SimRail train simulator controllers.
This time a simple one, a 4 position industrial style rotary switch and a button, to operate the wipers and wash the windscreen in the virtual trains.
I have 4 x 10K resistors linking each rotary switch output as a resistor ladder, 5 volts and ground to each side of the resistor ladder,
Then i'm reading the analog value through a single pin, A0 on an arduino beetle (leonardo style board)
When the rotary switch is moved, the sketch looks for which way the switch moves, and sends the keyboard codes to move the in game switch one notch in the correct.
There's just 3 positions i am using on the 4 position switch, i deliberately got a 4 position switch so i could read the switches pins without having OFF as no connection as is normal with switches.
:
The issue i'm having is when rotating the switch, sometimes the arduino is picking up the 'gap' between switch states, where the switch goes open circuit before making the next circuit.
This results in the switch in the game moving to positions it shouldn't (i imagine there's a little bit of contact bounce in here too)
Any suggestions on how to handle the brief open circuit situations?
:
I can re-wire things and read each individual switch state using 4 digital inputs on the arduino, but i guess that will also suffer the open circuit 'break before make' issue?
My sketch is:
#include <Keyboard.h> // Keyboard library
#define Washers_PIN 11
unsigned long startTime, endTime = 10; //10 millisecond timer
byte wiperSwitchPos, oldwiperSwitchPos, currentPos; // store wiper switch positions
int8_t diff;
int val;
bool posSent = true; // Position sent, set to yes
void setup() {
pinMode(Washers_PIN, INPUT_PULLUP);
val = getAnalog(); // Variable for storing wiper switch's position (resistor values)
Serial.begin(115200); // Start serial comms
while (!Serial)
; // Wait for pro-micro's usb comms to start
Serial.print("\nCurrent Wiper Switch position = ");
Serial.print(wiperSwitchPos);
currentPos = oldwiperSwitchPos = wiperSwitchPos;
}
void loop() {
val = getAnalog();
if (wiperSwitchPos != currentPos) { // if switch position has changed
startTime = millis(); // start the timer
currentPos = wiperSwitchPos; // Set current position in the switch position variable
posSent = false;
diff = 0;
}
if (!posSent && millis() - startTime > endTime) {
diff = wiperSwitchPos - oldwiperSwitchPos;
Serial.print("Wiper Switch Position = ");
Serial.print(wiperSwitchPos);
Serial.print("\t");
Serial.print("Difference = ");
Serial.println(diff);
// if diff number decreases
if (diff < 0) { // Wiper switch has been moved ClockWise
for (int i = 0; i < (diff * -1); i++) { // not sure
Keyboard.write(111); // send keyboard key O
}
}
// if diff number increases
if (diff > 0) { // Wiper switch moved Anti ClockWise
for (int i = 0; i < diff; i++) {
Keyboard.write(112); // send keyboard key P
delay(65); // 65 Ms delay.... must change to non blocking delays
}
}
oldwiperSwitchPos = wiperSwitchPos;
posSent = true;
}
int Washer_Button = digitalRead(Washers_PIN);
if (Washer_Button == HIGH) {
Keyboard.press(118);
Serial.println("Washing Windscreen");
} else {
Keyboard.release(118);
}
}
int getAnalog() {
val = analogRead(A0); // Read Wiper Switch resistors connected to A0
if (val > 750) wiperSwitchPos = 0; // Off
else if (val > 500) wiperSwitchPos = 1; // On Constant
else if (val > 245) wiperSwitchPos = 2; // Intermittant Short Delay
else if (val > -5) wiperSwitchPos = 3; // Intermittant Long Delay
}