/*-----------------------------------------------------------------------------------------
* This software is in the public domain, furnished "as is", without technical
* support, and with no warranty, express or implied, as to its usefulness for
* any purpose.
*
* Multiswitch.ino
*
* Multiswitch decoder for 4 switches. RC PWM signal length for each switch must be
* half of the previous one.
*
* This multiswitch based on the Yet another Multi Switch - YaMS implementation
* of Dirk Wiedemann (www.rc-bastelbu.de), but is not using the servo lib for the
* RC-Signal readings. The hardware information of the encoder should taken from
* the above referenzed web-location.
* The calibration steps of the RC input signals must be done as described
* in pwmread_rcfailsafe.ino as well.
*
* Author: Volker Frauenstein
* Date: 06/01/2021 Version: 1.2 functionality of hysteresis added for stability reasons
* of switch buttom recognition
*
* Date: 05/01/2021 Version: 1.1 pinout redefinition for migration to ESP32 architecture
* Date: 21/12/2020 Version: 1.0 implementation of multiswitch decoder for Arduino Nano
*/
// pinout definitions for the multiswitch
// const int msPin_a = 23; // Enginesound on/off -> used ESP32 internal (switchOn[0]), no pinout needed
// const int msPin_b = 22; // Horn on/off -> used ESP32 internal (switchOn[1]), no pinout needed
// const int msPin_c = 21; // MG sound on/off -> used ESP32 internal (switchOn[2]), no pinout needed
const int msPin_d = 13; // Frontlights on/off
// Thresholds to separate every switch state from his neighbors, must be customized for real encoders
// float MS_threshold [17] = { -1.0625, -0.9375, -0.8125, -0.6875, -0.5625, -0.4375, -0.3125, -0.1875, 0,
// 0.1875, 0.3125, 0.4375, 0.5625, 0.6875, 0.8125, 0.9375, 1.0625 };
// Adapted thresholds for Robbe Terratop with multiswitch
float MS_threshold [17] = { -1.0625, -0.9785, -0.89, -0.765, -0.6275, -0.495, -0.38, -0.2625, -0.095,
0.085, 0.23, 0.375, 0.5425, 0.7075, 0.8525, 0.965, 1.0625 };
// generig definitions
int hysteresis = 0; // counter for hysteresis
int last_state = 0; // switch state of last cycle
const int MSthreshold = 20; // threshold for hysteresis
// #define DEBUG_MS 1
// interface definitions to handle Multiswitch states -> definition in main.ino needed
// bool switchOn[4] = {false, false, false, false}; // one bit per switch: engine/horn/gunfire/lights
void setup_MultiSwitch() {
// pinMode(msPin_a, OUTPUT); // uncomment because function in SW
// pinMode(msPin_b, OUTPUT); // uncomment because function in SW
// pinMode(msPin_c, OUTPUT); // uncomment because function in SW
pinMode(msPin_d, OUTPUT); // pinout for 1-Relais Modul
}
void close_MultiSwitch() {
// digitalWrite(msPin_a, LOW); // close all digital pins
// digitalWrite(msPin_b, LOW);
// digitalWrite(msPin_c, LOW);
digitalWrite(msPin_d, HIGH); // Switch on defined with pulldown
for ( int i = 0; i <4 ; i++) {
switchOn[i] = false; // and switch of internal sound functions
}
} // function close_MultiSwitch closed
void run_MultiSwitch(int ch) { // function to check states of the multiswitch
// and activate the pinouts if needed
float MS_value = RC_in[ch]; // value of used RC channel for multiswitch
int S_state = 0; // value for state of switches (0 to 15)
for (int i = 0; i <= 15; i++) { // precalculate switchstate via the thresholds
if (MS_value > MS_threshold[i] && MS_value <= MS_threshold[i + 1]) S_state = i;
}
if ( S_state != last_state) { // check if switches have changed
if (hysteresis > MSthreshold) {
last_state = S_state; // yes we change
hysteresis = 0;
}
else {
S_state = last_state; // hysteresis is running, we we change
hysteresis++;
}
}
else hysteresis = 0; // no change triggered
#ifdef DEBUG_MS
Serial.print("MS_switch: ");Serial.print(S_state);Serial.print(" changecount: ");Serial.print(hysteresis);
#endif
if (S_state > 7) { // check state of highes switch
digitalWrite(msPin_d, LOW); // and activate pinout
S_state = S_state - 8; // get ready for next switch
switchOn[3] = true;
#ifdef DEBUG_MS
Serial.print(" T,");
#endif
}
else {
digitalWrite(msPin_d, HIGH); // switch is off -> deactivate pinout
switchOn[3] = false;
#ifdef DEBUG_MS
Serial.print(" F,");
#endif
}
if (S_state > 3) { // check state of next switch
// digitalWrite(msPin_c, HIGH);
S_state = S_state - 4;
switchOn[2] = true; // return with global defined bool array
#ifdef DEBUG_MS
Serial.print(" T,");
#endif
}
else {
// digitalWrite(msPin_c, LOW);
switchOn[2] = false;
#ifdef DEBUG_MS
Serial.print(" F,");
#endif
}
if (S_state > 1) { // check state of next switch
// digitalWrite(msPin_b, HIGH);
S_state = S_state - 2;
switchOn[1] = true;
#ifdef DEBUG_MS
Serial.print(" T,");
#endif
}
else {
// digitalWrite(msPin_b, LOW);
switchOn[1] = false;
#ifdef DEBUG_MS
Serial.print(" F,");
#endif
}
if (S_state > 0) { // check state of lowest switch
// digitalWrite(msPin_a, HIGH);
switchOn[0] = true;
#ifdef DEBUG_MS
Serial.print(" T,");
#endif
}
else {
// digitalWrite(msPin_a, LOW);
switchOn[0] = false;
#ifdef DEBUG_MS
Serial.print(" F:");
#endif
} // end of switch state check
#ifdef DEBUG_MS // show DEBUG_MS data if needed
Serial.print(" MSch");Serial.print(": ");
Serial.print(RC_in[ch]);Serial.print(" -> ");
for (int i = 0; i<4; i++){
Serial.print(switchOn[i]);Serial.print(",");
}
Serial.println();
#endif
} // function run_MultiSwitch closed