Hi,
ich hätte nicht gedacht, dass man sich an so einer Thematik länger als
10min aufhalten kann, aber ich bin mit meinen Denkansätze nicht zu
frieden.
Ich möchte gerne eine Tastendruck "nahezu" sofort auswerten aber auch
noch die Möglichkeit haben ein langes drücken zu detektieren.
ich speichere mir den Zustand des Pins aktuell in 2 Variablen:
aktueller und letzter Zustand.
Somit habe ich das bekannte detektieren von Kanten.
nehmen wir uns nun die methode "&incrementValue()" daher, die auf einen
Knopf/IO gemappt werden soll.
mein Timer aktualisiert "alt" & "neu" alle 10ms.
Somit habe ich also ggf. alle 10ms ein neues RISING oder FALLING.
1
if(RISING){
2
incrementValue();
3
}
Kommt überspringt manche Inputs, weil vom Timing so schnell gedrückt
worden ist, dass bereits wieder FALLING aktiv ist.
1
if(FALLING){
2
incrementValue();
3
}
Ist da zuverlässiger, verwirrt jedoch, wenn man den Knopf fest hält.
Und nun die spannendste Frage, wie baue ich ein
1
...
2
incrementValue();
3
}
für lange Haltezeit ein ohne die anderen beiden Detektionen zu
verlieren?
Grüße Oekel
Hallo,
schau dir die Entprell- und Auswertroutinen von Peter Dannegger (peda)
im Leitartikel an.
Damit kann u.a. man Press, Release oder Short- oder Long-Press und
Release auswerten.
Schöner Nebeneffekt es werden 8 Taster gleichzeitig entprellt!
Keine IDE genannt, kein µC genannt.
Darum ein "schönes" Arduino Beispiel im Anhang.
Die gedrückte Taste wird nach 20ms gemeldet
Der lange Druck nach 1020ms.
Mach was draus.
Die benötigten Libraries habe ich hier schon irgendwann mal gepostet.
Die findest du.
Hallo,
Hier ist noch der Link zum original Artikel "Universelle Tastenabfrage":
Beitrag "Universelle Tastenabfrage"
Weitere Referenzen wirst Du selbst finden.
Arduino Fanboy D. schrieb:> Die benötigten Libraries habe ich hier schon irgendwann mal gepostet.> Die findest du.
Nur die wären interessant gewesen. Der µC ist doch für die Idee völlig
uninteressant.
ansosten tut es mein Code hier auch: :P
HI
>Ich möchte gerne eine Tastendruck "nahezu" sofort auswerten aber auch>noch die Möglichkeit haben ein langes drücken zu detektieren.
Na ja, da gab es mal diese Tasten mit den kleinen Kristall-Kugeln drin.
Die haben schon bei Tastendrücken die Länge des Tastendrucks
vorausgesehen.
MfG Spess
Dein Vorhaben ist überhaupt nicht einfach...
Falls Arduino oder PlatformIO im Einsatz ist, nimm diese Bibliothek:
https://github.com/TOLDOTECHNIK/TTBOUNCE
Da kannst du die Methoden
1
attachClick()
für einen einfachen Klick und
1
attachPress()
für das lange Drücken verwenden.
Die Zeitfenster kannst du jeweils mit
Einfach die Aktion bei kurzem Tastendruck erst nach Loslassen starten
lassen, ansonsten den Beginn des Tastendrucks feststellen und nach der
gewünschten Wartezeit wenn Taste noch gedrückt die Aktion bei langem
Tastendruck starten.
Dabei Flag setzen daß Loslassen nicht zusätzlich die Aktion bei kurzem
Tastendruck startet.
Was mich betrifft finde ich Pedas Lösung optimal weil sich alles im
Hintergrund in einer Timer ISR abspielt. Für meine Projekte zumindest
lässt diese Lösung keine Wünsche offen. Funktioniert absolut zuverlässig
ohne den CPU Durchsatz nennenswert zu belasten. Auch mit Arduino
funktioniert es ohne irgendwelche Probleme. Das Geniale an seiner Lösung
ist, daß der Timer mit seiner ms Zeitbasis die ganze Arbeit erledigt.
Alles andere was der CPU abarbeitet spielt keine nennenswerte Rolle und
kann keinen Einfluß ausüben.
Philipp K. schrieb:> unsigned long lastintervallmillis = millis();> unsigned long changestate = millis();> unsigned long lastdebounce = millis();> unsigned long lastminpulse = millis();
Puh, ne riesen Menge Code und riesen Variablen je Taste. Mußt Du
wirklich einen langen Druck von 49 Tagen erkennen können?
Ich hab meine Tastaturabfrage in einen Process ausgelagert, der alle
50ms durchlaufen wird. Bleibt eine Taste gedrückt wird eine Variable
hoch gezählt, ist die Taste beim nächsten Processlauf nicht mehr
gedrückt, wird die Var auf 0 gesetzt.
Bei Var>=X kann ich also ein Unterprogramm ausführen lassen ...... nur
mal so prinzipiell.
Crazy H. schrieb:> Ich hab meine Tastaturabfrage in einen Process ausgelagert, der alle> 50ms durchlaufen wird. Bleibt eine Taste gedrückt wird eine Variable> hoch gezählt, ist die Taste beim nächsten Processlauf nicht mehr> gedrückt, wird die Var auf 0 gesetzt.> Bei Var>=X kann ich also ein Unterprogramm ausführen lassen ...... nur> mal so prinzipiell.
Ich glaube, wenn ich noch mal genauer drüber nachdenke sind meine
Anforderungen komplett unterschiedlich zu euren.
Ich möchte nicht erkennen, ob eine Taste x_sec gedrückt war und dann ein
einzelnes event abfeuern (ich glaube genau das macht der Code von
(peda)).
Sondern ich möchte so etwas wie ein fast_up fast_down eines Wertes
veranlassen, der gleichzeitig "schnell" auf einer Anzeige gezeigt wird.
Also ähnlich eines (DVD)-Players, der im Play/Pause Modus ist und ein
einzelner Druck auf die jeweilige Taste 1Sec im Film vor oder zurück
spult, das halten der Taste jedoch schnell vorspult und gleichzeitig die
Zeit im Display, wo man sich gerade befindet angezeigt wird.
Meine Vermutung, und nur das bitte ich kurz (falls richtig) zu
bestätigen ist, dass ich dieses Verhalten nur darüber erzielen kann den
jeweilen Entprell-Timer öfters als "normal" azufragen und so auch im µC
die routinen schneller/häufiger zu durchlaufen.
Ist das korrekt, oder gibt es alternativen?
Grüße Oekel
Wenn du lange Tastendrücke von kurzen Tastendrücken unterscheiden können
willst, dann kannst du prinzipiell erst dann dein Event auslösen, wenn
du die Taste (nach Entprellung) loslässt.
Das heißt, die Entprellroutine schaut beim Loslassen der Taste nach, wie
lange sie gedrückt war und löst dann das passende Event aus.
Was du willst, ist eine sich wiederholende Taste. Dazu schaust du in der
Entprellungroutine bei einer gedrückten Taste nach, wie lange sie schon
gedrückt ist. Wenn das lange genug ist, setzt du den Zähler zurück und
löst ein "repeat"-Event aus.
Philipp K. schrieb:> Vielleicht so.. ungetestet. Zählt hoch und wird immer schneller
Ja so in etwa habe ich es auch gelöst. :)
Wenn das the-way-of-doing ist, bin ich bereits zufrieden.
D a v i d K. schrieb:> gibt es alternativen?
In dem Fall kann man mit get_key_press() der Tastendruck auswerten und
mit get_key_rpt() das gedrückt halten. Die Repeatfunktion kann man z.B.
in 10-er Schritten zählen lassen. Es sind auch verschiedene Zeiten für
den Start der Repeatfunktion und das Wiederholen definierbar.
Es wird ein Repeatzähler für alle Tasten gemeinsam verwendet, was in der
Regel ausreichen sollte. Tasten ohne Repeat bzw. andere Pins des Ports
sollte man daher ausmaskieren.
https://www.mikrocontroller.net/articles/Entprellung#Timer-Verfahren_.28nach_Peter_Dannegger.29