Forum: Mikrocontroller und Digitale Elektronik Taster entprellen per Software


von Juerg F. (juerg_f)


Lesenswert?

Ich check einfach nicht, wie dieser Code einen Taster entprellen kann. 
Im Prinzip ist doch ein Prellen nichts anderes, als wenn ein Taster 
innert kurzer Zeit immer wieder zwischen zwei Zuständen wechselt. Warum 
wird denn dies nicht als mehrere Tastendrücke gewertet - die Abarbeitung 
des Codes geht ja "rasend schnell" und müsste doch diese Zustände als 
Tastendruck auswerten müssen.

Nicht falsch verstehen! Die Lösung funktioniert bei mir perfekt aber ich 
würde gerne die Funktion richtig verstehen - wie wird hier das Prellen 
rausgefiltert? ;-)

Aus der Anleitung: 
https://www.mikrocontroller.net/articles/Entprellung#Softwareentprellung

Flankenerkennung

Bei einem Taster gibt es insgesamt 4 theoretische Zustände:

    1. war nicht gedrückt und ist nicht gedrückt
    2. war nicht gedrückt und ist gedrückt (steigende Flanke)
    3. war gedrückt und ist immer noch gedrückt
    4. war gedrückt und ist nicht mehr gedrückt (fallende Flanke)

Diese einzelnen Zustände lassen sich jetzt bequem abfragen/durchlaufen. 
Die Entprellung geschieht dabei durch die ganze Laufzeit des Programms. 
Die Taster werden hierbei als Active-Low angeschlossen, um die internen 
Pull-Ups zu nutzen.

Diese Routine gibt für den Zustand "steigende Flanke" den Wert "1" 
zurück, sonst "0"

#define TASTERPORT PINC
#define TASTERBIT PINC1

char taster(void)
{
    static unsigned char zustand;
    char rw = 0;

    if(zustand == 0 && !(TASTERPORT & (1<<TASTERBIT)))   //Taster wird 
gedrueckt (steigende Flanke)
    {
        zustand = 1;
        rw = 1;
    }
    else if (zustand == 1 && !(TASTERPORT & (1<<TASTERBIT)))   //Taster 
wird gehalten
    {
         zustand = 2;
         rw = 0;
    }
    else if (zustand == 2 && (TASTERPORT & (1<<TASTERBIT)))   //Taster 
wird losgelassen (fallende Flanke)
    {
        zustand = 3;
        rw = 0;
    }
    else if (zustand == 3 && (TASTERPORT & (1<<TASTERBIT)))   //Taster 
losgelassen
    {
        zustand = 0;
        rw = 0;
    }

    return rw;
}

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Juerg F. schrieb:
> Warum wird denn dies nicht als mehrere Tastendrücke gewertet
Wie oft (oder wie schnell nacheinander) wird diese Routine denn 
aufgerufen?

von Klaus R. (klara)


Lesenswert?

Hollo,
diese Routine meldet Dir nur einen Zustand für einen Zeitpunkt. Wie 
erkennst Du denn das "Flackern"? Da fehlt doch noch etwas.
mfg Klaus

von c-hater (Gast)


Lesenswert?

Juerg F. schrieb:

> Ich check einfach nicht, wie dieser Code einen Taster entprellen kann.

Nur dadurch, dass er mit einem hinreichenden zeitlichen Abstand immer 
wieder aufgerufen wird. Dieser zeitliche Abstand ist die eigentliche 
Entprellung. Ohne diesen ist der Code vollkommen nutzlos und entprellt 
garnix.

von Juerg F. (juerg_f)


Lesenswert?

Mit dem Oszilloskop gemessen ca. alle 47us

von Juerg F. (juerg_f)


Lesenswert?

c-hater schrieb:
> Juerg F. schrieb:
>
>> Ich check einfach nicht, wie dieser Code einen Taster entprellen kann.
>
> Nur dadurch, dass er mit einem hinreichenden zeitlichen Abstand immer
> wieder aufgerufen wird. Dieser zeitliche Abstand ist die eigentliche
> Entprellung. Ohne diesen ist der Code vollkommen nutzlos und entprellt
> garnix.

Ach so! Habe nämlich grad festgestellt, dass doch nicht jeder 
Tastendruck so klar gewertet wurde. Gemäss Oszi habe ich festgestellt, 
dass nach einem Tastendruck es trotzdem noch möglich war, dass zwei 
Zustände gewechselt wurden.

Eingentlich müsste der Code doch mit einem Timer OVF verknüpft werden 
damit das Poling nicht so oft läuft...?

von W.S. (Gast)


Lesenswert?

Juerg F. schrieb:
> Ich check einfach nicht, wie dieser Code einen Taster entprellen kann.

Schreib dir lieber eine eigenen, dann weißt du es besser.
Im Prinzip ist es ganz einfach:
1. beim allerersten Kontakt kann man das Tasten-Ereignis generieren 
(also was der µC machen soll bei Tastendruck).
2. direkt danach testet man, ob der Taster über eine gewisse Zeit (sagen 
wir mal 30 ms) aus ist. Dann sollte jegliches Prellen erledigt sein.
3. wenn nach so etwa 800 ms der Taster noch immer gedrückt ist, dann 
kann man wieder ein Tasten-Ereignis draus machen, also ne 
Repetierfunktion. Und man kann die Wartezeit nach dem ersten Repetieren 
kürzer halten.

ist doch eigentlich leicht zu verstehen.

W.S.

von Juerg F. (juerg_f)


Lesenswert?

> Schreib dir lieber eine eigenen, dann weißt du es besser.
> Im Prinzip ist es ganz einfach:
> 1. beim allerersten Kontakt kann man das Tasten-Ereignis generieren
> (also was der µC machen soll bei Tastendruck).
> 2. direkt danach testet man, ob der Taster über eine gewisse Zeit (sagen
> wir mal 30 ms) aus ist. Dann sollte jegliches Prellen erledigt sein.
> 3. wenn nach so etwa 800 ms der Taster noch immer gedrückt ist, dann
> kann man wieder ein Tasten-Ereignis draus machen, also ne
> Repetierfunktion. Und man kann die Wartezeit nach dem ersten Repetieren
> kürzer halten.


Dieses Prinzip ist mir logisch - wäre so einfach mit Delay umzusetzen 
aber ich finde garantiert eine elegantere Lösung ohne Delay - kann ja 
nicht so schwer sein! ;-)

von Juerg F. (juerg_f)


Lesenswert?

Habe grad was erlickt! Nämlich dass ich folgenden Satz vom 
mikrocontroller.net tutorial falsch interpretiert habe:

""Die Entprellung geschieht dabei durch die ganze Laufzeit des 
Programms.""

Habe dies so interpretiert, dass die Entprellung im Durchlauf dieser 
Funktion "taster()" geschieht. Da ich jetzt noch ein "kleines" Delay von 
1ms eingebaut habe scheint der Code doch gut zu funktionieren.

Dh. wenn das ganze Programm mal grösser wird, wird auch die 
Entprellfunktion ohne Delay ganz ordenltich funzen!

Danke für eure Hilfe!

von Klaus R. (klara)


Lesenswert?

Juerg F. schrieb:
> Eingentlich müsste der Code doch mit einem Timer OVF verknüpft werden
> damit das Poling nicht so oft läuft...?

Polling ist nicht gerade elegant.
mfg Klaus

von c-hater (Gast)


Lesenswert?

Juerg F. schrieb:

> Eingentlich müsste der Code doch mit einem Timer OVF verknüpft werden
> damit das Poling nicht so oft läuft...?

Das wäre die übliche Anwendungsweise. Wobei natürlich nicht unbedingt 
ein kompletter Timer dafür geopfert werden muss. Ein brauchbares 
Intervall (Größenordnung so einige zehn ms) lässt sich oft aus einem 
anderweitig genutzten Timer ableiten, meist durch weitere Teilung von 
dessen Überläufen in Software.

Die Tastaturabfrage muss übrigens natürlich auch nicht direkt in der ISR 
erfolgen. Oft ist es wesentlich sinnvoller, in der ISR nur ein Flag zu 
setzen, welches der Hauptschleife meldet, dass es mal wieder Zeit für 
eine Tastaturabfrage wäre. Dort darf man dann natürlich nicht vergessen, 
dieses Flag auch wieder zurückzusetzen, wenn der gesetzte Zustand 
erkannt wurde, sonst ergibt sich auch wieder eine wirkungslose 
Entprellung.

von STK500-Besitzer (Gast)


Lesenswert?

Klaus R. schrieb:
> Polling ist nicht gerade elegant.
> mfg Klaus

Polling ist nicht das Problem, sondern das Delay.
Das hält den flüssigen Programmablauf auf.
Für regelmäßiges "Nachsehen" verwendet man Timer oder sieht nach, ob 
eine gewisse Zeit verstichen ist (manueller Timer-Überlauf).
Einfach Zeit zwischen zwei Nachguck-Momenten durch langweiliges Warten 
zu überbrücken, mag niemand.

von Lötlackl *. (pappnase) Benutzerseite


Lesenswert?

@Juerg F.

Schon bis zu diesem Abschnitt gelangt?

https://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29

Läuft bei mir auf AVR, besagtem AT91SAM7 (hatte ich vor Jahren mal 
nachgebaut) und auch auf nem STM32(F103), dort aber gleich mit der 
Vorgabe, bis zu 64 Tasten zu entprellen. Läuft auf den genannten 
Plattformen hervorragend. Ich möchte gar nichts anderes mehr.

von Peter D. (peda)


Lesenswert?

W.S. schrieb:
> 1. beim allerersten Kontakt kann man das Tasten-Ereignis generieren
> (also was der µC machen soll bei Tastendruck).

Und eignet sich sehr gut, um viele Fehlauslösungen durch Störungen zu 
erhalten. Z.B. durch ein Relais in der Nähe, welches 230V schaltet. Oder 
elektrostatische Entladungen, wenn man das Gerät nur berührt. Usw.

Bessere störsichere Softwarelösungen kosten nur etwas Gehirnschmalz, 
senken aber den Blutdruck des Benutzers nachhaltig.

von Juerg F. (juerg_f)


Lesenswert?

Lötlackl *. schrieb:
> @Juerg F.
>
> Schon bis zu diesem Abschnitt gelangt?
>
> 
https://www.mikrocontroller.net/articles/Entprellung#Komfortroutine_.28C_f.C3.BCr_AVR.29
>
> Läuft bei mir auf AVR, besagtem AT91SAM7 (hatte ich vor Jahren mal
> nachgebaut) und auch auf nem STM32(F103), dort aber gleich mit der
> Vorgabe, bis zu 64 Tasten zu entprellen. Läuft auf den genannten
> Plattformen hervorragend. Ich möchte gar nichts anderes mehr.

Klar bin ich soweit gekommen - aber dieser Code hat mich schon ein wenig 
erschlagen - so viele Zeilen Code um einen Taster zu enprellen ging mir 
durch den Kopf :-)

Habe mir gedacht, wenn ein einfacherer Code möglich ist - dann momentan 
lieber der!

Aber werde diesen trotzdem mal genauer anschauen - will nur code 
benutzen, den ich selber auch wirklich verstehe. Also ran an den Zauber!

von Lötlackl *. (pappnase) Benutzerseite


Lesenswert?

In der Tat, dieser Code erfordert etwas Hirnschmalz, da dort mit 2 
Registern (Variablen) ein 8-Bit breiter Binärzähler aufgebaut wird, der 
sozusagen jede beliebige Bitstelle unabhängig bis 4 zählt, bis ein 
zuverlässiger Zustand erkannt wird. Steht aber auch in der Beschreibung.

von Michael B. (laberkopp)


Lesenswert?

Juerg F. schrieb:
> Ich check einfach nicht, wie dieser Code einen Taster entprellen kann.

Das steht ja auch nicht in deinem Code.

Die Funktion funktioniert nur, wenn sie schnell wiederholt in kürzeren 
Zeitabständen aufgerufen wird, DIE LÄNGER DAUERN ALS DAS PRELLEN DES 
TASTERS DAUERT.

Also z.B. bei bis zu 5ms lang prellenden Taster in regelmässigen 10ms 
Zeitabständen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Juerg F. schrieb:
> Habe nämlich grad festgestellt, dass doch nicht jeder Tastendruck so
> klar gewertet wurde.
Logisch, da fehlt ja auch die Entprellung. Der Code ganz oben ist nur 
eine (etwas aufwändige) Flankenerkennung, vorher muss das auszuwertende 
Signal erst noch zuverlässig entprellt werden.

Beitrag #5977062 wurde vom Autor gelöscht.
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.