Forum: Mikrocontroller und Digitale Elektronik Drehencoder "Zwischen der Rastung"


von Richard B. (Gast)


Lesenswert?

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.

von Εrnst B. (ernst)


Lesenswert?

Dein Encoder hat also zwei Schritte pro Rastung?

Verwende auch eine entsprechende Auslese-Routine, die das 
Wackeln/Prellen im Zwischenschritt rausfiltert.

im Codebeispiel hier: Drehgeber wäre es die "encode_read2".

von Richard B. (Gast)


Lesenswert?

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.

von W.S. (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

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


Lesenswert?

Richard B. schrieb:
> mit ca. nem kiloHerz
Das ist ein dicker Brocken.
Und Heinrich schrieb seinen Nachnamen mit t vor dem z

von Wolfgang (Gast)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

Richard B. schrieb:
> Das heißt ich drehe innerhalb der Rastung.

Nenn das Kind ruhig beim Namen.

Du eierst auf dem Schaltpunkt des einen Encoderkanals rum.

von Richard B. (Gast)


Lesenswert?

Kann ich die Hysterse auch in Software abbilden?

von c-hater (Gast)


Lesenswert?

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.

von Richard B. (Gast)


Lesenswert?

Wie bilde ich diese denn in Software ab?

von Εrnst B. (ernst)


Lesenswert?

Richard B. schrieb:
> Wie bilde ich diese denn in Software ab?

z.B. so:

Εrnst B. schrieb:
> im Codebeispiel hier: Drehgeber wäre es die "encode_read2".

nur jeder zweite Drehimpuls wird ausgegeben, das Rumgeeiere zwischen den 
Rastungen weggerundet.

von Richard B. (Gast)


Lesenswert?

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.

von Jobst M. (jobstens-de)


Lesenswert?

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

von Richard B. (Gast)


Lesenswert?

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

von Εrnst B. (ernst)


Lesenswert?

Richard B. schrieb:
> Musste gestern feststellen, je langsamer ich werde, desto mehr
> prellen
> die Kontakte...

Hast du schon ausprobiert, die Pegelwechsel zwischen den Rastungen zwar 
in der Statemachine mitzunehmen, aber im Hauptprogramm nicht 
auszuwerten?

--> Drehgeber.

Oder liest du µC.net Wiki-Artikel aus Prinzip nicht?

von Soul E. (Gast)


Lesenswert?

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.

von Georg (Gast)


Lesenswert?

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

von Ralf (Gast)


Lesenswert?

Wenn man 4 Widerstände und 2 Kondensatoren in SMD-Bauform "spendiert", 
erspart man sich langwieriges Anpassen des Programmes. So, wie das hier 
"Johnny SGT" getan hat:
http://www.mikrocontroller.net/attachment/297926/rot.png

von Jobst M. (jobstens-de)


Lesenswert?

Ralf schrieb:
> Wenn man 4 Widerstände und 2 Kondensatoren in SMD-Bauform "spendiert",
> erspart man sich langwieriges Anpassen des Programmes.

Evtl. gibt es ja Stecksockel für den Drehgeber. Der findet das nämlich 
nicht witzig, ständig den Kondensator kurz zu schließen.


Gruß

Jobst

von sinnsuche (Gast)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

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.

von Harald W. (wilhelms)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

HALT--
Ich muß mich korrigieren: Figure 2 auf der rechten Seite enthält die 
korrekte Schaltung, bei der die Kondensatoren nicht direkt an den 
Richtungskontakten liegen

http://www.dream-dimensions.de/2015/10/using-rotary-encoders/

von Jobst M. (jobstens-de)


Lesenswert?

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

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.