ALPS STEC11 Drehgeber mit Atmel AVR uControllern auslesen

Prinzip

Die Drehgeber von ALPS der Serie STEC11 (für 11mm) sind in mehreren Ausführungen für horizontale und vertikale Montage mit und ohne Druckschalter erhältlich. Die meisten Modelle besitzen 30 Raststellungen, es sind aber auch welche mit 18 und sogar ganz ohne erhältlich.

Der Anschluss erfolgt über drei Kontakte A, B und eine gemeinsame Masse. Typischerweise werden A und B über pull-up Widerstände an die positive Betriebsspannung gelegt und beim Drehen nacheinander auf den gemeinsamen Masseanschluss gezogen. Die Modelle mit Drucktaster verfügen über zwei separate Anschlüsse für den Tastkontakt.

Die Drehgeber liefern zwei phasenverschobene Signale an A und B, die die Ermittlung der Drehrichtung erlauben. Die Ausgabe erfolgt im Gray-Code und hat daher die Eigenschaft, bei jedem Schritt nur eines der zwei Bit zu verändern, was den Code störunanfälliger macht. Die Tabellen zeigen die Sequenzen bei Links- und Rechtsdrehung. Die Tabelle rechts zeigt ausserdem die Konvertierung des 2Bit-Graycodes in einen Binärwert. Wendet man diese Konvertierung auf die Sequenzen bei Links- und Rechtsdrehung an, erhält man für eine Linksdrehung die Werte 0,3,2,1 und rechts 0,1,2,3. Das sieht doch gleich viel logischer aus!

Auswertung

Es ist verlockend, die Drehgeber über einen Interrupt auszuwerten, der z.B. bei steigender und fallender Flanke von Ausgang A triggert. Im Interrupt wird der Zustand des anderen Ausgangs abgefragt; ist er 0 bei steigender Flanke, war es eine Linksrehung, ansonsten handelt es sich um eine Rechtsdrehung. In der Praxis scheitert diese Lösung am Kontaktprellen der Drehgeber, das viele zusätzliche Interrupts generiert. Hier könnte man zwar mit etwas Analogelektrik ein Filter nachrüsten, sinnvoller und ökonomischer ist dagegen die Abtastung im Timer-Interrupt.

Wie man aus den Sequenzen sieht, kann man die Richtung nur dann zuverlässig erkennen, falls alle Einzelschritte erkannt werden: Beobachtet man einen Wechsel von 00 auf 11 oder von 01 auf 10, bedeutet das, dass man einen Schritt verpasst hat (da sich beide Bits gleichzeitig verändert haben), es ist aber unmöglich, zu sagen, ob es sich dabei um eine Links- oder eine Rechtsdrehung gehandelt hat. Die Abtastfrequenz muss also entsprechend hoch gewählt werden. Ich habe mit 256 Hz gute Erfahrungen gemacht; ab 1kHz ist man in jedem Fall auf der sicheren Seite.

Methode 1: Tabelle

Die einfachste Möglichkeit besteht darin, aus dem alten und aktuellen Wert des Drehgebers einen 4-Bit Wert zu bilden und als Index auf eine Tabelle zu verwenden, die das Inkrement enthält. Von den 16 möglichen Zuständen in dieser Tabelle entsprechen 4 dem Fall, dass überhaupt keine Bewegung stattgefunden hat (0000, 1111, 0101, 1010); hier ist das Ergebnis 0. Jeweils vier Zustände entsprechen den Sequenzen für die Links- und Rechtsdrehung und führen zu den Werten -1 bzw. +1. Die verbleibenden vier Werte entsprechen einem Doppelschritt (0011, 0110, 1001, 1100); die Tabelle sieht hierfür den Wert 0 vor, ignoriert solche Schritte also. Man könnte auch einen Fehlercode ablegen und gesondert handhaben. Ich habe das zu debugging-Zwecken mal gemacht, um festzustellen, wie häufig Doppelschritte bei niedrigen Abtastfrequenzen vorkommen.

Methode 2: Direkte Konvertierung

Man kann die Gray-Binärumsetzung auch explizit vornehmen - bei nur 2 Bits, also vier möglichen Zuständen, ist das schnell gemacht.

1. initialisiere Wert mit 0

2. falls Eingang A aktiv, setze den Wert auf 3

3. falls Eingang B aktiv, verknüpfe den Wert Exclusiv-Oder mit 1

4. ermittle die Differenz aus altem und neuem Wert. Wir erhalten die Werte -3 oder 1 für eine Linksdrehung, bzw. 3 oder -1 für eine Rechtsdrehung. Ein Wert von 2 oder -2 deutet auf einen Fehler hin.

5. Sofern Bit 0 der Differenz aus altem und neuem Wert gesetzt ist, haben wir einen gültigen Einzelschritt. In diesem Fall wird der neue Wert als alter Wert gespeichert, und der Zähler um die Differenz, und-verknüpft mit 2 und um 1 reduziert, inkrementiert.

Die letzte Operation verdient eine genauere Betrachtung. Nach der Und-Verknüpfung mit 2 erhält man den Wert 0 für eine Linksdrehung bzw. 2 für eine Rechtsdrehung. Nach der Subtraktion von 1 erhält man das Inkrement, -1 für links und +1 für Rechts.

Umsetzung in Assembler

Die Umsetzung in AVR-Assembler ist einfach:

Methode 2:

;Drehgeber auslesen

start: Clr val          ;Wert löschen
       In temp, portd   ;I/O-Port einlesen - hier ist es D
       Sbrc temp,bitA   ;falls Portbit Eingang A 0 ist, skip
       Ldi val,#3       ;Wert mit 3 linitialisieren
       Sbrc temp, bitB  ;falls Portbit Eingang B 0 ist, skip
       Eori val,#1      ;exclusiv-oder Wert mit 1
       Mov temp, prev   ;alten Wert laden
       Sub temp, val    ;neuen Wert abziehen
       Sbrs temp, bit0  ;falls bit 0 gesetzt ist, skip
       Rjmp exit        ;fertig, Wert ignorieren
       Mov prev,val
       Andi temp,#2
       Subi temp,#1
       Add cnt,temp
Exit:  mov prev, val
       ret
 

Statistics