Forum: Mikrocontroller und Digitale Elektronik Drehencoder entprellen


von Samsing (Gast)


Lesenswert?

Hallo,

ich habe einen EC11 Drehencoder und das Signal prellt beim Zählen. In 
meinen bisherigen Projekten war so etwas nie ein Problem, jetzt habe ich 
jedoch einen "Beep" als Feedback und möchte das Prellen deshalb 
ausschließen.

Finde leider kein gutes Codebeispiel. Wollte das Rad nicht neu erfinden.

Hat jemand einen Tipp ?

Samsing

von spontan (Gast)


Lesenswert?


von Samsing (Gast)


Lesenswert?

Da wird aber nichts entprellt.

von Further (Gast)


Lesenswert?

Na aber hallo wir da entprellt...

von Samsing (Gast)


Lesenswert?

also kennt jetzt jemand ein Beispiel ?

von Harald W. (wilhelms)


Lesenswert?

Samsing schrieb:

> Da wird aber nichts entprellt.

Wenn die Auswertung "richtig" gemacht wird (Pegel- und nicht Flanken-
gesteuert) brauchst Du auch nicht zu entprellen.
Gruss
Harald

von Seppl (Gast)


Lesenswert?

Vielleicht solltest du angeben, wie du bisher die Encoder-Werte
verarbeitest? An welchem uC wird der Drehencoder betrieben?
Verwendest du eine Hardware-Unterstützung (Zähler in Hardware)
oder ist alles in Software realisiert?

von spontan (Gast)


Lesenswert?

>Da wird aber nichts entprellt.

Kann jemand der einen fertigen Code sucht, aus welchem Grund auch immer, 
kann so jemadn auch fertigen COde beurteilen? Hat er sich überhaupt die 
Mühe gemacht?

Oder muß im Kommentar des Codes nur drinstehen: "hier wird entprellt" ?

von Samsing (Gast)


Lesenswert?

Harald Wilhelms schrieb:
>Wenn die Auswertung "richtig" gemacht wird (Pegel- und nicht Flanken-
>gesteuert) brauchst Du auch nicht zu entprellen.
Ja. Die Auswertung habe ich richtig gemacht.


@Seppl
Ich lese die Encoderwerte in einer 1ms Task ein, nehme die beiden 
Zustände aus der letzten Task hinzu, gehe damit in eine State-Tabelle 
und habe als Ergebnis eben ein "HOCH" oder "RUNTER"-Zählen. Der 
Drehencoder wird an einem PIC16F1713 betrieben. Interne Weak-Pull Ups. 
Auswertung in Software (1ms Task)

>aus welchem Grund auch immer
Weil ich gerne bewährtes benutze. Man muss es ja nicht 1:1 übernehmen. 
Aber verstehen und für sein Projekt anpassen.

von Mike (Gast)


Lesenswert?

Samsing schrieb:
> Auswertung in Software (1ms Task)

Dann hast du in der Software vermutlich vergessen, eine Hysterese zu 
implementieren oder du hast ein Problem mit der Lage der Rastpunkte.

von Samsing (Gast)


Lesenswert?

Hallo Mike,

die Rastepunkte sollten eigentlich richtig liegen, denn ich zähle genau 
am "Berg". Das passt auch. Wenn ich den nur leicht berühre habe ich 
keine Probleme.

>Dann hast du in der Software vermutlich vergessen, eine Hysterese zu
>implementieren
Ich verstehe den Begriff Hysterese hier nicht genau. Aber möglicherweise 
meinst Du damit das, was ich mit "Prellen" meine.

von Samsing (Gast)


Lesenswert?

Da sich wohl nichts findet, bin ich gerade an einer Entprellung dran.
Vielleicht überarbeite ich den Artikel dann in dieser Richtung, wenn es 
funktioniert.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wie äußert sich denn dieses Prellen?

Samsing schrieb:
> Ich lese die Encoderwerte in einer 1ms Task ein, nehme die beiden
> Zustände aus der letzten Task hinzu, gehe damit in eine State-Tabelle
> und habe als Ergebnis eben ein "HOCH" oder "RUNTER"-Zählen.

Das ist prinzipiell in Ordnung so. Allerdings kann es erforderlich sein,
die Zustandstabelle an die spezifischen Eigenschaften¹ des verwendeten
Drehgebers anzupassen.

Liegt bspw. eine Signalflanke auf oder sehr dicht an einem Einrastpunkt,
sollte an dieser Stelle kein für den Benutzer sichtbarer Zustandswechsel
stattfinden.

Bei vielen Drehgebern ist es möglich, die Inkrementpunkte gegenüber den
Dekrementpunkten um eine Flanke zu versetzen. Damit erhält man eine Art
Hysterese, die verhindert, dass der Wert beim langsamen Drehen zwischen
zwei Zählerständen zwischen diesen hin und her zappelt.

Mit einem schnellen Copy/Paste von Code aus dem Netz kommst du oft nicht
zum Ziel. Wenn du aber dir aber Gedanken um die genaue Funktionsweise
deines Drehgebers und des Auswerteverfahrens machst, ist die Anpassung
hinterher ganz leicht.

Du musst jedenfalls keinen zusätzlichen Entprellcode schreiben. An
Anpassen der Zustandstabelle ist völlig ausreichend.

————————————
¹) Insbesondere die Lage der Signalflanken relativ zu den Einrastpunkten
   undAnzahl der Signalflanken zwischen zwei Einrastpunkten, beides kann
   durch Messungen ermittelt werden.

von Mike (Gast)


Lesenswert?

Samsing schrieb:
> Ich verstehe den Begriff Hysterese hier nicht genau.

Wenn dein Geber an der Flanke einer der Phasen zwischen zwei Zuständen 
hin und her springt, stört das einen richtig aufgebauten 
Zustandsautomaten nicht. Trotzdem kann das für den Nutzer natürlich 
unerwünscht sein. Das kannst aber nur du über Zusatzfilterung für den 
ausgegebenen Zustand verhindern, weil der Drehgeber nicht unterscheiden 
kann, ob du hin und her drehst, oder ob da eine Flanke zappelt.
Beispielsweise könnte man eine Hysterese für den Drehweg implementieren, 
die am Ausgang Zustandswechsel unterbindet, wenn nur einen Schritt in 
der Drehrichtung erfolgte und danach schon wieder ein 
Drehrichtungswechsel. Ob das sinnvoll ist, hängt von der Anwendung ab.

von Samsing (Gast)


Lesenswert?

@Yalu
Ich habe eine Tabelle mit 16 Einträgen. Davon gäbe es 4 für "RECHTS". 
Ich hatte bisher nur eine der 4 Flanken benutzt. Diese, die am besten 
zum mechanischen Raster passte. Hab jetzt auch mal die anderen 3 
versucht. Ändert sich aber nichts.
Abtastfrequenz ist allerdings 10kHz und nicht wie zuerst geschrieben 
1kHz.

@Mike
Ja genau. Und ich hab halt so eine Anwendung. Ich drehe von 0 bis 100 
und jedemal gibt es eine Feedback durch einen leisen Beep. Bei 100 ist 
man dann am rechten Rand und es soll nichts mehr zu hören sein.
Signal des Drehencoders sieht jedoch so aus, wenn ich nach rechts weiter 
drehe:

+        +        +        -++        +        +


Das "+" wird begrenzt (kein Beep), das -++ wird jedoch als "kurz LINKS" 
erkannt und mit Beep quittiert.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Samsing schrieb:
> Ich hatte bisher nur eine der 4 Flanken benutzt.

Das ist vermutlich das Problem. Wenn du den Drehgeber über diese Flanke
hinwegdrehst und der Kontakt etwas prellt, zappelt der ermittelte
Zählwert, da das Inkrementieren und Dekrementieren exakt an derselben
Stelle erfolgt.

Schließ mal zwei LEDs an die Kanäle des Drehgebers an, dreh ihn ganz
langsam durch zeichne dabei die Winkelpositionen der Signalflanken von A
und B sowie der Rastpunkte relativ zueinander auf. Das muss nicht aufs
Grad genau sein, aber wenigstens so genau, dass man erkennen kann, ob
ein Rastpunkt etwa in der Mitte zwischen zwei Signalflanken oder ganz
nah bei einer der Flanken liegt.

So ein Digramm könnte (muss aber nicht) folgendermaßen aussehen:
1
             _______         ____
2
A       ____| :     |_______| :
3
              :       :       :
4
         _______         _______
5
B       |     : |_______|     : |
6
              :       :       : 
7
Rastp.        ^       ^       ^
8
        ———————————————————————————> Drehwinkel
9
10
            :   :   :   :   :   :
11
           ——> <—— ——> <—— ——> <——
12
            +   -   +   -   +   -

Wenn du in diesem Beispiel bei jedem Zustandswechsel von B den Zähler
inkrementierst bzw. dekrementierst, macht sich genau an diesen Punkten
das Kontaktprellen (oder deine zittrige Hand ;-)) negativ bemerkbar.

Edit:

Bitte den Beitrag ab hier ignorieren, es folgt nur noch Mist:
1
| Wenn du hingegen bei positivem Drehsinn den Zähler beim Zustandswechsel
2
| von A inkrementierst und ihn bei negativem Drehsinn beim Zustandswechsel
3
| von B dekrementierst, passiert das nicht.
4
| 
5
| Um während einer positiven Drehung den Wert fälschlicherweise um 1
6
| zurückspringen zu lassen, müsstest du nämlich den Knopf um etwa eine
7
| Viertelsignalperiode bzw. eine halbe Rastweite zurückdrehen. So arg
8
| zitterst du aber nicht. Auch das Kontaktprellen stört nicht mehr, denn
9
| während A prellt ist B stabil und umgekehrt. Es kann also ein Inkrement
10
| und Dekrement an derselben Winkelposition stattfinden.
11
| 
12
| Die kleinen Pfeile mit den Plus- und Minuszeichen verdeutlichen dies. So
13
| sagt bspw. der erste dieser Pfeile folgendes aus: Wenn der Drehknopf in
14
| positiver Richtung (im Diagramm also von links nach rechts) über die
15
| steigende Flanke von A bewegt wird, während B high ist, wird der Zähler
16
| inkrementiert.
17
| 
18
| Der Winkelabstand zwischen den Inkrement- und Dekrementpunkten ist die
19
| Hysterese. Je größer sie ist, umso zuverlässiger wird die Auswertung.
20
| So, wie du die Auswertung bisher realisiert hast, ist die Hysterese aber
21
| null, d.h. Kontaktprellen und Zittern machen sich maximal bemerkbar.
22
| 
23
| Das Hystereseverhalten kannst du durch eine geeignetee Anpassung der
24
| Zustandstabelle realisieren. Am Programmcode selber musst du vermutlich
25
| nichts ändern. Solltest du Schwierigkeiten dabei haben, kannst du ja das
26
| Signaldiagramm für deinen Drehgeber zusammen mit deinem Auswertecode
27
| posten. Dann wird dir sicher jemand helfen.

: Bearbeitet durch Moderator
von Samsing (Gast)


Lesenswert?

Hallo Yalu,
das Diagramm hab ich nicht gezeichnet. Ich hab's aber mal 
programmtechnisch so umgesetzt wie Du gesagt hast. Es bringt aber keine 
Verbesserung.

Ich hab ja 4 Zustände 0 bis 3 und entsprechend 4 Übergänge.

Mechanisch raster der Drehgeber bei Zustand 0 ich hatte bisher bei 2->3 
ein "RECHTS" und bei 3->2 ein "LINKS" erkannt. Das habe ich geändert auf
2->3: RECHTS
1->0: LINKS

Jetzt drehe ich also und habe bei 2->3 die obere (rechte) Softwaregrenze 
erreicht. Es soll in Zukunft nicht mehr weiter nach oben (rechts) 
gezählt werden. Er letzter "Beep".

Ich drehe gedanklich weiter. 3->0->1->2->3 (diesmal kein Beep). Alles 
o.k.
Ich drehe gedanklich weiter. 3->0->1->0[PRELL]->1-> ....das Prellen wird 
trotzdem fälschlicherweise als "LINKS" erkannt.

Es ist jetzt sogar so, dass das System noch schlechter geworden ist. 
Denn jetzt würde ein Zittern um 0 und 1 zu einem mehrfachen Linkszählen 
führen. Zählfehler also.

von Peter D. (peda)


Lesenswert?

Samsing schrieb:
> Da wird aber nichts entprellt.

Erzähl mal noch einen vom Pferd.

Natürlich wird hier entprellt:
http://www.mikrocontroller.net/articles/Drehgeber#Solide_L.C3.B6sung:_Beispielcode_in_C

Der Trick ist, daß nicht nur an den Rastungen gezählt wird, sondern an 
jedem Wechsel. Somit wird ein Preller bei der nächsten Abtastung sofort 
wieder zurück gezählt.

Bei Encodern, die genau an einer Flanke rasten, muß man den Startwert so 
wählen, daß dort kein Zählerwechsel erfolgt, sondern nur das unterste 
Bit zappelt.

von Peter D. (peda)


Lesenswert?

Samsing schrieb:
> Es ist jetzt sogar so, dass das System noch schlechter geworden ist.

Was hindert Dich daran, einfach mal das Beispiel auszuprobieren, so wie 
es ist?

von Samsing (Gast)


Lesenswert?

>Was hindert Dich daran, einfach mal das Beispiel auszuprobieren, so wie
>es ist?
Ich hab meinen Programmcode. Der ist wie das Beispiel "Drehgeber mit 
wackeligem Rastpunkt dekodieren". Nur etwas anders geschrieben. Aber 
gleiche Funktion.

>Erzähl mal noch einen vom Pferd.

>Natürlich wird hier entprellt:
>http://www.mikrocontroller.net/articles/Drehgeber#...
Nein. Wird nicht. Diese Beispiele sind geschrieben auf: "Prellen ist 
weiterhin möglich, ein Prellen führt aber zu keinem Zählfehler"


>Somit wird ein Preller bei der nächsten Abtastung sofort wieder zurück >gezählt.
Genau. Und eben diese Preller brauche ich bei meiner Anwendung nicht. 
Deswegen such ich eine Programmschnipsel, dass entprellt.
... bzw. ich such nicht mehr. Ich hab's jetzt hinbekommen.

von Mike (Gast)


Lesenswert?

Samsing schrieb:
> Ich hab's jetzt hinbekommen.

Und wie?

von Samsing (Gast)


Lesenswert?

teilweise Pseudocode, um es universeller zu halten.
Wobei "cnt" hier nicht wirklich die Zählvariable ist, sondern nur ein 
"Hilfszähler" der von -2 bis +2 zählt.
1
 ....
2
    // Decode rotary encoder
3
    switch (EN_StepTab[encoderState]) {
4
        case ENC_NO_STEP:
5
            break;
6
        case ENC_LEFT_STEP:
7
            cnt --;
8
            cnt_timeout = 0;
9
            break;
10
        case ENC_RIGHT_STEP:
11
            cnt ++;
12
            cnt_timeout = 0;
13
            break;
14
        case ENC_ERROR_STEP:
15
            break;
16
    }
17
18
19
    // If there were 2 steps, do not wait.
20
    // Count them immediatly
21
    if (cnt == 2) {
22
        cnt = 0;
23
        cnt_timeout = 0;
24
        DoMyThings(INC);
25
        DoMyThings(INC);
26
    }
27
28
    // If there were 2 steps, do not wait.
29
    // Count them immediatly
30
    if (cnt == -2) {
31
        cnt = 0;
32
        cnt_timeout = 0;
33
        DoMyThings(DEC);
34
        DoMyThings(DEC);
35
    }
36
37
    // Wait x ms for "no change in signal A and B"
38
    if (cnt_timeout < x_ms) {
39
        cnt_timeout ++;
40
    }
41
    else {
42
43
        // For at least x ms "no change"
44
        // now you can count them.
45
        if (cnt == 1 )
46
            DoMyThings(INC);
47
        if (cnt == -1)
48
            DoMyThings(DEC);
49
50
        cnt = 0;
51
   }

von rostblau (Gast)


Lesenswert?

>Der Winkelabstand zwischen den Inkrement- und Dekrementpunkten ist die
>Hysterese. Je größer sie ist, umso zuverlässiger wird die Auswertung.
Oh !
Man MUSS IMMER an einer Flanke hoch und runter zählen. Es ist zwar nicht 
notwendig, jede Flanke zu zählen. Aber wenn man es tut, dann immer die 
steigende und die fallenden.

Nur eine zu zählen ist der Schlimmste Fehler, den man machen kann. 
Schlimmer als HTML Layout mit Tabellen. Schlimmer als IC ohne 
Abblockkondensatoren.

von Yalu X. (yalu) (Moderator)


Lesenswert?

rostblau schrieb:
> Man MUSS IMMER an einer Flanke hoch und runter zählen.

Danke für den Hinweis!

Ja, das war vollkommener Mist, den ich da geschrieben habe. Mir ist das
gestern Abend sogar noch aufgefallen, hatte aber nicht mehr die Muße,
das sofort zu korrigieren, zumal der TE ja inzwischen eine eigene Lösung
gefunden hat.

Ich schäme mich deswegen und nehme hiermit das, was ich oben geschrieben
habe, zurück.

Drehgeber kenne ich sonst nur von der Antriebs- und Steuerungstechnik,
da ist es üblich, dass immer alle Flanken und in beide Richtungen
ausgewertet werden, um die maximale Auflösung zu erhalten. Dort stellt
sich dieses Problem deswegen überhaupt nicht.

Eine Hysterese bei Drehgebern in Bedienfeldern zur Entprellung ist aber
trotzdem möglich, allerdings sollte man sie nicht direkt auf die
Abtastung der Gebersignale, sondern auf die Zählerwerte anwenden.

von rostblau (Gast)


Lesenswert?

Ehrt Dich!
Vor Leuten, die sich selbst mal korrigieren, habe ich mehr Respekt als 
vor denen, die alles wissen.

von Axel S. (a-za-z0-9)


Lesenswert?

rostblau schrieb:
>>Der Winkelabstand zwischen den Inkrement- und Dekrementpunkten ist die
>>Hysterese. Je größer sie ist, umso zuverlässiger wird die Auswertung.
> Oh !
> Man MUSS IMMER an einer Flanke hoch und runter zählen. Es ist zwar nicht
> notwendig, jede Flanke zu zählen. Aber wenn man es tut, dann immer die
> steigende und die fallenden.
>
> Nur eine zu zählen ist der Schlimmste Fehler, den man machen kann.

Du hast es nicht begriffen.

Der Zustandsautomat macht schon richtig einen Zustandsübergang für jeden 
Codewechsel. Aber es ist eine Halbschrittauswertung - es liegen zwei 
Codewechsel zwischen benachbarten Rastpunkten. Die für den Anwender 
sichtbare Zählvariable wird also nur an einem der beiden Codewechsel 
hoch- bzw. runtergezählt. Und welcher Codewechsel das sein soll, das 
kann man sich aussuchen. Durchaus auch unterschiedlich je nach 
Drehrichtung.


XL

von spontan (Gast)


Lesenswert?

>Nein. Wird nicht. Diese Beispiele sind geschrieben auf: "Prellen ist
>weiterhin möglich, ein Prellen führt aber zu keinem Zählfehler"

Was ist für Dich denn die Definition von "Entprellen"?

Ich würd behaupten wollen, daß der Encoder entprellt ist, wenn das 
Prellen eines Encoderes (ist eine Eigenschaft des Bauteils) keine 
Auswirkung auf den Zählerstand hat.

Leistet das Deine Routine wirklich? Teile davon hast Du nicht 
veröffentlicht. Sieht aber auf den ersten Blick aus, als wenn Du keine 
4-fach-Auswertung machst, sondern teilst. Und damit das erkannte Prellen 
(betrifft ja nur das letzte Bit des Zählers) verschwinden läßt.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Axel Schwenke schrieb:
> Du hast es nicht begriffen.

Doch, doch, "rostblau" hat es schon begriffen. Der, der es nicht
begriffen hat, bin (bzw. war) ich ;-)

Sein Hinweis bezog sich auf meinen Beitrag, und ich bin dort tatsächlich
einem Trugschluss verfallen.

: Bearbeitet durch Moderator
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.