Mehrfache Tastenabfrage

Gast #4811374
Lesenswert?

Ich möchte gerne mittels einem einzigen Taster verschiedene Funktionen 
ermöglichen:

.) Ein mal kurz drücken zb. LED grün leuchten.
.) Zwei mal kurz drücke LED rot leuchten
.) Drei mal kurz drücken led blau leuchten
.) Lange drücken löscht die LED's wieder.
(nur so als Beispiel mal)

Die Tastenabfrage lang/kurz kenne ich bereits. Dazu gibt es ja das 
schöne Beispiel von Peter Dannegger.

Wie allerdings kann ich abfragen wie oft eine Taste kurz hintereinander 
gedrückt wurde und drauf reagieren?
Wie gehe ich das an?
Mir geht's jetzt rein nur um die Tastenauswertung.
Moderator (Firma: Titel) Persönliche Seite #4811428
Lesenswert?

Manfred schrieb:
> Wie allerdings kann ich abfragen wie oft eine Taste kurz hintereinander
> gedrückt wurde und drauf reagieren?
> Wie gehe ich das an?
Mit einem Zähler. Und ein Zähler ist auch schon die einfachste Form 
eines Zustandsautomaten (Statemachine, FSM), weil er sich den Zustand 
vorher merkt und auf einen Impuls hin weitergezählt wird.

> Mir geht's jetzt rein nur um die Tastenauswertung.
Das ist der falsche Ansatz. Denn wenn du immer "nur" einzelne 
Teilprobleme durch Basteln ohne übergreifendes Konzept löst, dann wird 
es bald darauf woanders klemmen...
Gast #4811447
Lesenswert?

THOR schrieb:
> Dann solltest du dich mal über Statemachines informieren.

Würde ich auch vorschlagen. Mal nach "finite Automaten" suchen.

Damit löst man so was ohne Spaghetticode.

Tip zur Implementierung: Die Nummer des aktuellen Maschinenzustands 
einfach für ein "CASE"-Statement verwenden.
#4811516
Lesenswert?

Manfred schrieb:
> .) Ein mal kurz drücken zb. LED grün leuchten.
> .) Zwei mal kurz drücke LED rot leuchten

Soll "Zwei mal kurz drücken" heißen, ein zweites mal kurz drücken oder 
soll rot nur leuchten, wenn zweimal kurz hintereinander ohne längere 
Pause gedrückt wird?

Soll die grüne dann ausgehen, also Wechsel von grün nach rot, oder soll 
rot zusätzlich leuchten?

Eine präzise Zielvorstellung ist schon die halbe Programmierung.
#4811578
Lesenswert?

Manfred schrieb:
> Wie gehe ich das an?

erst mal soltest du definieren, WAS du auswerten möchtest. Das WIE ist 
dann den nächste Schrittt.

Mal dir erst mal ein Impuls-Diagramm auf, welches deine möglichen 
Tastendruck-Varianten darstellt. Mach dir momentan keinen Gedanken über 
Tasten-Prellen, sondern gehe von einer idealen Taste aus. Das 
Tasten-Entprellen kann man "später" auch noch in den Code mit 
"einarbeiten"

Nachdem du darüber etwas nachdenkst, wirst du schon mal wissen, was du 
auswerten möchtest, z.B.

einen Doppel-Klick und einen Dreifach-Klick:

___|--|__|--|______>Aktion#1
___|--|__|--|__|--|______>Aktion#2


z.B. zeigt obiges diagramm, daß:

1. zwischen letztem Tastendruck und einer durchzuführenden Aktion eine 
längere Zeit vergehen muß, als die Zeit zwischen den einzelnen 
Tastendrücken (nennen wir die Zeit mal T-ENDE)

2. die Pause zwischen Tastendrücken (nennen wir sie mal T-ZWISCHEN) 
immer kürzer sein muß als T-ENDE, weil ja sonst fälschlicherweise das 
Ende der eingabe angenommen wird

3. möglicherwiese kann die Tasten-Drück Dauer beliebig lang sein (nenen 
wir sie mal T-DRÜCK), oder sie fällt irgendwann aus einem Timeout raus 
(nenen swir sie mal T-TIMEOUT)

aus 1. und 2 und 3 folgt:
du mußt Zeiten messen können
tastendrücke von..bis ms werden als "kurzer druck" gedeutet
tastendrücke von..bis ms werden als "langer druck" gedeutet
taste loslassen von..bis ms werden als "kurze Pause" gedeutet
taste loslassen von..bis ms werden als "lange Pause" gedeutet
taste loslassen von..bis ms werden als "Eingabeende" gedeutet
es gibt Zeit-Abhängigkeiten zwischen den 5 Tastendrück 
bzw.Loslass-Zuständen

du kannst nun daraus ein Zustands-situation herleiten, und daraus 
wiederuum ein Zustands-Diagramm (oder Graph) konstruieren. da ist dann 
genau ersichtlich, daß du dich z.B. "im Zustand xx" befindest

___|--|__|--|__|--|______>Aktion#2
               ^
               |
            Zustand xx

hier wäre der Zustand den du erreicht hast (mal "lang gesprochen", und 
alle zwischenzustände aufgeführt):

Ruhezustand
Taste wurde kurz gedrückt (kurztatstenzähler=1)
Taste wurde kurz losgelassen (kurztastenloslasser=1)
Taste wurde kurz gedrückt (kurztastenzähler=2)
Taste wurde kurz losgelassen (kurztastenloslasser=2)

da die Aktion / der Zustand "Taste wurde längere Zeit losgelassen" 
(=durchlaufen der Zeit T-ENDE) noch nicht statt gefunden hat, befindest 
du dich also immer noch im "Eingabemodus". Dieser Eingabemodus ist genau 
erst dann abgeschlossen, wenn der Zustand "Taste wurde längere Zeit 
losgelassen" statt gefunden hat.
Gast #4811587
Lesenswert?

>.) Ein mal kurz drücken zb. LED grün leuchten.
>.) Zwei mal kurz drücke LED rot leuchten
>.) Drei mal kurz drücken led blau leuchten
>.) Lange drücken löscht die LED's wieder.
>(nur so als Beispiel mal)

Es läuft auf ein eher bescheidenes HMI (Mensch-Maschine-Schnittstelle) 
hinaus. Überlege dir, wie praxisnah und auch bequem/komfortabal diese 
Tasterdrückerei ist. Die Zustände "kurz gedrückt" und "lang gedrückt" 
kann man noch nachvollziehen. Soviele Platz- und Pinprobleme kann man 
gar nicht haben, dass man nicht noch einen weiteren Taster bzw. zwei 
hinzufügen kann.

Die Antwort entspricht nicht der Fragestellung, aber in erster Linie 
sollte man sich erst fragen, wie sinnig das Ganze werden soll.
#4811591
Lesenswert?

ProjektX schrieb:
> Es läuft auf ein eher bescheidenes HMI (Mensch-Maschine-Schnittstelle)
> hinaus. Überlege dir, wie praxisnah und auch bequem/komfortabal diese
> Tasterdrückerei ist. Die Zustände "kurz gedrückt" und "lang gedrückt"
> kann man noch nachvollziehen. Soviele Platz- und Pinprobleme kann man
> gar nicht haben, dass man nicht noch einen weiteren Taster bzw. zwei
> hinzufügen kann.

das macht genau den wesentlichen Unterschied aus.

a) Mein Tacho am Fahrrad : eher "umständlich"
3 Tasten, -zig veschiedene Einstelloptionen. Ziemliches Gefummel mit 
"drücke Taste 1, Taste 2, Taste 3 <für dies oder jenes>

a) Mein Gurtwickler am Fenster (Rademacher Rollotron): eher 
"komfortabel"
3 Tasten, -zig veschiedene Einstelloptionen. Bedienung ist ziemlich 
intuitiv.
Gast #4811603
Lesenswert?

Wenn es aber jedoch genauso sein soll, wie von dir beschrieben, dann 
nimmst du für den (prellfreien bzw. entprellten) Taster einen 
PinChangeInterrupt mit dem Trigger auf die Flanke, die entsteht, wenn du 
den Taster löslässt.

Wenn der Taster losgelassen wird, inkrementierst du eine Zählvariable 
(zaehler =1, da der Taster bereits einmal gedrückt war) und startest 
deinen Timer (Timerstand = 0).

Bei jeder weiteren Interruptausführung ( und falls zaehler != 0) rufst 
du den aktuellen Timerstand ab. Ist dieser in deinem als "kurz" 
definierten Zeitbereich aufgetreten - sagen wir mal, nicht später als 2 
Sekunden seit der letzten Tasterbetätigung - ist das der zweite 
Tasterdruck. (zahler wird inkrementiert und Timer wird neugestartet). 
Falls die Zeit überschritten wurde, ist das ein komplett neuer Vorgang 
(und du setzt alle Variablen zurück).

Den Vorteiler würde ich ganz grob einstellen, dass zwschen zwei 
Tasterdrücken kein Überlauf stattfinden kann (ansonsten diesen bei der 
Zeitdifferenzrechnung beachten).

Für das lange Drücken musst du eine simple zyklische Pinabfrage in der 
main.c machen (und das auch nur dann, fall zaehler 1 oder 2 oder 3 ist). 
Ebenfalls über einen Timer (z.B. deinen Systemzeit-Timer, ginge aber 
u.U. sogar derselbe). Natürlich musst du erstmal grob anpeilen, was für 
dich "langes Drücken" bedeutet - 1 Sekunde, 10?












und lässt den Timer bei der ersten Flankenänderung starten. (Timerstand 
= 0)
Gast #4811613
Lesenswert?

>Wie allerdings kann ich abfragen wie oft eine Taste kurz hintereinander
>gedrückt wurde und drauf reagieren?

Na wie wohl: Du misst die Zeit zwischen zwei Tastenbetätigungen. Dazu 
musst Du Dein System aber glücklicherweise nicht gleich mit einer 
Echtzeituhr ausrüsten, sondern es reicht schon eine einzige 
Timervariable, die bei einem Tastendruck auf einen bestimmten Wert 
gesetzt und ansonsten in einem festen Zeitraster ("Systemtick", z. B. 
alle 10 ms) heruntergezählt wird (bei Erreichen von Null ist die 
komplette Aktion beendet). Außerdem brauchst Du natürlich noch eine 
Countervariable, die die Tastendrücke zählt - Du willst ja jederzeit 
wissen, wie oft eine Taste gedrückt wurde. Aber damit kannst Du Deine 
Aufgabe dann im Prinzip auch schon lösen.

Viel Spaß und Erfolg!
Gast #4811739
Lesenswert?

Dann habe ich dir bereits den Programmablauf geschrieben, musst diesen 
nur in Code umwandeln.

Darf ich mal fragen, wieso genau dieser Mikrcontroller?
Und welcher Pin genau ist noch frei für den Tastereinsatz?
#4811762
Lesenswert?

ProjektX schrieb:
> Darf ich mal fragen, wieso genau dieser Mikrcontroller?

Welcher ist es denn überhaupt? Oder wurde das schon erwähnt?

> Und welcher Pin genau ist noch frei für den Tastereinsatz?
Mit nem freien ADC-Pin hätte man ja Glück. Aber auch sonst ist noch 
nicht aller Tage Abend.

Manfred schrieb:
> Mehr Eingänge stehen mir nicht zur Verfügung.
> Der Rest wird für Ausgänge genutzt.

Auch da gibt es den ein oder anderen Trick. An eine LED kann man auch 
einen Taster mit dranhängen.
Gast #4811794
Lesenswert?

>ProjektX schrieb:
> Darf ich mal fragen, wieso genau dieser Mikrcontroller?

>>Welcher ist es denn überhaupt? Oder wurde das schon erwähnt?

Zitat, 3. Beitrag: "Oh, sorry, hab vergessen zu erwähnen das ich das 
ganze mittels AVR ATtiny44 realisieren möchte in C." Scheint also ein 
ATTiny44 zu sein :D

Es fehlen aber immer noch etliche Informationen.
#4811946
Lesenswert?

Thomas E. schrieb:
> Selber Schuld.

nö die ersten gingen kaputt, wurden geklaut usw.
Zwischendurch haben die auch mal die Serie geändert, also nichts mit 
selber Schuld ausser das man dieses blöde ständig sich ändernde 
Bedienkonzept nie übernehmen kann.

Thomas E. schrieb:
> Spätestens beim zweiten hättest du doch merken müssen,
> daß du damit nicht umgehen kannst.

später habe ich das Radfahren pausiert

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren