Forum: Projekte & Code Tasten Auswertung


von roman65536 (Gast)


Angehängte Dateien:

Lesenswert?

Nein nein nein... keine neue Tasten Entprellung...



Es geht um folgendes ...
man hat ein Uc und ein paar tasten angeschlossen und nun moechte man 
heraus finden ist taste xy gedruckt oder nicht.  Oder wurde diese gerade 
erst gedruckt oder gerade erst losgelassen. Oder ... Man haelt diese 
schon seit laengerem gedruckt..

Alles bekannte Anforderungen an kleine uC Steuerungen mit ein paar 
tasten.
Also habe ich in die tasten gehauen und raus gekommen sind diese 
Routinen, die genau diese Anforderungen erfüllen.
Das ganze ist so programmiert, das man bis zu 32 oder 64 (bei long long) 
tasten solchen Status anfragen kann.

Der Status, die eine Tasten haben kann sind :
RELEASE wenn alles losgelassen ist
RELEASED wenn die Taste seit letzte abfrage Losgelassen wurde
PRESS wenn die Taste gedruckt ist
PRESSED wenn die Taste gedruckt wurde
PRESS_LONG wenn die Taste seit laengerem (Definition von laenge siehe 
source code) gedruckt wurde


Der Status kann mehrere tasten Zustaende haben (PRESSED|PRESS) oder 
(PRESS|PRESS_LONG) :D und folgt der negativen logik. (low active).



Viel Spass und hoffe Euch hilft es genau so,
wie es mir geholfen hat :)
Roman

von Peter D. (peda)


Lesenswert?

roman65536 schrieb:
> Nein nein nein... keine neue Tasten Entprellung...

Hast recht, das Entprellen, also das Wichtigste, macht sie gerade nicht.
Warum?


> man hat ein Uc und ein paar tasten angeschlossen und nun moechte man
> heraus finden ist taste xy gedruckt oder nicht.  Oder wurde diese gerade
> erst gedruckt oder gerade erst losgelassen. Oder ... Man haelt diese
> schon seit laengerem gedruckt..

Jau, dat gibbed allet schon längst, schau Dir mal meine Entprellfunktion 
für 8 Tasten an.
Die hat sogar ne Repeatfunktion und merkt sich den Druck, auch wenn 
schon wieder losgelassen wurde.
Sie benötigt auch deutlich weniger Code, SRAM und CPU-Zeit.


> RELEASED wenn die Taste seit letzte abfrage Losgelassen wurde
...
> PRESSED wenn die Taste gedruckt wurde
> PRESS_LONG wenn die Taste seit laengerem (Definition von laenge siehe
> source code) gedruckt wurde

Deine Abfrage switches_status() liest doch nur den Status und setzt 
nichts zurück. Also wie sollen dann genau nur einmal die Flags gesetzt 
sein?

In meiner Routine erfolgt das Abtasten und das Auswerten dagegen völlig 
unabhängig. Das Main kann die Ereignisflags auswerten und rücksetzen, 
wann es Zeit hat und ist nicht an einen festen Zyklus gebunden.


Peter

von roman65536 (Gast)


Lesenswert?

Hmm..
Das mag ja sein Peter, das deine schneller, kleiner und und und ist... 
Nur was soll man mit einer AVR Assembler routine auf einem Coldfire oder 
ARM ??
oder ... wie werte ich zb. tasten aus, die von einem key/display 
controller kommen so wie sie zb. in den video recordern verbaut sind ?? 
Da kommen die tasten bytes fix entprellt. Und wo es auch mehr als nur 8 
tasten sein koennen ?? oder auswerten von hmm.. sagen wir mal 
touchscreen ?? ist der stift auf der Flaeche oder nicht..

Die eigentlich Arbeit erledigt die switches_update() routine..
der alte wert wird verglichen mit den aktuellen. Per Xor oder "^" in C.
so alla D flip flop danach input und output xor'en und schon hat man 
deltas.
der Rest ist nur noch logisches ORen oder ANDen..

"..merkt sich den Druck, auch wenn
schon wieder losgelassen wurde." Weiss nicht was du meinst.



roman

von Peter D. (peda)


Lesenswert?

roman65536 schrieb:
> Nur was soll man mit einer AVR Assembler routine auf einem Coldfire oder
> ARM ??

Hä?
Das ist doch C.

Beitrag "Universelle Tastenabfrage"

Und ein ARM ist bestimmt auch nicht unglücklich, wenn er weniger 
CPU-Zeit benötigt.
Je nach Portbreite ist dann die Routine natürlich für minimal 16 oder 32 
Inputs.
Das Vertical Counter Prinzip bearbeitet immer alle 8/16/32Bits parallel 
und nicht in einer Loop.


> "..merkt sich den Druck, auch wenn
> schon wieder losgelassen wurde." Weiss nicht was du meinst.

Der Timerinterrupt läuft immer, z.B. alle 10ms und tastet ab.
Die Mainloop ist z.B. für eine Sekunde mit was anderem beschäftigt. Dann 
ruft sie get_key_press() auf und bekommt das Ereignis. Die Taste kann 
derweil schon 0,5s losgelassen worden sein.
Der Trick ist, daß erst get_key_press() das Flag liest und löscht. Jeder 
Tastendruck bewirkt dadurch auch nur genau ein Ereignis. Egal, wann und 
wie oft get_key_press() aufgerufen wird.


Peter

von Martin S. (docmartin)


Lesenswert?

Da muß ich Peter zustimmen: die Bulletproof-Geschichte läuft problemlos 
auch auf einem STM32 (Cortex-M3) und auf einem ARM9 (unter WinCE6) - 
reines C, ohne Spezialitäten, man muß nur die aktuelle Belegung der 
Tasteneingänge abfragen...

Ahoi, Martin

von M. K. (kichi)


Lesenswert?

Martin Schneider schrieb:
> Da muß ich Peter zustimmen: die Bulletproof-Geschichte läuft problemlos
> auch auf einem STM32 (Cortex-M3) und auf einem ARM9 (unter WinCE6)

Ebenfalls auf einem TMS320F2812.

von roman65536 (Gast)


Lesenswert?

Schaut..
Mir hat diese version geholfen. Peter's "C" version kenne ich nicht, 
resp. nicht gefunden in dem Uc.net code Sammlung (nur die asm avr 
version), Peter nehme es nicht persoenlich, es ist manchmal schwer hier 
etwas zu finden. Mir hat meine version geholfen den sie ist universal 
und auch fuer Linux Solaris anwendbar resp. direkt PS/2 codes, Curses 
oder Xwin. Wie schon jemand geschrieben hat.. nicht jede kann bei allen 
moeglichen Applikationen Interrupts verwenden (damit ich nicht sagen 
will, dass pooling besser ist).

Ich moechte doch niemanden schlecht oder besser machen oder 
Programmierer Ego ankratzen. Ich verwende ja auch Peters code Fragmente 
:) wollte lediglich etwas an die Gemeinschaft zurueckgeben. Sollte meine 
version jemanden helfen, take it. wenn nicht.. niemand ist gezwungen es 
runter zu laden.

lg roman

von Peter D. (peda)


Lesenswert?

Wenn ich Deinen Code richtig verstehe, funktioniert er nur dann, wenn 
switches_update() und switches_status() immer genau im Wechsel 
aufgerufen werden. Erfolgt das zu langsam, können Ereignisse verloren 
gehen.

Deshalb war es mir wichtig, das Abtasten und das Auswerten voneinander 
zu entkoppeln.
Es nervt nämlich tierisch bei vielen kommerziellen Geräten, wenn 
Tastendrücke verloren gehen.


Peter

von roman65536 (Gast)


Lesenswert?

Peter,


Ja das ist so..
Bei meiner Applikation wollte ich eigentlich auf das PRESSED losgehen..
dh. mich interessierte eigentlich nicht ob die Taste gedruckt ist (zu 
dem zeitpunkt). Es sollte ein Taste gedrueck werden (was ein Status 
PRESSED|PRESS zurueck gibt) um in ein Menue zu gelangen. Danach muss die 
Taste wieder losgelassen werden und wieder gedruckt werden um weiter im 
Menue etwas zu selektierien etc.

Bei mir laufft das ganze ohne Interrupts, den es je ein grosse loop. die 
delta Erkennung koennte ich verbessern resp. aus dem loop rausnehmen, 
jedoch die 5 verschiedene status muss ich per loop tun.




roman

von Karl H. (kbuchegg)


Lesenswert?

roman65536 schrieb:
> Peter,
>
>
> Ja das ist so..
> Bei meiner Applikation wollte ich eigentlich auf das PRESSED losgehen..
> dh. mich interessierte eigentlich nicht ob die Taste gedruckt ist (zu
> dem zeitpunkt). Es sollte ein Taste gedrueck werden (was ein Status
> PRESSED|PRESS zurueck gibt) um in ein Menue zu gelangen. Danach muss die
> Taste wieder losgelassen werden und wieder gedruckt werden um weiter im
> Menue etwas zu selektierien etc.

Genau für den Fall sind die PeDa Routinen besser geeignet.
Deine Funktionen könnte ich mir bei einem Joystick vorstellen, obwohl 
ich mir nicht sicher bin, ob da nicht direkte Pin Abfrage einfacher 
wäre.

> Bei mir laufft das ganze ohne Interrupts, den es je ein grosse loop. die
> delta Erkennung koennte ich verbessern resp. aus dem loop rausnehmen,
> jedoch die 5 verschiedene status muss ich per loop tun.

Man kann deine Funktionen auch aus einem Interrupt heraus aufrufen. So 
ist das ja auch wieder nicht. Genauso wie man die PeDa Routinen aus der 
ISR isolieren, in eine Funktion packen und aus der Hauptschleife heraus 
aufrufen könnte.

Aber die fehlende Entprellung wäre für die meisten hier ein 
KO-Kriterium.

Die PeDa Routinen haben den Charme, dass
* sie kurz sind
* so gut wie keine Rechenzeit verbrauchen
* irgendein regelmässiger Interrupt, den man mitbenutzen kann in
  praktisch jedem Programm rumlungert
* sobald die ISR aktiv ist, sich keine Gedanken mehr um verlorene
  Tastendrücke machen braucht. Selbst wenn das Programm kurzfristig
  etwas mehr zu tun hat, gehen selbst kurze Tastendrücke nicht verloren.
* sie auch mit den grindigsten Tasten, deren Kontakte ausgeleiert sind,
  klar kommen.
* sie schnell in ein Projekt übernommen, eingebaut und angepasst werden
  können.

Es ist schwer, diese Funktionalität zu toppen. Egal in welcher Richtung. 
In Punkte Codeverbrauch, Resourcenverbrauch, Komfort (sowohl für den 
Anwender als auch für den Programmierer) sind sie so ziemlich das 
Optimium dessen, was man kriegen kann.

von roman65536 (Gast)


Lesenswert?

Tja Karl..

Genau um das ging es auch bei mir ja .. eine Art Joystick,
mit dem ich dann nur noch feststellen wollte ging es rauf/runter oder 
ins menue rein. Und dabei habe ich nur berücksichtigt, das ich die 
gleichen routinen auch fuer das auswerten von einem PT6311 benutzen 
koennte oder etwas anderes.

Da ich leider zu dem Zeitpunkt nichts von der C version wusste und in 
der AVR Code samlung nur die ASM version fand, haute ich selber in die 
tasten.
Es geht doch gar nicht um zu top'en. waere zb. die C version auch dort, 
wuerde ich es meine wahrscheinlich nie programieren.

Zu dem waere es wirklich keine Sache den code zu ergänzen das nix 
verloren geht. Ob das allerdings Sinn macht, ist eine andere Sache... 
den PRESSED|RELEASED zusammen... na ja.

Meine End user (4,7 jh) kommen mit der Version auf alle Faelle ziemlich 
klar, ob jetzt die tasten status per int. oder per polling gesetzt wird, 
ist Ihnen egal, Hauptsache passiert was..
Und mir hat es geholfen.

Irgendwie, kommt es mir vor als nur "privilegierte" leute hier code rein 
stellen koennen... ich zwinge doch niemanden...

BTW: Peter du hast mich auf eine idee gebracht wie ich den loop los 
werden kann. hmmm... cool...

von Peter D. (peda)


Lesenswert?

Da hier schon einige den Code kennen und davon begeistert sind, mag der 
Eindruck entstehen, daß nun alle auf Dich eindreschen. Das ist aber 
bestimmt nicht so gemeint.

Letztendlich wichtig ist, daß eine Lösung zuverlässig arbeitet.
Und schön ist dann, wenn sie mit möglichst wenig Seiteneffekten und 
Ressourcen in andere Projekte einfügbar ist.

Meine Projekte sind wohl etwas kleiner als Deine, daher kein extra 
Tastenkontroller und das Entprellen muß mit drin sein.


Peter

von Karl H. (kbuchegg)


Lesenswert?

roman65536 schrieb:

> Genau um das ging es auch bei mir ja .. eine Art Joystick,
> mit dem ich dann nur noch feststellen wollte ging es rauf/runter oder
> ins menue rein.

OK.
Das ist dann im Eröffnungsposting nicht so recht reübergekommen.

> Irgendwie, kommt es mir vor als nur "privilegierte" leute hier code rein
> stellen koennen... ich zwinge doch niemanden...

Sorry, wenn dieser Eindruck entsteht.
Das wir sicherlich nicht so gemeint.

Das Thema Tastenentprellunf und Auswertung (diesmal mit echten 
Digi-Tastern) ist eines, welches oft genug um restlichen Forum 
auftaucht. Und oft sehen wir dort völlig untaugliche Entprellfunktionen, 
die der Frager nur deswegen eingebaut hat, weil er sie 'irgendwo' 
gefunden hat.
Ich denke, es ist auch in der Codesammlung wichtig abzugrenzen, wo ein 
Code eingebaut werden kann und wo nicht. Wo er Sinn macht und wo nicht. 
Wo es bessere Lösungen gibt und wo nicht.

> BTW: Peter du hast mich auf eine idee gebracht wie ich den loop los
> werden kann. hmmm... cool...

Dann hat es sich schon ausgezahlt :-)

von roman65536 (Gast)


Lesenswert?

Vielleicht liegt es auch an meinem wording...
Ich wollte nicht dass ein Eindruck von Entprellung entsteht. Das thema 
ist ja zur genuege behandelt.
Es geht hier um eine High level Auswertung (oder zu minderst higher 
level :).
dh. Von einem Kontroller ala VFD Kontroller kriegt man eine byte 
sequence mit Tasten bits, die entweder high oder low sind. Den 
Kontroller muss man periodisch auslesen um an diese key byte sequence zu 
gelangen. Jedoch..
So wie der VFD Kontroller arbeitet, sind die tasten schon entprellt und 
ready to use.

Darum auch das Wort "Auswertung" und kein bulletprooved oder Entprellung 
etc...


Meine Routinen stellen dann fest, ob die key's high/low sind oder seit 
dem letztem Durchlauf resp. abfrage Gedruckt worden sind oder wieder 
Losgelassen, oder ist eine taste laenger gedruckt.


roman

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.