5 oder 12V sind eigentlich egal. Die Info mit dem 12 V Steckernetzteil als Versorgung wäre im Anfangsposting sinnvoll gewesen.
Gruß Tommy
5 oder 12V sind eigentlich egal. Die Info mit dem 12 V Steckernetzteil als Versorgung wäre im Anfangsposting sinnvoll gewesen.
Gruß Tommy
Mein Vorschlag ein Zetel + Bleistift und aufzeichnen wie und was, Fotos sind immer Willkommen.
Darauf warte ich schon seit ungefähr 2 Stunden.
Da wirst Du noch weiter warten müssen, da er erst in der nächsten Woche wieder am Gerät ist.
Gruß Tommy
Ach Herrje. Das finde ich weeeeeeiiit hergeholt.
So und jetzt beobachte dich selber beim Denken wie es dir mit dem Satz mit dem Bindestrich geht.
Da geht dir bestimmt auch schon wieder der Hut hoch
a.) weil es Stefan schreibt
b.) weil man mit argwöhnischer Interpretation sonst was zwischen den Zeilen herauslesen kann.
Dir fällt das gar nicht mehr auf mit dem argwöhnischen Interpretieren weil es für dir völlig normal erscheint.
??? und was ist der ?
Ein Schlagschalter, Not-Aus usw. sind auch keine Schalter?
Da kannst Du rein interpretieren, was Du willst, das interessiert mich nicht.
Ich habe ihn eine lange Zeit nebenan erlebt. Das prägt.
Bis er unter Moderatoren-Aufsicht gestellt wurde und gegangen ist.
Gruß Tommy
Ich hoffe ich habe das jetzt richtig verstanden. Der Schalter soll die Fußbedale ersetzen. Schalter links, emuliert den zweifachen Pedaldruck (Effekt schnell), Schalter Mitte emuliert den Pedaldruck für Effekt aus und Schalter rechts für einfachen Pedaldruck (Effekt langsam).
Da dürfte es ja nicht reichen, einfach einen PIN nach dem Auswerten der Schalterstellung so lange auf HIGH zu setzen bis der Schalter erneut betätigt wird. Ich denke so ein Pedal wird auch wieder los gelassen und nicht permanent drauf getreten . Ich wüsste nicht wie man damit einen doppelten Pedaldruck nachstellen soll.
Darum habe ich folgenden Vorschlag:
//
// Programm zum Emulieren von Tasterbetätigungen über einen Wechselschalter
// Schalterstellungen
// 1 0 1
// Effekt schnell Effekt aus Effekt langsam
// 2 x Taster 1 1 X Taster 2 1 x Taster 1
//
class Timer {
public:
void start() { timeStamp = millis(); }
bool operator()(const uint32_t duration) const { return (millis() - timeStamp >= duration) ? true : false; }
private:
uint32_t timeStamp {0};
};
enum EffectSelection : uint8_t { effectA, effectB, effectsOff };
enum SwitchEffects : uint8_t { on, ready, startWait, wait, waitEnd };
template <size_t N> EffectSelection checkPinState(const uint8_t (&pins)[N]) {
for (size_t i = 0; i < N; ++i) {
if (digitalRead(pins[i]) == LOW) { return static_cast<EffectSelection>(i); }
}
return EffectSelection::effectsOff;
}
template <size_t N> void switchPins(const uint8_t (&pins)[N], uint8_t mask) {
uint8_t bitmask = 1 << (N - 1);
for (size_t i = 0; i < N; ++i) { (mask << i & bitmask) ? digitalWrite(pins[i], HIGH) : digitalWrite(pins[i], LOW); }
}
//
// Konstanten und Variablendefinitionen
//
constexpr uint8_t deviceCheckPins[2] {4, 5}; // Pins am Umschalter
constexpr uint8_t devicePins[2] {6, 7}; // Pins für die Effektschaltung
// Bitmasken zum Schalten der Effektpins
constexpr uint8_t SW_MASK_ALL_OFF {0x00};
constexpr uint8_t SW_MASK_DEV_D {0x02};
constexpr uint8_t SW_MASK_DEV_E {0x01};
constexpr uint32_t PIN_ENABLE_DURATION_MS {200}; // Dauer des emulierten Tasterdrucks in Millisekunden
constexpr uint32_t PIN_WAIT_DURATION_MS {100}; // Dauer zwischen zwei Tasterdrücken in Millisekunden
Timer timer; // Timer für Zeitmessungen erzeugen
//
// Hauptprogramm
//
void setup() {
Serial.begin(115200);
for (auto pin : deviceCheckPins) { pinMode(pin, INPUT_PULLUP); }
switchPins(devicePins, SW_MASK_ALL_OFF);
for (auto pin : devicePins) { pinMode(pin, OUTPUT); }
}
void deviceSelect() {
static EffectSelection prevCheck {EffectSelection::effectsOff};
static SwitchEffects pState {SwitchEffects::ready};
static bool doubleSwitch {false};
static bool blockCheck {false};
if (blockCheck == false) { // Die Abfrage wird blockiert, wenn gerade eine Schaltung erfolgt
EffectSelection check = checkPinState(deviceCheckPins);
delay(50); // Taster entprellen
if (check != prevCheck) { // Es hat eine Schalterbetätigung stattgefunden.
timer.start();
prevCheck = check;
pState = SwitchEffects::on;
blockCheck = true; // Schalterabfrage solange blocken bis Tasteremulation beendet ist
switch (check) {
case EffectSelection::effectA:
Serial.println("Schalte Taster D - Effekt an langsam");
switchPins(devicePins, SW_MASK_DEV_D);
break;
case EffectSelection::effectB:
Serial.println("Schalte Taster D - Effekt an schnell");
switchPins(devicePins, SW_MASK_DEV_D);
doubleSwitch = true;
break;
default:
Serial.println("Mittelstellung -> Schalte Taster E - Effekt aus");
switchPins(devicePins, SW_MASK_DEV_E);
break;
}
}
}
//
// Notwendig für das Ausschalten des HIGH Signals an den entsprechenden Pins
// (Entspricht dem Loslassen eines Tasters) und zum Auslösen des zweiten Tastenrucks (je nach Schalterstellung)
//
switch (pState) {
case SwitchEffects::on: // Warten bis die Zeit für den emulierten Tastendruck abgelaufen ist
if (timer(PIN_ENABLE_DURATION_MS) == true) { // Zeit abgelaufen, Pin wieder auf LOW bringen (= Taster loslassen)
switchPins(devicePins, SW_MASK_ALL_OFF);
// Wenn weiterer Tastendruck notwendig dann Status "startWait" für einen weiteren Durchlauf
pState = (doubleSwitch == true) ? SwitchEffects::startWait : SwitchEffects::ready;
}
break;
case SwitchEffects::startWait: // Warten bis zur nächsten Tastersimulation
timer.start();
pState = SwitchEffects::wait;
break;
case SwitchEffects::wait: // Testen ob die Wartezeit bis zum zweiten Tasterdruck abgelaufen ist
if (timer(PIN_WAIT_DURATION_MS) == true) { // Wenn ja, dann nächsten Tastendruck emulieren
timer.start();
pState = SwitchEffects::waitEnd;
}
break;
case SwitchEffects::waitEnd:
if (timer(PIN_ENABLE_DURATION_MS) == true) { // Nächsten Tastendruck emulieren
switchPins(devicePins, SW_MASK_DEV_D);
timer.start();
doubleSwitch = false;
pState = SwitchEffects::on;
}
break;
case SwitchEffects::ready: blockCheck = false; break;
default: break;
}
}
void loop() { deviceSelect(); }
Das Programm kann hier ausprobiert werden:
Leider hat der Schalter in der Simulation keine Mittelstellung. Darum habe ich das mit zwei Schaltern emuliert. Aus diesem Grund wird die Mittelstellung von beiden Schaltern einmal "angefahren". Die LEDs zeigen die Schaltung der beiden "Geräte" an.
Das Programm hat ein delay(50) zum Entprellen der (des) Schalter(s). Ansonsten kommt es ohne delays aus.
Oder eine einfache Variante mit delays:
#include <Streaming.h>
Print &cout {Serial};
//
// Programm zum Emulieren von Tasterbetätigungen über einen Wechselschalter
// Schalterstellungen
// 1 0 1
// Effekt schnell Effekt aus Effekt langsam
// 2 x Taster 1 1 X Taster 2 1 x Taster 1
//
enum EffectSelection : uint8_t { effectA, effectB, effectsOff };
template <size_t N> EffectSelection checkPinState(const uint8_t (&pins)[N]) {
for (size_t i = 0; i < N; ++i) {
if (digitalRead(pins[i]) == LOW) { return static_cast<EffectSelection>(i); }
}
return EffectSelection::effectsOff;
}
template <size_t N> void switchPins(const uint8_t (&pins)[N], uint8_t mask) {
uint8_t bitmask = 1 << (N - 1);
for (size_t i = 0; i < N; ++i) { (mask << i & bitmask) ? digitalWrite(pins[i], HIGH) : digitalWrite(pins[i], LOW); }
}
//
// Konstanten und Variablendefinitionen
//
constexpr uint8_t deviceCheckPins[2] {4, 5}; // Pins am Umschalter
constexpr uint8_t devicePins[2] {6, 7}; // Pins für die Effektschaltung
// Bitmasken zum Schalten der Effektpins
constexpr uint8_t SW_MASK_ALL_OFF {0x00};
constexpr uint8_t SW_MASK_DEV_D {0x02};
constexpr uint8_t SW_MASK_DEV_E {0x01};
constexpr uint32_t PIN_ENABLE_DURATION_MS {200}; // Dauer des emulierten Tasterdrucks in Millisekunden
constexpr uint32_t PIN_WAIT_DURATION_MS {100}; // Dauer zwischen zwei Tasterdrücken in Millisekunden
//
// Hauptprogramm
//
void setup() {
Serial.begin(115200);
for (auto pin : deviceCheckPins) { pinMode(pin, INPUT_PULLUP); }
switchPins(devicePins, SW_MASK_ALL_OFF);
for (auto pin : devicePins) { pinMode(pin, OUTPUT); }
}
void deviceSelect() {
static EffectSelection prevCheck {EffectSelection::effectsOff};
EffectSelection check = checkPinState(deviceCheckPins);
delay(50);
if (check != prevCheck) { // Es hat eine Schaltebetätigung stattgefunden. // Taster entprellen
prevCheck = check;
switch (check) {
case EffectSelection::effectA:
cout << F("Schalte Taster D - Effekt langsam\n");
switchPins(devicePins, SW_MASK_DEV_D);
delay(PIN_ENABLE_DURATION_MS);
switchPins(devicePins, SW_MASK_ALL_OFF);
break;
case EffectSelection::effectB:
cout << F("Schalte Taster D - Effekt schnell\n");
switchPins(devicePins, SW_MASK_DEV_D);
delay(PIN_ENABLE_DURATION_MS);
switchPins(devicePins, SW_MASK_ALL_OFF);
delay(PIN_WAIT_DURATION_MS);
switchPins(devicePins, SW_MASK_DEV_D);
delay(PIN_ENABLE_DURATION_MS);
switchPins(devicePins, SW_MASK_ALL_OFF);
break;
default:
cout << F("Mittelstellung -> Schalte Taster E - Effekt aus\n");
switchPins(devicePins, SW_MASK_DEV_E);
delay(PIN_ENABLE_DURATION_MS);
switchPins(devicePins, SW_MASK_ALL_OFF);
break;
}
}
}
void loop() { deviceSelect(); }
Hello Kai,
Ganz so ist es nicht, die Taster des Effektgerätes werden jeweils nur einmal gedrückt:
Taster D steuert die Geschwindigkeit zwischen den Stufen Slow und Fast, indem jeder Tastendruck diese umschaltet, also ein Toggle: ist die aktuelle Gewchwindigkeit Slow und der Taster wird gedrückt dann wechselt sie auf Fast, ein weiterer Tastendruck von Taster D wechselt wieder auf Slow, beim nächsten Tastendruck wieder auf Fast usw.
Taster E hält die Geschwindigkeit an, der Tastendruck geht also auf Stop, der nächste Tastendruck wieder zurück usw.
Das Effektgerät kann nicht mit permanenten Schalterpositionen umgehen sondern nur mit Impulsen, ich glaube es löst die jeweilige Funktion des Tasters aus wenn der Taster wieder losgelassen wird (muss ich aber kommende Woche am Gerät mal testen). Deshalb die ganze Übung, da es demnächst nicht mehr durch die Taster sondern durch einen Handschalter mit drei Positionen bedient werden soll
Genau das macht das Programm doch. Eine Schalterstellung für zwei Tastendrücke ( Impulse ) -> Effekt schnell , eine Schalterstellung für einen Impuls -> Effekt langsam an Pin 6 und eine Schalterstellung für einen Impuls -> Effekt aus, an Pin 7.
Es ist jeweils nur eine Schalterbetätigung notwendig.
Wenn ich @hervshahn richtig verstanden habe, braucht es zur Umschaltung von langsam nach schnell nur 1 Impuls. Derselbe impuls würde danach wieder von schnell nach langsam umschalten,
Nach meiner Einschätzung ist das Problem, dass bei der Schalterversion S - 0 - L zwischen S und L auch kurzzeitig der 0 - Zustand auftaucht. Wenn das durch entsprechende Verzögerungen verhindert wird, reagiert das Gerät vermutlich merklich träge auf das Ausschalten..
Oder es werden zwischen S und L zwei Impulse zum Aus und wieder Ein schalten geschickt, was sicher auch nicht gewollt ist.
Da sowieso zwei Eingangspins für den Schalter gebraucht werden:
Wäre 00 = aus ,01 = L, 11 = S eine Lösung? Also ein Schalter mit den Stellungen 0 - 1 - 2 ?
Von der Bedienung besser fände ich aber zwei Schalter: Ein-Aus und S-L
Bleibt die Frage was aktuell passiert, wenn im Zustand Aus ein S-L Umschaltimpuls kommt.
Wird der erfasst und fürs nächste Einschalten gemerkt?
Danke Kai, das hilft mir echt schon weiter, allerdings wird immer nur ein Tasterimpuls benötigt:
Schalterstellung A: 1x Taster D Impuls
Schalterstellung B: 1x Taster E Impuls
Schalterstellung C: 1x Taster D Impuls
Nein, es muss mit Impulsen auf Schalter - Änderungen reagiert werden.
Für mich sind zwei Pedal-/Tastendrücke auch zwei Impulse. Wenn man nur einen Kippschalter verwendet und bei jeder Schalterbetätigung nur ein Impuls gesendet wird, muss man von „Effekt schnell“ immer über „Effekt langsam“ um auf „Aus“ zu kommen und umgekehrt.
Ja, es braucht jeweils nur einen Impuls des gleichen Tasters für die Umschaltung zwischen langsam und schnell, der wechselt bei jeder Betätigung dazwischen hin und her.
Hier mal ein Foto vom Schalter:
Hebel nach links auf Chorale (Langsam): Pol 1 und 3 sind verbunden -> Taster D soll einmal betätigt werden
Hebel in Mittelstellung (Stop): kein der drei Pole sind verbunden -> Taster E soll einmal betätigt werden
Hebel nach rechts auf Tremolo (Schnell): Pol 2 und 3 sind verbunden -> Taster D soll einmal betätigt werden
Das Problem, dass der Schalter zwischen Langsam und Schnell immer über die Mittelstellung "Stop" geht ist korrekt, hab ich heute auch nochmal drüber nachgedacht. Der Sketch müsste das dann in sofern abfangen dass er den entsprechenden Impuls erst dann auslöst, wenn der Schalter eine bestimmte Zeitlang in einer Stellung bleibt, z.B. nach 500ms
Zwei Schalter wären sicher einfacher, aber der einzelne Schalter mit den drei Stellungen ist vorhanden und auch seit sicher 80 Jahren der Standard bei der Steuerung von Leslie Kabinetten und damit auch die entsprechende Bedienung beim Spielen von Hammond Orgeln so eingeübt.
Ja ich glaube das ist so, wenn ich das Gerät mit den Fußtastern bediene. Bei der Bedienung über den oben gezeigten Handschalter tritt das aber nicht mehr auf
Dann dürfte die "einfache" Version ja ausreichend sein:
//
// Programm zum Emulieren von Tasterbetätigungen über einen Wechselschalter
// Schalterstellungen
// 1 0 1
// Effekt langsam Effekt aus Effekt schnell
// 1 x Taster 1 1 X Taster 2 1 x Taster 1
//
#include <Streaming.h>
Print &cout {Serial};
class Timer {
public:
void start() { timeStamp = millis(); }
bool operator()(const uint32_t duration) const { return (millis() - timeStamp >= duration) ? true : false; }
private:
uint32_t timeStamp {0};
};
enum EffectSelection : uint8_t { effectA, effectB, effectsOff };
template <size_t N> EffectSelection checkPinState(const uint8_t (&pins)[N]) {
for (size_t i = 0; i < N; ++i) {
if (digitalRead(pins[i]) == LOW) { return static_cast<EffectSelection>(i); }
}
return EffectSelection::effectsOff;
}
template <size_t N> void switchPins(const uint8_t (&pins)[N], uint16_t mask) {
uint16_t bitmask = 1 << (N - 1);
for (size_t i = 0; i < N; ++i) { (mask << i & bitmask) ? digitalWrite(pins[i], HIGH) : digitalWrite(pins[i], LOW); }
}
//
// Konstanten und Variablendefinitionen
//
constexpr uint8_t deviceCheckPins[2] {4, 5}; // Pins am Umschalter
constexpr uint8_t devicePins[2] {6, 7}; // Pins für die Effektschaltung
// Bitmasken zum Schalten der Effektpins
constexpr uint8_t SW_MASK_ALL_OFF {0x00};
constexpr uint8_t SW_MASK_DEV_D {0x02};
constexpr uint8_t SW_MASK_DEV_E {0x01};
constexpr uint32_t PIN_ENABLE_DURATION_MS {200}; // Dauer des emulierten Tasterdrucks in Millisekunden
constexpr uint32_t PIN_WAIT_DURATION_MS {300}; // Dauer zwischen zwei Tasterdrücken in Millisekunden
Timer checkTimer;
Timer impulseTimer;
//
// Hauptprogramm
//
void setup() {
Serial.begin(115200);
for (auto pin : deviceCheckPins) { pinMode(pin, INPUT_PULLUP); }
switchPins(devicePins, SW_MASK_ALL_OFF);
for (auto pin : devicePins) { pinMode(pin, OUTPUT); }
}
void deviceSelect() {
static EffectSelection prevCheck {EffectSelection::effectsOff};
static bool isPinHigh {false};
EffectSelection check = checkPinState(deviceCheckPins);
if (check != prevCheck && checkTimer(PIN_WAIT_DURATION_MS) == true) { // Es hat eine Schaltebetätigung stattgefunden. // Taster entprellen
prevCheck = check;
checkTimer.start();
impulseTimer.start();
isPinHigh = true;
switch (check) {
case EffectSelection::effectA:
cout << F("Schalte Taster D - Effekt schnell\n");
switchPins(devicePins, SW_MASK_DEV_D);
break;
case EffectSelection::effectB:
cout << F("Schalte Taster D - Effekt langsam\n");
switchPins(devicePins, SW_MASK_DEV_D);
break;
default:
cout << F("Mittelstellung -> Schalte Taster E - Effekt aus\n");
switchPins(devicePins, SW_MASK_DEV_E);
break;
}
}
if(isPinHigh == true && impulseTimer(PIN_ENABLE_DURATION_MS)) {
switchPins(devicePins, SW_MASK_ALL_OFF);
isPinHigh = false;
}
}
void loop() { deviceSelect(); }
Der Übergang zwischen den Schaltstufen wird dadurch überbrückt, dass der Taster nur in einem bestimmten Intervall abgefragt wird. Entsprechend der Schalterstellung wird dann ein Impuls ausgelöst.
Super, Danke Dir!
Das checke ich dann auch kommende Woche mal ![]()
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
Hallo Stefan,
Annahmen 1 und 2 kann ich so bestätigen, zu Annahme 3 muss ich nochmal genau checken aber ich bin mir ziemlich sicher das deine Annahme auch stimmt
Danke nochmals an alle die hier geantwortet haben, und sorry dass ich nicht alle benötigten Infos von vornherein bereitgestellt hatte, aber mir war einfach nicht klar was alles wichtig sein könnte. Die Diskussion hier hat mir sehr geholfen um Klarheit zu bekommen, bin halt nicht erfahren was das alles angeht.
Was die Funktion des Effektgeräts und damit die Logik des Sketches angeht müsste in der Tat der jeweilige Zustand festgehalten werden, wenn ich weiter drüber nachdenke.
Wenn nämlich der Schalter zum Beispiel aus dem Modus "Langsam" auf Stop (Mittelstellung) gestellt wird, und danach aus dem Stop Modus wieder auf "Langsam" gestellt wird, müsste nur der Impuls für Taster E ausgelöst werden (Stop Modus aus), wird der Schalter aber hingegen auf "Schnell" gestellt wird müssten sowohl der Impuls für Taster E (Stop aus) als auch für Taster D (Umstellung von langsam auf schnell) ausgelöst werden, umgekehrt natürlich genauso. Wird also doch noch etwas komplexer...
Das fände ich auch, aber leider habe ich keine Schaltpläne des Effektgeräts (Leslie Simulator) und ich glaube auch kaum dass der Hersteller diese rausrückt. Die einzige Möglichkeit die mir einfällt ist eine indirekte Feststellung des Zustands, da das Gerät diesen mit Leuchtdioden anzeigt: bei "Schnell" blinken sie schnell, bei "Langsam" blinken sie langsam, bei "Stop" leuchten sie dauerhaft. Wie das durch den Arduino ausgewertet werden kann (falls überhaupt) .. noch keine Ahnung