Forum: Compiler & IDEs Entprellen und trotzdem schnell reagieren


von Helge Suess (Gast)


Lesenswert?

Hallo zusammen!

Ich habe versucht, den von Peter Dannegger vorgestellten Algorithmus zum 
Entprellen für meine Anwendung zu adaptieren.

Meine Anforderungen:
Ich will ohne viel Verzögerung auf die erste Flanke einer gedrückten 
Taste reagieren können. Das danach folgende Prellen soll unterdrückt 
werden. Ich muss auch wissen, wann eine Taste losgelassen wurde (Das ist 
nicht zeitkritisch).

Nun haben aber fast alle Formen des Entprellens zur Folge, dass die 
Taste erst als stabil erkannt wird, wenn sie eine Zeit lang ihren 
Zustand behält. Das ist ja auch gut so, wenn man mit Störungen auf der 
Leitung rechnen muss. In meinem Fall kann ich annehmen, dass ich solche 
Störungen nicht habe (und wenn, dann kann ich damit leben).

Lässt man den Algorithmus im Simulator laufen fällt auf, dass der erste 
Tastendruck so behandelt wird wie ich mir das vorstelle. Die beiden 
Zähler sind nämlich noch mit 0 initialisiert. In allen folgenden 
Aufrufen stehen sie beide auf 1 für eine Taste. Das bewirkt, dass erst 
die 4 Zyklen durchlaufen werden bis die Taste als gültig erkannt wird.

Wie kann man das Verhalten ändern ohne dem Algorithmus seine Eleganz und 
Kompaktheit zu nehmen?

Wie erkennt man dass eine Taste losgelassen wurde?
Ich habe folgende Zeile am Ende der Tastenauswertung eingefügt:
1
key_release = key_press ^ i;
Die gesetzten Bits repräsentieren die Tasten, die losgelassen wurden.

Danke schon mal für eure Ideen,

Helge ;-)=)

von Peter D. (peda)


Lesenswert?

Was stören Dich an 30ms?

Der Mensch reagiert typisch erst nach 200ms auf ein erwartetes Ereignis:

http://wdw.prosieben.de/lifestyle_magazine/galileo/themenarchiv/25791/


Du kannst auch das Abfrageintervall verkleinern.
2ms sollten noch ausreichen bei nicht allzu großen Tastern.
Das sind dann nur noch 8ms Verzögerung.


Peter

von Gast (Gast)


Lesenswert?

Reagier einfach auf einen PinChange oder stell den Timer schneller ;-)

von Bernhard M. (boregard)


Lesenswert?

Ich habe das Vorgehen schon mal im 
Beitrag "Entprellung (Hardware)" beschrieben:

Ein Problem der Entprellung kann sein, daß durch Alterung der
Tasterkontakte die Prellzeit größer wird.
Ich hatte das mal bei Telefonen (ISDN) beim Gabelschalter, weil dann
beim Abheben durch prellen gleich wieder aufgelegt wird...
Ältere Schalter konnten da durchaus mehrere 10ms nachprellen, so daß ein
Entprellen von mind. 100ms notwendig war, allerdings musste aufgrund der
max. Verzögerung nach 10ms reagiert werden.
Hardwareentprellung kommt bei Massenproduktion nicht in Frage (zu
teuer), also musste in Software dynamisch entprellt werden:
1) nach einer Tastenänderung Tastenzustand merken und 10ms warten,
2) ist der Tastenzustand nach 10ms UNgleich dem gemerkten ->
Tastenänderung ignorieren und auf nächste Änderung warten (dann weiter
bei 1))
3) ist der Tastenzustand nach 10ms gleich dem gemerkten ->
Tastenänderung dem System mitteilen und die nächsten 100ms (ich hatte
dmals sogar 1sec.) NICHT mehr auf Tastenänderungen reagiren.
4) ist nach Ablauf dieser Zeit der Tastenzustand ungleich dem dem Zustan
von 3) dann das ganze weiter bei 1)
5) ansonsten warten auf die naächste Tastenänderung.

Klingt jetzt komplizierter als es ist...ich habe das vor ~15 Jahren auf
8051 und später auf 6811 implementiert...



Drücken und loslassen behandelt man auch nicht separat, deshalb wird 
oben auch immer von "Zustand" gesprochen, dieser Zustand wird nach dem 
Entprellen auch weitergegeben...
Mit dem Algorithmus kannst Du in sehr kurzer Zeit reagieren...allerdings 
gibt es die lange Wartezeit als "Totzeit" zwischen zwei Ereigneissen...

von Heiko_S (Gast)


Lesenswert?

Hallo zusammen!
Ich habe meine eigene Routine gebastelt (konnte nicht zwei Jahre auf 
Peters Programm warten) und habe folgenden Algorithmus genommen:
Interrupt auf negative Flanke -> Interruptroutine schaltet eine 
Verzögerung von 30 msec ein (Timer der alle 1 msec einen Interrupt 
erzeugt) und den Interrupt aus -> nach Ablauf der Verzögerungszeit wird 
der momentane Tastenzustand übernommen und wenn Sie gedrückt ist, wird 
der Interrupt auf positive Flanke wieder eingeschaltet. Sollte nun der 
Interrupt erneut generiert werden, kann man davon ausgehen, das die 
Taste released wurde. Funktioniert auch mit älteren Tastern und bisher 
ohne Probleme.
Leider muss dafür nicht nur der I/O Interrupt sondern auch ein Timer 
Interrupt programmiert werden. In meinem Fall nutze ich solch einen 
Timer Interrupt für alle möglichen Verzögerungen die man so überwachen 
muss. Der Vorteil ist, das ein Programm weiterlaufen kann und nur die 
Status-Flags von Tasten oder ähnlichem im "main" abgefragt werden 
müssen. Setze ich im übrigen auch erfolgreich im ARM Umfeld ein.

Nur so als Anregung!

von Peter D. (peda)


Lesenswert?

Bernhard M. wrote:

> Ich hatte das mal bei Telefonen (ISDN) beim Gabelschalter, weil dann
> beim Abheben durch prellen gleich wieder aufgelegt wird...
> Ältere Schalter konnten da durchaus mehrere 10ms nachprellen, so daß ein
> Entprellen von mind. 100ms notwendig war, allerdings musste aufgrund der
> max. Verzögerung nach 10ms reagiert werden.

Wozu das?
Ich kenne keinen, der innerhalb 10ms den Hörer abnehmen und zum Ohr 
führen kann.
Auch kenne ich keinen Anbieter, der die Gebühren 10ms genau abrechnet.


> Klingt jetzt komplizierter als es ist...ich habe das vor ~15 Jahren auf
> 8051 und später auf 6811 implementiert...

Ja, man kann es eben auch kompliziert machen.

Ich mags aber lieber einfach:
Ich taste 4* auf Gleichheit ab und das für 8 Tasten gleichzeitig.
D.h. ob eine Taste oder 8 ist in CPU-Zeit und Codebedarf kein 
Unterschied.
Und auf nem 32Bit ARM wärs dann für 1..32 Tasten gleich.

Die logischen Operationen haben nicht nur den Vorteil der gleichzeitigen 
Bearbeitung entsprechend der Bitbreite, sondern erzeugen auch sehr 
effizienten und kleinen Code. Es sind ja in der Entprellroutine 
keinerlei Tests und Sprünge nötig.


Peter

von mr.chip (Gast)


Lesenswert?

Das ist ja wohl nicht allzu schwierig: Reagiere auf die erste Flanke des 
Signals und füge dann eine Totzeit ein, in der kein weiteres Signal 
akzeptiert ist.

von Bernhard M. (boregard)


Lesenswert?

@Peter:

ja, es gibt keinen Anbieter, der das so genau berechnet. Aber das war 
damals für die Post (jetzt Telekom), das Hauptproblem war / ist, das im 
ISDN die Verbindung nicht (wie im analogen Telefon) vom abnehmenden 
Telefon hergestellt (bzw. der Audiokanal durchgeschaltet) wird, sondern 
von den beteiligten Anlagen. Anforderung war, daß in 100ms die 
Verbindung stehen muß, da wurde an jeder Stelle optimiert.
Unabhängig davon war eine maximale Verzögerung durch Entprellen 
vorgegeben, die lag glaube ich bei 20ms.
Und "den Hörer zum Ohr führen"... nun in Call Centern, die zumindest 
damals diese Telefone benutzten, wurde Headset und externer 
Gabelschalter (oft als Fußschalter) benutzt.

Ich weiß, für Hobbyanfoderungen ist das übertrieben kompliziert...

@mr.chirp:
Reagieren auf die erste Flanke geht nur, wenn Dir keine Störungen eine 
Flanke auslösen können.

von Helge Suess (Gast)


Lesenswert?

Hallo zusammen!

Danke für die Anregungen. Ich steuere einen Auslöser einer Kamera. Dazu 
habe ich einen Mikrotaster in einem Griff. Der Griff ist von der Kamera 
selbst hermetisch getrennt. Daher sende ich die Ereignisse aus dem Griff 
optisch in das Gehäues in dem die Kamera eingebaut ist.

Entprellung in Hardware habe ich mir auch angesehen. Das kostet locker 
um die 40-60ms und ist wenig flexibel. Ausserdem braucht es Platz und 
Strom.

Durch meine signal-Strecke habe ich einige Verzögerungen:
Taste entprellen
Signalübertragung
Signal in Schaltzustand an der Kamera wandeln

Ich möchte nur nicht, dass dadurch eine teure Kamera eine 
Auslöseverzögerung eine billigen Kompaktknipse bekommt.

Ich habe insgesamt 7 Tastenzustände. Die übertrage ich gemeinsam als 1 
byte seriell. Das passiert ohne viel zusätliche Absicherung weil ich 
praktisch nur einen Optokoppler mit etwas mehr Abstand habe (max. 30mm 
in einem Rohr durch 2 Glasfenster). Ob die Übertragung so funktioniert 
und welche Geschwindigkeit ich maximal erreiche muss ich noch austesten. 
Etwas komplexer macht die Tatsache, dass es 4 Taster gibt die jeweils 
paarweise einen Drehimpulsgeber simulieren (immer eine Taste für links 
drehen, eine für rechts).
Das bedeutet, dass ich die Tastenzustände dafür in zwei versetzte 
Schaltzustände umsetzen muss (je nach Richtung versetzt). Da bin ich 
noch am Überlegen wie ich das elegant löse. Momentan überlege ich mir 
gerade eieen Ringpuffer, der die Zustände speichert und über einen Timer 
abgearbeitet wird damit ich die Schaltverzögerung des Drehgebers 
erreiche. Die anderen Tasten kann ich direkt ohne weitere Verzögerung 
zum Schalten verwenden.

Ein weiterer Punkt ist dann auch noch der Strombedarf des Senders. Der 
soll es mit einer Knopfzelle (CR2032) lange aushalten. Besonders, wenn 
länger nichts passiert. Da habe ih mir auch schon ein Stromsparkonzept 
überlegt.

Helge ;-)=)

von Sebastian DGJ (Gast)


Lesenswert?

Hallo,

@Helge
warum eigendlich zum Entprellen immer ERST warten und DANN die 
zugehörige Anwendung ausführen?
Wenn man diese nach dem ersten Tastenpegelwechsel sofort ausführt, aber 
anschließend dafür sorgt, daß die zugehörige Anwendung aufgrund des 
Prellens (= anschließende "wilde" Pegelwechsel) nicht noch einmal, also 
nicht mehrmals ausgelöst wird, mußte das doch auch gehen, oder?
Vielleicht könnte man beim ersten Pegelwechsel, wenn die Anwendung 
ausgelöst wird, einen Timer starten, der bis zu dessen Ablauf ein 
weiteres Auslösen verhindert (ZB in dieser Zeit das Tasten-polling 
überspringen).
Allerdings müßte hierzu sichergegengen werden, daß kein Pegelwechsel 
durch (EM-) Störungen auftritt, d.h. aufgrund irgendeiner anderen 
Ursache als die des Tastendrucks.

Sebastian ;-)

von Gast (Gast)


Lesenswert?

>warum eigendlich zum Entprellen immer ERST warten und DANN die
>zugehörige Anwendung ausführen?

Keine schlechte Idee: eigentlich :-)

Eine andere Möglichkeit wären Hall-Schalter, der per Magnet aktiviert 
werden. Magnetfelder prellen nicht - behaupte ich mal. Zudem haben die 
Hallsensoren meistens eine Hysterese.

von Sebastian DGJ (Gast)


Lesenswert?

>Eine andere Möglichkeit wären Hall-Schalter, der per Magnet aktiviert
>werden. Magnetfelder prellen nicht - behaupte ich mal. Zudem haben die
>Hallsensoren meistens eine Hysterese

Wenn die mechanische Konstruktion gut genug ist, um den Hall-Schalter 
präzise auszulösen, sollte das auch gehen. Ist natürlich etwas 
aufwändiger.

Nochmal zum Tastenentprellen:
Man muß berücksichtigen, daß eine menschlich bediente Taste 2 mal 
prellt:
1. Beim Drücken und 2. beim Wieder-Loslassen. Meine o.g. Idee hatte ich 
mal verwirklicht; aber beim Wieder-Loslassen (=fallende Flanke, wenn 
Taste im high-active-style verdrahtet), hat gut funktioniert. Will man 
sofort beim Tastendruck die Applikation starten (das habe ich aber noch 
nicht praktisch getestet), muss natürlich dafür gesorgt werden, daß 
diese beim Wieder-Laslassen nicht nochmal ungewollt ausgelöst wird. Zum 
Beispiel (high-active-style-Taste):
1. An steigender Flanke: Applikation auslösen, Timer auf ca 30-100ms 
starten
2. Während Timer läuft, Tasten-polling weglassen (=Tastenpegel 
ignorieren)
3. Wenn Timer abgelaufen: bei erster fallenden Flanke Timer nochmal 
starten
4. Wie 2.

Sebastian

von Simon K. (simon) Benutzerseite


Lesenswert?

Ihr wisst aber schon, dass das Prellen beim Drücken/Loslassen (nahezu) 
identisch ist. Auch beim Loslassen hat man eine steigende Flanke.

Und das erklärt auch warum man erst wartet und dann die Anwendung 
ausführt: Weil erst nach einer bestimmten Zeit der Status des 
Schalters/Tasters bekannt ist.

von Karl H. (kbuchegg)


Lesenswert?

Das lässt sich aber lösen.

Erkennt man eine steigende Flanke (Taster high aktiv),
so gilt das als Tastendruck.
Anschliessend wird die Prellzeit abgewartet in der Flankenwechsel
ignoriert werden

Erkennt man eine fallende Flanke (High aktiver Taster losgelassen)
so gilt das als Loslassen und danach wird wieder die Prellzeit
abgewartet und Flankenwechsel ignoriert.


Der springende Punkt ist ganz einfach der, dass nach dem Erkennen
eines Flankenwechsels erst mal eine Zeitlang alles ignoriert wird,
was denn so am Eingang passiert.

Der Nachteil: Jeglicher kleiner Spike führt zum Auslösen des
Mechanismus. Und wenn man dann auch noch Buch darüber führt,
ob die Taste jetzt gedrückt oder losgelassen ist, dann bringt
ein Spike in dieser Einfachvariante diese Buchführung
durcheinander. Aber auch das ist lösbar: Nach dem Ablaufen
der Prellzeit nachsehen in welchen Zustand der Eingang jetzt
ist und mit dem Zustand vergleichen in dem er sein sollte.

von Sebastian DGJ (Gast)


Lesenswert?

@Simon
>Ihr wisst aber schon, dass das Prellen beim Drücken/Loslassen (nahezu)
>identisch ist. Auch beim Loslassen hat man eine steigende Flanke.

Klar. Siehe oben.

>Und das erklärt auch warum man erst wartet und dann die Anwendung
>ausführt: Weil erst nach einer bestimmten Zeit der Status des
>Schalters/Tasters bekannt ist.

Das verstehe ich nicht ganz. Wenn man weiß, daß die Taste vor dem 
Drücken in Ruhe war (=Ruhepegel) und dann eine aktive Flanke auftritt, 
ist doch klar, daß die Taste gedrückt wurde (außer natürlich beim 
Auftritt von Leitungsstörungen o.ä., die wir ja ausschliessen wollten, 
s.o.). Wenn man das anschließende Prellen ignoriert, passiert doch nix. 
Beim WIederloslassen ist es ganz ähnlich, außer, daß jetz während des 
Aktivpegels (=während die Taste gerdrückt bleibt) auf die Flanke in 
Richtung Ruhepegel gewartet und das anschließende Prellen wieder 
ignoriert werden muß .

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.