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
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
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?
>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" ?
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.
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.
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.
Da sich wohl nichts findet, bin ich gerade an einer Entprellung dran.
Vielleicht überarbeite ich den Artikel dann in dieser Richtung, wenn es
funktioniert.
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.
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.
@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.
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
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.
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.
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?
>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.
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.
>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.
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.
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
>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.
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.