Hallo zusammen,
ich habe gerade die Dannegger-Super-Entprellung auf meinem uC
implementiert.
Funktioniert auch gut!
Es ist hier ja so, dass wenn man die Taste drückt, der Tastendruck erst
registriert wird, wenn man wieder losgelassen hat.
Gibt es eine Möglichkeit, es irgendwie so anzupassen, dass das Programm
auf den Tastendruck sofort reagiert. Um z.b. bei einem Menü sofort bei
Tastendruck das nächste Item anzuzeigen, obwohl die Taste noch gedrückt
ist und trotzdem erst zwischendruch ein loslassen registriert werden
muss, bevor der nächste Tastendruck erfolgen kann?
Ich persönlich steige durch die Dannegger-Entprellung sowieso nicht
durch, hab sie genommen, weil sie hier so beliebt ist.
Vladislav schrieb:> OK, noch ein Nachtrag: mit get_key_press läufts, wie ich es meine.> Wofür ist dann get_key_short?
Wenn du zwischen langem und kurzem Tastendruck unterscheiden willst. Wie
lange eine Taste gedrückt wurde, kannst du logischerweise erst dann
feststellen, wenn sie wieder losgelassen wurde oder die Zeit für 'langer
Tastendruck' erreicht ist.
Sorry Karl-Heinz, das versteh ich grad nicht. Für welche Funktion
würdest du get_key_short nehmen.
Den get_key_press für Menü rauf und runter und so
Den get_key_long um z.b. beim hochzählen von größeren Werten den Lauf zu
beschleunigen.
Aber den get_key_short? Hab ich die Funktion grad nicht verstanden.
Vladislav schrieb:> Sorry Karl-Heinz, das versteh ich grad nicht. Für welche Funktion> würdest du get_key_short nehmen.
Ich erfinde jetzt etwas
einzelner kurzer Tastendruck: ein Zahlenwert erhöht sich um 1
einzelner langer Tastendruck: selbiger Wert erhöht sich um 100
get_key_press und get_key_long passen nicht zusammen.
Entweder du verwendest get_key_press
oder du verwendest das Duo get_key_short / get_key_long
get_key_press ist es egal, wie lange gedrückt wird
nur bei short/long wirkt sich das aus.
Karl heinz Buchegger schrieb:> nur bei short/long wirkt sich das aus.
Press und long sind 1A, nur short leuchtet mit nicht ein.
Bei long geht meine LED jetzt an, wenn ich die Taste lange gedrückt
halte, aber bei short geht sie erst an, wenn ich die Taste dann wieder
losgelassen hab.
Karl heinz Buchegger schrieb:> einzelner kurzer Tastendruck: ein Zahlenwert erhöht sich um 1> einzelner langer Tastendruck: selbiger Wert erhöht sich um 100
Ist aber nun gerade ein Fall, bei dem es funktionieren würde. ;-)
Mit dem ersten Tastendruck (Drücken genügt) erhöht man den Wert
um 1. Nach 500 ms ist die Taste immer noch gedrückt, und man
erhöht erstmal um 99, danach weiter um jeweils 100, wenn sie weiter
gedrückt bleibt.
Vladislav schrieb:> Press und long sind 1A, nur short leuchtet mit nicht ein.> Bei long geht meine LED jetzt an, wenn ich die Taste lange gedrückt> halte, aber bei short geht sie erst an, wenn ich die Taste dann wieder> losgelassen hab.
Ja logisch.
Wie soll denn das Programm feststellen ob du mit dem Niederdrücken einer
Taste jetzt kurz oder lang drücken willst?
In a Nutshell: Wenn du keinen Sinn darin siehst, dann verwends einfach
nicht :-)
Ich könnte mir auch dieses Szenario vorstellen:
Benutzer hat die Möglichkeit eine Taste zu drücken. DIe Funktionalität
springt erst dann an, wenn er die Taste loslässt. Bleibt er länger auf
der Taste, so kann er dadurch die Anforderung 'löschen' und die
Funktionalität wird nicht ausgeführt.
Karl heinz Buchegger schrieb:> In a Nutshell: Wenn du keinen Sinn darin siehst, dann verwends einfach> nicht :-)
Nein, um Gotteswillen, ich bin grad begeistert und probier ein bisschen
damit rum.
Wenn ich jetzt aber z.b. eine LED mit REPEAT toggle und eine andere mit
LONG und REPEAT dabei die ganze zeit gedrückt halte, dann wird aus dem
LONG ein PRESS ?
Siehe:
Beitrag "Re: Universelle Tastenabfrage"
Erlaubte Funktionen einer Taste:
- get_key_press()
- get_key_rpt()
- get_key_press() mit get_key_rpt()
- get_key_short() mit get_key_long()
- get_key_short() mit get_key_long_r() und get_key_rpt_l()
Peter
Du benutzt doch hier auch long alleine.
Ich komm da immernoch nicht so ganz hinter, tut mir leid.
Kannst du mir die einzelnen Funktion vielleicht nochmal eben
beschreiben, wieso welche nur zusammen mit anderen gehen?
Ich probiere gerade z.b. mittels zweier gleichzeitig gedrückter Tasten
einen Punkt zurückzuspringen. Aber das will nicht so.
Ich hatte:
1
elseif(get_button_press(BUTTON_1|BUTTON_2))
2
{
3
item=0;
4
}
aber das geht nicht, dann springt er auch bei einer zurück und wenn ich:
Danke Peter für deine Routine, ihre ausführliche Dokumentation und deine
Erläuterung der Funktionen an dieser Stelle nochmal.
Hey Vladislav, diese Zeilen oben müssen aus deinem Post verschwunden
sein...
Ich verstehe das mit den Kombinationen nicht und darüber hinaus probiere
ich die ganze Zeit herum, um mit Taste 1 und 2 aus dem Menü einen Punkt
zurück zu springen. Aber ich bekomme es nicht hin.
Habe mir den Thread zum Entprellen schon durchgelesen...mir ist das auch
klar, dass der uC nicht wissen kann, ob gleich noch eine zweite taste
kommt... es klappt halt nur, wenn ich sie wirklich gleichzeitig drücke.
Gibt es dafür keine Lösung?
Vladislav schrieb:> Ich verstehe das mit den Kombinationen nicht
Dann vergiss fürs erste die Kombinationen. Man braucht sie nur in
Sinderfällen.
> und darüber hinaus probiere> ich die ganze Zeit herum, um mit Taste 1 und 2 aus dem Menü einen Punkt> zurück zu springen. Aber ich bekomme es nicht hin.
Dann zeig dein Programm
> kommt... es klappt halt nur, wenn ich sie wirklich gleichzeitig drücke.
Eine Menüfuhrung, die darauf beruht, dass der Benutzer 2 Tasten
gleichzeitig drücken muss, ist meistens sowieso schlecht. Sowas erfreut
immer wieder die Grobmotoriker.
Spendier deinem Benutzer genügend Tasten oder bau ihm einen Menüpunkt
'Zurück' ein, dann brauchst du nur 3 Tasten.
Danke für deine Antwort! Hier mal ein kurzer Auszug vom Menü:
1
case11:// Menuepunkt 1.1
2
{
3
if(disp_done==FALSE)// Gibt einmal neuen Inhalt auf Display aus
4
{
5
lcd_clear_display();// Loesche Display
6
lcd_jump_to(2,1);// Untere Zeile, 1. Stelle
7
lcd_send_string("MENUE");// Sende String "Menue"
8
lcd_jump_to(1,3);// Obere Zeile, 3. Stelle
9
lcd_send_num(1,TRUE);// Sende 1 mit Dezimalpunkt
10
lcd_send_num(1,FALSE);// Sende 1 ohne Dezimalpunkt
11
12
disp_done=TRUE;// Display-Inhalt fertig
13
}
14
15
if(get_button_press(BUTTON_3))// Wenn Taste 'OK' gedrueckt
16
{
17
disp_done=0;// Beim naechsten mal Display beschreiben
18
item=12;// Menuepunkt auf 1.2 (weiter)
19
}
20
elseif(get_button_press(BUTTON_1|BUTTON_2))// <- PROBLEM HIER!
21
{
22
item=10;// Menuepunkt auf 1.0 (zurueck)
23
disp_done=0;// Beim naechsten mal Display beschreiben
24
}
25
26
break;
27
}
So sieht ein Menüpunkt aus.
Ich habe leider nur drei Tasten, da komm ich nicht drum herum. Daher ist
meine Tastensteuerung etwas eingeschränkt...
Ich würde daher gerne mit BUTTON_1 und BUTTON_2 gleichzeitig einen Punkt
zurückspringen, aber nunja, die Problematik ist mir bekannt...der uC
kann nicht wissen, was kommt.
Es geht halt, wenn ich wirklich gleichzeitig:
Vladislav schrieb:> die Problematik ist mir bekannt...der uC> kann nicht wissen, was kommt.
Dann ist Dein Versuch in etwa so erfolgreich, wie einen Gegenstand nach
oben fallen lassen zu wollen.
Du mußt Dir erstmal einen Plan machen, welche Betätigungsmöglichkeiten
Du hast und wie Du sie verwendest.
Einfach drauflos programmieren und merken, da fehlt ne Taste, ist der
falsche Weg!
Du hast mit 3 Tasten z.B. folgende Möglichkeiten, die von einem MC ohne
Hellsehen eindeutig erkannt werden können:
Ich kann also vom normalen Programm in den Menüpunkt 1.0 springen und
von der untersten Ebene überall wieder ins Programm - vorzugsweise mit
LINKS+RECHTS
Mal angenommen ich bin im Punkt 2.0, dann kann ich mit mit LINKS
(get_button_press (BUTTON_LINKS) ins Menü 1.0 und mit RECHTS
(get_button_press (BUTTON_RECHTS) in 3.0
Will ich aber jetzt zurück zum Programm mit gleichzeitigen Druck von
LINKS+RECHTS, dann nimmt der uC natürlich den normalen Befehl für RECHTS
oder LINKS...oh man, 3 Tasten sind echt scheisse, aber ich kann das
nicht ändern.
Was kann ich hier tun? Ich bin echt ratlos!
Vladislav schrieb:> Will ich aber jetzt zurück zum Programm mit gleichzeitigen Druck
Nochmal:
gleichzeitiges Drücken vom Benutzer zu verlangen ist praktisch IMMER
Mist!
Denn das kriegt kein Mensch hin.
Irgendeine der beiden Tasten kommt immer früher! Da kannst du als
Programmierer nichts dagegen tun.
> von> LINKS+RECHTS, dann nimmt der uC natürlich den normalen Befehl für RECHTS> oder LINKS...oh man, 3 Tasten sind echt scheisse, aber ich kann das> nicht ändern.
Dann musst du das Menüsystem so umbauen, dass du nicht darauf angewiesen
bist, dass 2 Tasten gleichzeitig gedrückt werden müssen!
> Was kann ich hier tun? Ich bin echt ratlos!
Im einfachsten Fall verzichtest du darauf, dass der Benutzer mit
irgendeiner Sonderkombination wieder in den normalen Programmlauf kommt
sondern zwingst ihn, dass er sauber über das Hauptmenü aussteigt.
Eine Variante davon zwingt den Benutzer gar nicht, dass er das selber
macht, sondern das Programm bricht nach x Sekunden ohne Benutzereingabe
das Menüsystem ab und geht selbsttätig zurück.
Du kannst ihm auch im Menü einen Menüpunkt 'Exit' anbieten, den er
anwählen muss um direkt aus einem Submenü wieder in den normalen
Programmlauf auszusteigen.
Du kannst die Taste für 'Auswahl' mit einer Sonderfunktion für 'langen
Tastendruck' versehen und wenn das passiert erfolgt der Ausstieg und
lebst damit, dass zunächst eine Funktion mehr oder weniger ausgewählt
wird, die dann durch den langen Tastendruck abgebrochen wird.
Aber eines solltest du auf keinen Fall tun: Ohne Planung und Überlegung
wie das Konzept deiner Benutzersteuerung funktionieren soll dich
hinsetzen und drauflos programmieren. Denn das geht mit Sicherheit
schief.
> oh man, 3 Tasten sind echt scheisse
3 Tasten reichen völlig aus, siehe die ganzen Menüsysteme die auf einem
einzigen Drehencoder mit Tastfunktion basieren. Nur muss man sich im
Vorfeld überlegen, wie die Menüsteuerung funktionieren soll.
Was spricht z.B gegen einen Punkt "zurück" in jedem Menü?
Jedes Menü kommt mit 2 Pfeiltasten/oder Encoder und einer Enter Taste
aus. Und das kann auch jeder bedienen, man muss sich ja nix merken
Karl heinz Buchegger schrieb:> gleichzeitiges Drücken vom Benutzer zu verlangen ist praktisch IMMER> Mist!
Naja. Ist eine Frage der Definition von "gleichzeitig". Ich habe
lange Zeit die Emulation der mittleren Maustaste (die bei X11-
Programmen ja seit Jahr und Tag üblich war) durch gleichzeitiges
Drücken beider Tasten einer 2-Tasten-Maus benutzt, das geht schon.
Man muss halt eine Karenzzeit einplanen, innerhalb derer beim Drücken
der ersten Taste der Zustand von "nicht gedrückt" nach "unentschlossen"
wandert, und erst nach dem Timeout wechselt er in "eine Taste gedrückt"
oder "zwei Tasten gedrückt". Für die besagte Maustastenemulation
waren glaub' ich 50 ms Karenzzeit ein sinnvoller Wert, wenn die
mechanische Konstruktion der Tasten schlechter ist als bei einer Maus,
würde ich auf 100 ms gehen. In dieser Zeit schafft es ein Normal-
sterblicher durchaus, beide Knöpfe gedrückt zu halten.
Volker Zabe schrieb:> Ich glaube , ich würde die Variante "3 Tasten kurz/lang" wählen.
Ich habe jetzt auch erstmal die Kombination kurz/lang.
Jetzt ist es so: LINKS+RECHTS lang gedrückt, Menü zurück, geht auch,
solange ich nicht NACH LINKS und NACH RECHTS mit get_key_PRESS sondern
mit SHORT mache, was natürlich zur Folge hat, dass der nächste Punkt
erst kommt, wenn man die entsprechende Taste wieder los lässt,
währenddessen die lang gedrückten aufs Drücken reagieren und nicht aufs
loslassen.
GRRR...
Vladislav schrieb:> Volker Zabe schrieb:>> Ich glaube , ich würde die Variante "3 Tasten kurz/lang" wählen.>> Ich habe jetzt auch erstmal die Kombination kurz/lang.>> Jetzt ist es so: LINKS+RECHTS lang gedrückt, Menü zurück, geht auch,> solange ich nicht NACH LINKS und NACH RECHTS mit get_key_PRESS sondern> mit SHORT mache, was natürlich zur Folge hat, dass der nächste Punkt> erst kommt, wenn man die entsprechende Taste wieder los lässt,> währenddessen die lang gedrückten aufs Drücken reagieren und nicht aufs> loslassen.>> GRRR...
Du versuchst krampfhaft eine 'Do what I mean' Steuerung zu bauen.
Das funktioniert nicht.
Entweder du löst deine Aktionen aus, wenn die Taste niedergedrückt wird.
In dem Fall musst du damit rechnen, dass der Benutzer genau das
eigentlich gar nicht wollte. Da dein Programm aber nicht hellsehen
kann wie lange der Benutzer die Taste noch gedrückt halten wird,
läufst du in das Problem, dass du eine Aktion die eigentlich schon
stattgefunden hat, bei anhaltend langem Tastendruck wieder rück-
gängig machen musst, bzw. das ganze Menüsystem so aufzubauen, dass
dieser vom Benutzer eigentlich nicht gewollte Tastendruck keinen
'Schaden' anrichtet.
Oder du löst die Aktion erst beim Loslassen (oder überschreiten einer
Zeitbegrenzung) aus.
Dann hast du natürlich das Problem, das es für den Benutzer so
aussieht: Er drückt eine Taste und zunächst mal passiert nichts,
weil die Aktion ja erst beim Loslassen angestossen werden kann, weil
ja beim Niederdrücken noch nicht feststeht, ob das ein kurzer oder
ein langer Tastendruck werden wird.
Die eierlegende Wollmilchsau, die auch noch zukünftige Aktionen des
Benutzers erraten kann, existiert nun mal nicht.
Jörg Wunsch schrieb:> Man muss halt eine Karenzzeit einplanen, innerhalb derer beim Drücken> der ersten Taste der Zustand von "nicht gedrückt" nach "unentschlossen"> wandert, und erst nach dem Timeout wechselt er in "eine Taste gedrückt"> oder "zwei Tasten gedrückt". Für die besagte Maustastenemulation> waren glaub' ich 50 ms Karenzzeit ein sinnvoller Wert, wenn die> mechanische Konstruktion der Tasten schlechter ist als bei einer Maus,> würde ich auf 100 ms gehen. In dieser Zeit schafft es ein Normal-> sterblicher durchaus, beide Knöpfe gedrückt zu halten.
Schon klar. So oder so ähnlich haben wir das wohl damals alle gemacht,
als die ersten 3-Tasten Mäuse aufgekommen sind.
Aber mit dem, was in der PeDa Entprellung vorhanden ist, ist das ohne
zuätzlichen Programmieraufwand nicht möglich. Die ist nicht darauf
ausgelegt, dass mehrer Tastendrücke 'gleichzeitig' einen weiteren
virtuellen Tastendruck ergeben.
Karl heinz Buchegger schrieb:> Aber mit dem, was in der PeDa Entprellung vorhanden ist, ist das ohne> zuätzlichen Programmieraufwand nicht möglich.
Naja, es geht schon. Ist aber wirklich keine schöne Bedienung.
So, ich muß mich korrigieren.
Ohne Timeout ist das nun auch für Grobmotoriker bedienbar.
Dafür ist ne extra Funktion hinzugekommen, get_key_common().
Hier der Code:
Beitrag "Universelle Tastenabfrage mit 2 Tastenerkennung"
Peter
Peter Dannegger schrieb:
> Man kann auch auswählen, ob der Druck beider Tasten innerhalb einer> bestimmte Zeit erfolgen soll (#define TIMEOUT)
Wo wird denn im Quelltext der Wert von TIMEOUT ausgewertet? Also wo wird
berücksichtigt, ob ich 10 oder 100 oder 1000 eingebe?
Ansonsten prima! Die Funktion fehlte noch - deine Tastenentprellung ist
wirklich der Hammer, PeDa! Danke sehr!
Heribert schrieb:> Wo wird denn im Quelltext der Wert von TIMEOUT ausgewertet? Also wo wird> berücksichtigt, ob ich 10 oder 100 oder 1000 eingebe?
TIMEOUT entscheidet nur zwischen mit/ohne.
Die Zeit steht in:
Hallo zusammen!
Ich habe die Entprellung grad bei mir ebenfalls mal mit eingebunden!
Peter, großes LOB!!! Sehr gut!!!
Ne Frage habe ich noch. Ich werde die Entprellung hauptsächlich zur
Menüsteuerung nutzen. Jetzt mache ich zum Beispiel während des Betriebs
mit langem Tastendruck der einen Taste das Menü auf. Vorher wird auf
keine Tasten reagiert.
Mir fällt dabei auf, dass wenn ich jetzt beispielsweise vorher bereits
eine andere Taste mal gedrückt habe, sich der uC das ja merkt.
Es passiert während des Betriebes nichts, da die Taste nicht abgefragt
wird.
Wenn ich aber jetzt ins Menü gehe und die Taste ab da eine Funktion hat,
dann fragt er ja den Status ab und hat im Speicher noch, dass die Taset
gedrückt worden war und führt das dann auch direkt aus.
Kann man das umgehen?
Danke schonmal,
Gerd
Gerd schrieb:> Kann man das umgehen?
Ohne bisher ein Menü realisiert zu haben: beim Öffnen des Menüs
get_key_press & get_key_rpt einmalig aufrufen und das Problem sollte
sich erledigt haben.