Bitte schreibe einen Sketch, wie Du Dir das so vorstellst. Dann sehen die vielen, die Dir hier im Forum helfen können, wo Du hinsichtlich Deiner Kenntnisse stehst und wie Dir am besten zu helfen wäre.
Das klingt nach einem Automaten (state machine), und zwar nach einem ziemlich komplexen. Schau erst mal nach, was Du dazu findest, und versuche zu verstehen, wie so ein Automat funktioniert.
Vor allem brauchst Du eine Debounce Funktion, die das Prellen des Tasters eliminiert. Dazu gibt's diverse Beispiele (IDE Examples...). Diese Funktion kann (zum Testen) gleich die LED im/am Taster ansteuern, damit man sehen kann, was als Eingabe vom Programm erkannt wurde.
Danach könnte man sowas wie einen Morse-Code definieren, mit kurzen und langen Tastendrücken bzw. Pausen, und den dazu gehörenden Baum zeichnen. Der Automat muß dann erkennen, welchen Ast er durchwandern soll, je nachdem ob die Taste kurz oder lang gedrückt gehalten oder losgelassen wurde. Am Ende von jedem Ast steht dann, was mit den LEDs oder sonstigen Gerätschaften passieren soll.
DrDiettrich:
Das klingt nach einem Automaten (state machine), und zwar nach einem ziemlich komplexen. Schau erst mal nach, was Du dazu findest, und versuche zu verstehen, wie so ein Automat funktioniert.
Vor allem brauchst Du eine Debounce Funktion, die das Prellen des Tasters eliminiert. Dazu gibt's diverse Beispiele (IDE Examples...). Diese Funktion kann (zum Testen) gleich die LED im/am Taster ansteuern, damit man sehen kann, was als Eingabe vom Programm erkannt wurde.
Danach könnte man sowas wie einen Morse-Code definieren, mit kurzen und langen Tastendrücken bzw. Pausen, und den dazu gehörenden Baum zeichnen. Der Automat muß dann erkennen, welchen Ast er durchwandern soll, je nachdem ob die Taste kurz oder lang gedrückt gehalten oder losgelassen wurde. Am Ende von jedem Ast steht dann, was mit den LEDs oder sonstigen Gerätschaften passieren soll.
Oha, du fährst ja gleich richtige Geschütze auf.
Ich befürchte, der TO sollte erst mal die Basics lernen.
Aber das mit dem Entprellen der Taster sollte er schon im Hinterkopf behalten.
HotSystems:
Du solltest erst mal üben, wie ein Taster abgefragt wird.
Wie ein Taster abgefragt wird, ist mir schon klar und die Debounce Funktion ist auch kein Neuland für mich.
Allerdings habe ich noch wenig/keine Erfahrung mit Countern, Case oder "Morse-Code".
Könne mir nicht jemand einen kurzen Beispiel-Sketch schreiben, bei dem ein Taster abgefragt wird und dann je nach Counter-Ergebnis auf einen Case verweist?
Oder is das der falsche Lösungsansatz?
Das klingt nach einem Automaten (state machine), und zwar nach einem ziemlich komplexen
Da kann ich nur "stimmt 100%" zu sagen... Hier müssen in der Tat mehrere Ebenen zusammenspielen. Debouncing, Timer, Counter... Der Hinweis auf Morse-Code war auch goldrichtig. Da beißt man sich gerne mal die Zähne dran aus weil auch noch "Pausen" in dieser Sache berücksichtigt werden müssen. Auch wenn der Wunsch von Hubbert90 vielleicht gar nix damit zu tun hat.
Oder is das der falsche Lösungsansatz?
Ich denke JA, denn im Grunde wäre das ein geeignetes Ding für OOP mit ein paar passenden Methoden - aber darauf will ich hier jetzt erstmal gar nicht eingehen...
vielleicht hilft dir die Funktion pulseIn(pin, state) etwas, mit state HIGH, LOW usw. Wenn du den Taster entprellst (z.B. mit Widerständen und Kondensator) und die richtige Schaltung wählst, bekommst du mit dem pulseIn Befehl eine Zeit, wie lange das state zutrifft. z.B. wenn du den Taster 2 s drückst bekommst du eine bestimmte Zeitzahl, die du dann einfach in einen Integer schreiben kannst. Den Integer kannst du dann mit einer if-clause vergleichen.
dasselbe wendest du dann zum zählen an, erst mit pulseIn messen, prüfen wie lang es ist, dann entscheiden ob da mehr klicks kommen können und einfach nen Integer hochzählen lassen. Wieder mit if prüfen ob die Integervariable größergleich 3 ist und du kannst deine Befehle dahinter schreiben.
Hubbert90:
Wie ein Taster abgefragt wird, ist mir schon klar und die Debounce Funktion ist auch kein Neuland für mich.
Hört sich für mich an, als wenn Du mit simplen mechanischen Tastern noch total auf Kriegsfuß stehst.
Kennst Du den Unterschied in der "Tasterschaltung mit PullUp-Widerstand" und "Tasterschaltung mit PullDown-Widerstand" und kannst Du erklären, ob Du für diese Codezeile im setup()
pinMode(Taster, INPUT);
einen PullUp- oder PullDown-Widerstand in Deiner Schaltung benötigst und auch tatsächlich verbaut hast?
Jurs bringt es auf den Punkt.
Wenn du mit der Tasterabfrage soweit klar kommst, wie du schreibst, warum bringst du das nicht in deinem Sketch.
Wir helfen dir ja, aber du musst auch dein Teil beitragen.
Das Entprellen kannst du ja, wie schon geschrieben, per Hardware losen und später optimieren.
Gibt's keinen fertigen Code für ein Morse-Programm, das Morsezeichen lesen kann? Dann wäre dreimal kurz ein "S", einmal lang ein "T". Den Rest kann man in einen großen switch packen, der die Aktionen zu den empfangenen Zeichen ausführt.
Soooo, ich konnte mein Problem nun fast komplett mit der ClickButton Library lösen.
Allerdings will ich nun die erste 3 LEDs gemeinsam an oder aus schalten wenn ich den Taster 1 Sekunde lang drücke, jedoch springen die LEDs beim aktuellen Code nur in den jeweils anderen Zustand um.
Hier der Sketch:
Allerdings will ich nun die erste 3 LEDs gemeinsam an oder aus schalten wenn ich den Taster 1 Sekunde lang drücke, jedoch springen die LEDs beim aktuellen Code nur in den jeweils anderen Zustand um.
also... eine Lösung "auf die Schnelle" habe ich leider keine - aber mich irritiert an deinem Code so einiges:
In den Unterprogrammen "BlinkKurz()" usw. sehe ich eine Menge "delay(...)". Hiermit blockierts du dir schon jegliche Reaktionen auf irgendwelche Eingaben. Heißt, dass im Moment des Blinkens absolut nix mehr geschehen kann, keine Counter-Increments, keine Tastenabfragen, keine (vielleicht notwendige) parallele Weiterverarbeitung von irgendwas, rein gar nix. Alles wäre absolut "gegen" die von "DrDittrich" angesprochene "State Machine" und seinen Morsezeichen. Hierzu wäre aber ein Code notwendig, der vollkommen frei von jeglichen Blockierungen ist.
Vielleicht wäre es für die Community (und für dich) hilfreich, wenn du mal "genau" auflistest, was du eigentlich "wirklich" mit welchen Eingaben erreichen möchtest (ich selbst steige da noch nicht wirklich hinter). Eventuell findet man im Laufe der Zeit gemeinsam eine perfekte Lösung.
Dein Code sieht aus wie "Die Lösung haben wir schon, nun fehlt uns nur noch das dazu passende Problem" :-]
Woran willst Du z.B. festmachen, ob bei langem Drücken alle LED ein- oder ausgeschaltet werden sollen? Wenn LED1 an ist, und LED2 aus, sollen dann alle ein oder aus geschaltet werden?
Daß delay() jedes Timing durcheinanderbringt, wurde ja schon erwähnt. Schau Dir mal BlinkWithoutDelay an, wie man sowas richtig implementiert. Statt Deiner Funktionen BlinkenKurz usw. brauchst Du einen Automaten, der im Laufe der Zeit seinen Zustand und ändert, und entsprechend die LED blinken läßt. Diesen Automaten packst Du in eine Funktion, die bei jedem Durchlauf von loop() aufgerufen wird, so wie jetzt schon button1.Update().
Der Automat könnte dann z.B. einen Zähler enthalten, der angibt, wie oft geblinkt werden soll. Nach jedem einzelnen Blinken wird der Zähler heruntergezählt, bis er 0 ist. Zusätzlich ein Intervall, das die Länge des Blinkens angibt. Das läßt sich mitsamt dieser Variablen auch in eine Klasse packen, so wie für ClickButton.
Bei den anderen LEDs kann der Code auch vereinfacht bzw. übersichtlicher gemacht werden. Bislang würde es zumindest reichen, statt der Zähler nur bool Variablen zu nehmen, die mit var=!var getoggelt werden, und mit digitalWrite(LED, var) ohne ein if und %2 direkt ausgegeben werden können.
DrDiettrich:
Dein Code sieht aus wie "Die Lösung haben wir schon, nun fehlt uns nur noch das dazu passende Problem" :-]
Woran willst Du z.B. festmachen, ob bei langem Drücken alle LED ein- oder ausgeschaltet werden sollen? Wenn LED1 an ist, und LED2 aus, sollen dann alle ein oder aus geschaltet werden?
Man weiß es nicht so genau, aber in einer Demokratie müßte wohl die Mehrheit entscheiden, und bei 3 LEDs gibt es ja immer eine Mehrheit von mindestens zwei-zu-eins.
D.h. wenn LED1 an ist, und LED2 aus, dann kommt es drauf an, welchen Schaltstatus LED3 hat. D.h. wenn LED3 an ist, steht es zwei-zu-eins für "derzeitig sind die LEDs an", also alle drei ausschalten.
Aber wenn LED3 aus ist, stünde es zwei-zu-eins für "derzeitig sind die LEDs aus", also in dem Fall alle drei einschalten.