Drehencoder "Zwischen der Rastung"

Gast #4876871
Guten Abend.

Habe schon seit längerem die super Routine aus dem Forum hier im Einsatz 
um Drehencoder aus zu lesen. Das klappt auch wunderbar (so lange ich 
normal drehe...)

Jetzt ist mir bei einem Drehencoder aufgefallen, dass wenn ich ihn zu 
langsam drehe (wirklich langsam...) das er aufeinmal beide Richtungen 
erkennt. Drehe ich ihn normal (wie man ihn eigentlich dreht, klappt 
alles wunderbar)...
Ich habe schon beide Tabellen hier aus dem Forum ausprobiert, bei beiden 
das gleiche.

Kann ich diese Schritte "zwischen" der Rastung irgendwie raus filtern?
Ich brauche nur die Drehrichtung, incrementieren oder decrementieren 
brauche ich gar nicht.
1
void Read_Encoder(void)
2
{
3
    Encoder.Last = ((Encoder.Last << 2) & 0x0F);
4
    if((READ_PIN(GPIOA,GPIO_Pin_0))) Encoder.Last |= 0x02;
5
    if((READ_PIN(GPIOA,GPIO_Pin_1))) Encoder.Last |= 0x01;
6
    Encoder.Result = Encoder.Table[Encoder.Last];
7

8
    if(Encoder.Result == -1) // right evaluated
9
    {
10
       Encoder.Bit |= 1<<0; // set flag
11
       Encoder_Out(1,0); // output set
12
    }
13

14
    if(Encoder.Result == 1) // left evaluated
15
    {
16
      Encoder.Bit |= 1<<1; // set flag
17
      Encoder_Out(0,1); // output set
18
    }
19

20
    if((Encoder.Bit & 1<<0) == (1<<0))
21
    {
22
        Encoder.PhaseHigh++;
23
        if(Encoder.PhaseHigh >= PHASE_HIGH_MS)
24
        {
25
            Encoder.PhaseHigh = 0;
26
            Encoder.Bit &= ~(1<<0);
27
            Encoder_Out(0,0);
28
        }
29
    }
30

31
    if((Encoder.Bit & 1<<1) == (1<<1))
32
    {
33
        Encoder.PhaseHigh++;
34
        if(Encoder.PhaseHigh >= PHASE_HIGH_MS)
35
        {
36
            Encoder.PhaseHigh = 0;
37
            Encoder.Bit &= ~(1<<1);
38
            Encoder_Out(0,0);
39
        }
40
    }
41
}

Die Abfrage läuft mit ca. nem kiloHerz.
Gast
Nein.

Wenn dem so wäre, würde es beim schneller drehen ja extrem auffallen.
Das ist aber nicht der Fall.

Regelrecht wenn ich den Encoder sehr langsam drehe, gerade dort wo er 
nicht einrastet. Das heißt ich drehe innerhalb der Rastung.
Gast
Richard B. schrieb:
> Jetzt ist mir bei einem Drehencoder aufgefallen, dass wenn ich ihn zu
> langsam drehe (wirklich langsam...) das er aufeinmal beide Richtungen
> erkennt.

Dein Encoder prellt.
Sowas ist normal.

Es gibt hier Leute, die auf Polling und softwaremäßige Entprellung 
schwören, aber ich gehöre nicht dazu.

Mein Rat wäre deshalb, den Encoder hardwaremäßig zu entprellen.

Das Einfachste ist ein 10..100nF Kondensator über die Kontakte.
Sowas hilft schon mal sehr. Wenn dann dein µC-Eingang auch noch 
Schmitt-Trigger-Verhalten kann, ist die Sache hardwaremäßig komplett 
erledigt.

Dann kannst du mit Interrupts arbeiten und bist mit dem Drehgeber fast 
völlig unabhängig von der Drehgeschwindigkeit. Ich mache das seit vielen 
Jahren so und bin's zufrieden.

W.S.
Richard B. schrieb:
> Habe schon seit längerem die super Routine aus dem Forum hier im Einsatz
> um Drehencoder aus zu lesen.

Hier gibt es Unmengen an Codebeispielen, die keiner alle im Kopf haben 
kann. Du mußt schon den Link darauf posten.

Die ersten 3 Zeilen sind klar, die 4. müßte ein += enthalten, damit 
aufwärts (x += 1) bzw. abwärts (x += -1) gezählt wird.
Der ganze Rest ist mir völlig unverständlich.
Und die spärlichen Kommentare sind nichtssagend. Ein Kommentar soll 
nicht in Prosa wiederholen, was schon aus der Codezeile klar hervorgeht. 
Sondern er soll sagen, warum man etwas macht.

Richard B. schrieb:
> Ich brauche nur die Drehrichtung, incrementieren oder decrementieren
> brauche ich gar nicht.

Das geht damit nicht. Die Entprellwirkung beruht darauf, daß ein Preller 
wieder abgezogen wird.
Gast
W.S. schrieb:
> Das Einfachste ist ein 10..100nF Kondensator über die Kontakte.

Die brennen beim Schließen des Kontaktes dann auch gleich die 
Kontaktflächen etwas frei.

Richard B. schrieb:
> Jetzt ist mir bei einem Drehencoder aufgefallen, dass wenn ich ihn zu
> langsam drehe (wirklich langsam...) das er aufeinmal beide Richtungen
> erkennt.

Ja, was soll der arme Kerl denn machen, wenn sich der Kontakt vom einen 
Kanal an der Schaltschwelle immer öffnet und schließt. Das ist doch 
völlig richtig, dass er dann immer vor- und zurück zählt. Schlimm wäre 
es, wenn der Wert dann in eine Richtung weglaufen würde.

Was du brauchst, ist eine Hysterese in deiner Richtungsauswertung, die 
verhindert, dass die Vor- und Rückzappelei an deinem Ausgang erscheint.
Gast
Richard B. schrieb:

> Kann ich die Hysterse auch in Software abbilden?

Scheinbar nicht, wenn du das fragen musst.

Falls die Frage eigentlich war: "Kann man die Hysterese auch in Software 
abbilden?", dann ist die Antwort: Ja, natürlich kann man das.
Gast
Dafür habe ich die Tabelle angepasst.
1
.Table      = {0,0,-1,0,0,0,0,0,1,0,0,0,0,0,0,0}

wahrscheinlich falsch.
Es wird jedoch wenn ich normal drehe, nur +1 Incrementiert.
Du musst dafür sorgen, dass die selbe Flanke in beiden Richtungen für 
die Zählung benutzt wird. Sonst hast Du eine Flanke, welche gerade 
flattert, die in die eine Richtung Inkrementiert und in die andere 
Richtung nichts tut. Logisch, dass dann Deine Zahl nach oben weg 
wandert.

Mein Code (AVR ASM)
1
sbis  PINA, 2   ; Abfrage der beiden Bits und Speicherung in tmp
2
ori  tmp, 8
3
sbis  PINA, 3
4
ori  tmp, 4
5

6
LDI  ZL, LOW(2*DrehgeberArray)
7
LDI  ZH, HIGH(2*DrehgeberArray)
8
ADD  ZL, tmp
9
ADC  ZH, null
10
LPM  tmp2, Z
11
ADD  tmp1, tmp2 ; Wert aus der Tabelle an Position tmp zum Wert addieren
12
LSR  tmp  ; die uralten Bits aus tmp raus schieben, nur die alten behalten
13
LSR  tmp

tmp enthält die beiden Bits vom Drehgeber der letzten beiden Abfragen
tmp1 ist das Ergebnis.

Meine Tabelle(n)
1
DrehgeberArray
2
.db  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,-1, 0, 0 ; Aktuell
3
.db  0,-1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
4
.db  0,-1, 1, 0, 1, 0, 0,-1,-1, 0, 0, 1, 0, 1,-1, 0 ; Jeder Schritt zählt

Vielleicht kannst Du Dir ja etwas abgucken ...


Gruß

Jobst
Gast
Richard B. schrieb:

> Musste gestern feststellen, je langsamer ich werde, desto mehr prellen
> die Kontakte...

Das dürfte normal sein.

Bei hochwertigen Encodern ist die Phasenlage zwischen mechanischem Klick 
und elektrischem Schaltvorgang definiert. Der Schaltvorgang erfolgt an 
einer Stelle, wo die Kraft minimal ist, so dass man sich beim normalen 
Drehen dort möglichst kurz aufhält.

Bei Billigencodern ist die Zuordnung mechanischer Klick  <--> 
elektrische Kontakt undefiniert und exemplarabhängig. Ich hatte schon 
welche, die in der stationären Ruhelage geschaltet haben. Da reicht dann 
schon Trafobrummen um ausreichend Vibration zu erzeugen um Pulse zu 
generieren. Die Mark mehr für Alps oder Panasonic ist da schon gut 
investiert.


Optische Encoder (Grayhill, Copal, etc) sind nahezu prellfrei.
Gast
Richard B. schrieb:
> Musste gestern feststellen, je langsamer ich werde, desto mehr prellen
> die Kontakte...

Du verstehst die Funktion überhaupt nicht, wahrscheinlich auch weil du 
weder die Antworten hier noch Knowhow-Artikel dazu lesen willst. Die 
Kontakte mögen prellen oder auch nicht, an einem bestimmten Punkt 
schalten sie nun einmal um, das ist ihre Aufgabe. Und wenn man genau an 
diesen Umschaltpunkt positioniert, bewirkt eben die kleinste Veränderung 
das Umschalten; dass der Ausgang zwischen 0 und 1 hin- und herspringt 
ist also völlig normal auch bei prellfreien Schaltern. Da aber eine 
korrekte Auswertung dabei einen Schritt aufwärts zählt, beim 
Zurückspringen aber wieder abwärts, wird der Zählerstand nicht 
verfälscht.

Das Springen beim Umschaltpunkt kann nur durch eine Hysterese eliminiert 
werden, aber der Drehencoder kann keine mechanische Hysterese haben, 
daher muss die Hysterese in der Auswertesoftware realisiert werden. 
Sofern das Auf/Ab in der letzten Stelle überhaupt stört.

Georg
Gast
Eine Hardware ist keine Lösung.
Wenn der Encoder an seinem Schaltpunkt schaltet, ist das seine Aufgabe.
Ein RC-Netzwerk gibt dieses Schalten auch weiter, muß es ja auch, sonst 
ist der Encoder sinnbefreit.
Wenn das Netzwerk das Umschalten weitergibt, wird immer ein 
nachgeordneter Zähler zählen. Soll er j auch.

Also hilft ein Netzwerl nix gegen das Schalten am Umschaltpunkt.

Das einzige was hilft: die Umschaltungen richtig interpretieren.

... Aber das überlassen die Spezialisten ja einem RC-Netzwerk. So wird 
das nix. Nicht heute und nicht zu einem anderen Zeitpunkt.
Gast
Jobst M. schrieb:
> Evtl. gibt es ja Stecksockel für den Drehgeber.
Eventuell gibt es auch Stänkerer.
> Der findet das nämlich
> nicht witzig, ständig den Kondensator kurz zu schließen.

Ich habe das in dieser Form bei > 10 Geräten mit den unterschiedlichsten 
Typen seit Langem im Einsatz. Es kümmert sie alle nicht im Mindesten, 
daß sie mit ihren Kontakten die beiden Kondensatoren kurzschließen.
soul e. schrieb:

> Bei Billigencodern ist die Zuordnung mechanischer Klick  <-->
> elektrische Kontakt undefiniert und exemplarabhängig.

Manchmal hilft es dann, die beiden Anschlüsse des Drehencoders
zu tauschen. Normalerweise ist bei richtiger Auswertung das
Prellen der Kontakte unwichtig und muss nicht hardwaremäßig
entfernt werden. Allerdings kann Dauerprellen durch Vibrati-
onen den µC unnötig beschäftigen.
Ralf schrieb:
> Eventuell gibt es auch Stänkerer.

... könnte seinen Grund haben ...

Ralf schrieb:
> Ich habe das in dieser Form bei > 10 Geräten mit den unterschiedlichsten
> Typen seit Langem im Einsatz.

Ich habe >10 Drehgeber in einer Matrix in einem Gerät im Einsatz.
Die Anzahl spielt keine Rolle. Wenn es bei einem Gerät funktioniert, 
wird es auch bei anderen Geräten funktionieren. Du hast ja auch selber 
schon festgestellt, dass Deine zuerst gepostete Schaltung nicht richtig 
gewesen ist. Dennoch ist der Einsatz von Kondensatoren überflüssig. Die 
Software muss einfach richtig arbeiten.


Gruß

Jobst

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 9 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.