So es geht doch nichts über reale Bilder und eine Beschreibung die alle wichtigen Details umfasst.
Da muss @hervshahn noch einiges nachliefern.
Ich hatte jetzt auch ohne diese Details zu kennen Spaß daran mit Annahmen die ich für sehr wahrscheinlich halte mal ein Programm zu schreiben.
Die Schaltzusände LOW/HIGH der beiden Half-Moon-Schalterkontakte werden einzeln in Variablen gespeichert und dann ausgewertet.
Möglicherweise kann man durch Zusammenfügen zu einem zweibit-Wert "00", "01", "10" die Logik noch vereinfachen.
Annahme 1: Die Fuß-"Dinger" sind wirklich Taster im Sinne von wenn man Sie betätigt wird der Kontakt geschlossen, sobald man den Fuß herunternimmt öffnet sich der Kontakt wieder.
Annahme 2: Der Half-Moon-Schalter sieht so aus wie auf der Abbildung und ist auch so beschriftet wie auf der Abbildung. Das bedeutet dann wenn man von slow auf fast
oder
von fast auf slow umschalten will kommt man an der Stop-Stellung vorbei.
Das bedeutet man muss eine Fallunterscheidung machen zwischen dem Umschalten
slow ==> stop ===> fast
und
slow ==> stop ==> slow
sowie
fast ==> stop ===> slow
und
fast ==> stop ==> fast
Annahme 3: Der Hammond-Orgel-Nachbau merkt sich den slow/fast Modus:
Soll heißen
wenn man sich im slow Modus befindet und der Start/Stop-impuls kommt,
wird der Leslie-Effekt gestoppt. Wenn man dann wieder Start/Stop-Impuls macht dann läuft es im slow-Modus also im gleichen Modus wieder an.
ebenso
wenn man sich im fast Modus befindet und der Start/Stop-impuls kommt,
wird der Leslie-Effekt gestoppt. Wenn man dann wieder Start/Stop-Impuls macht dann läuft es im fast-Modus also im gleichen Modus wieder an.
Und das muss @hervshahn mal posten ob das so stimmt.
So wie ich das verstanden habe hat der Hammond-Orgel-Nachbau im Urzustand zwei Fuß-Taster
Und soll auf so einen Half-Moon-Schalter umgebaut werden
Hier der Code. Jedoch nicht getestet.
Es gibt noch eine Sache die noch nicht gelöst ist:
Wenn man die Hammond-Orgel selbst einschaltet wie ist dann die Voreinstellung für den Leslie-Effekt?
Da der Code je nach Schalterstellung einen Modus Leslie-Effekt Ein/aus und slow/fast setzt
und ja immer nur mit Impulsen gearbeitet wird könnte die Situation entstehen, dass das Arduino-Programm von slow ausgeht aber die Orgel von fast
bzw.
von Leslie-Effekt aktiv / nicht aktiv.
An der Stelle muss man noch einmal genau hinschauen und wahrscheinlich etwas am Programm verändern.
Superklasse wäre natürlich wenn man den Zustand von der Hammond-Orgel elektronisch abgreifen kann und auch dem Arduino zuführt.
Wenn das nicht geht dann macht es wahrscheinlich Sinn wenn man noch zwei Korrektur-Taster hätte. Damit kann man dann Den Zustand des Hammond-Orgel-Nachbaus und des Arduinos aufeinander abgleichen.
Taster 1: Erzeuge einen StartStop-Impuls
Taster 2: Erzeuge einen Slow/fast-Impuls
const byte OnBoard_LED = 13; // onboard-LEDESP32 / ESP8266
const byte slowInputPin = 4;
const byte fastInputPin = 5;
byte lastSlowInputState;
byte lastFastInputState;
const byte SlowFastPulsePin = 10;
const byte StartStopPulsePin = 11;
const byte slow = 0;
const byte fast = 1;
byte slowFastMode;
const byte stopped = 0;
const byte running = 1;
byte runMode;
const byte closed = LOW;
const byte opened = HIGH;
unsigned long pulseStartTime = 0;
const unsigned long pulseLength = 300;
void setup() {
Serial.begin(115200);
Serial.println("Setup-Start");
pinMode(slowInputPin, INPUT_PULLUP);
pinMode(fastInputPin, INPUT_PULLUP);
pinMode(SlowFastPulsePin, OUTPUT);
pinMode(StartStopPulsePin, OUTPUT);
lastSlowInputState = digitalRead(slowInputPin);
lastFastInputState = digitalRead(fastInputPin);
// Half-moon-Schalter in Mittelstellung = beide Kontakte geöffnet
if ( (lastSlowInputState == opened) && ((lastFastInputState == opened)) ) {
runMode = stopped;
digitalWrite(StartStopPulsePin, HIGH);
delay(pulseLength);
digitalWrite(StartStopPulsePin, LOW);
}
// Half-moon-Schalter auf Stellung slow
if (lastSlowInputState == closed && lastFastInputState == opened) {
runMode = running;
slowFastMode = slow;
digitalWrite(SlowFastPulsePin, HIGH);
delay(pulseLength);
digitalWrite(SlowFastPulsePin, LOW);
}
// Half-moon-Schalter auf Stellung fast
if (lastSlowInputState == opened && lastFastInputState == closed) {
runMode = running;
slowFastMode = fast;
digitalWrite(SlowFastPulsePin, HIGH);
delay(pulseLength);
digitalWrite(SlowFastPulsePin, LOW);
}
}
void scanSwitchContacts() {
byte actualSlowInputState = digitalRead(slowInputPin);
byte actualFastInputState = digitalRead(fastInputPin);
if ( (lastSlowInputState != actualSlowInputState) || ( lastFastInputState != actualFastInputState ) ) {
// prüfe auf Stop-Stellung
if ( (actualSlowInputState == opened) && (actualFastInputState == opened) ) {
if (runMode == running) {
runMode = stopped;
digitalWrite(StartStopPulsePin, HIGH);
pulseStartTime = millis();
}
}
}
if ( lastSlowInputState != actualSlowInputState ) {
if (actualSlowInputState == closed) { // wenn Half-moon-Schalter auf Stellung slow
runMode = running;
// wenn vom mode fast kommend (Schalter war in Stellung fast dann auf Stop jetzt slow
if (slowFastMode == fast) {
slowFastMode = slow;
digitalWrite(SlowFastPulsePin, HIGH);
pulseStartTime = millis();
}
// wenn von Stop erneut slow geschaltet wird dann einen StartStop-Pulse geben
if (slowFastMode == slow) {
digitalWrite(StartStopPulsePin, HIGH);
pulseStartTime = millis();
}
}
}
if ( lastFastInputState != actualFastInputState ) {
if (actualFastInputState == closed) { // wenn Half-moon-Schalter auf Stellung fast
runMode = running;
// wenn vom mode slow kommend (Schalter war in Stellung slow dann auf Stop jetzt auf fast
if (slowFastMode == slow) {
digitalWrite(SlowFastPulsePin, HIGH);
pulseStartTime = millis();
}
// wenn von Stop erneut auf fast geschaltet wird dann einen StartStop-Pulse geben
if (slowFastMode == fast) {
digitalWrite(StartStopPulsePin, HIGH);
pulseStartTime = millis();
}
}
}
lastSlowInputState = actualSlowInputState;
lastFastInputState = actualFastInputState;
}
void CheckPulseTiming() {
if (pulseStartTime != 0) {
if (millis() - pulseStartTime >= pulseLength) {
digitalWrite(StartStopPulsePin, LOW); // Impuls beenden
digitalWrite(SlowFastPulsePin, LOW); // Impuls beenden
pulseStartTime = 0; // pulseStartTime auf null setzen als Indikator KEIN Impuls aktiv
}
}
}
void loop() {
BlinkHeartBeatLED(OnBoard_LED, 250);
delay(50); // billiges Schalter entprellen
scanSwitchContacts();
CheckPulseTiming();
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long & startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}
void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
static unsigned long MyBlinkTimer;
pinMode(IO_Pin, OUTPUT);
if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
}
}
vgs
