www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Drehencoder auswerten


Autor: donald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe hier grad ein kleines Verständnis-Problem beim Auswerten zweier 
Drehencoder an meiner Schaltung.

Ich bekomme die Daten vom Betriebssystem in meinem Programm rein und 
zwar jeweils in einer Variable für A und B der beiden Drehencoder:
char left[2];
char right[2];
In den beiden Variablen stehen auch die richtigen Werte drin.

Doch mein Encoder gibt, im optimal-Fall, 4 Werte aus pro "Klick". So 
zieht das bei meinem Test-Programm aus:
(drehung links herum)
A:1  B:1
A:0  B:1
A:0  B:0
A:1  B:0

(drehung rechts herum)
A:0  B:1
A:1  B:1
A:1  B:0
A:0  B:0

Nun weiss ich nicht genau wie ich das Auswerten kann, dass er mir nach 
der vierten Umdrehung in eine Variable schreibt, in welche Richtung er 
gedreht wurde.

Achja, Code wäre zwar schön, brauche aber nicht. Das Programmieren an 
sich ist nicht das Problem, ich weiss nur nicht genau wie ich das machen 
kann/soll...

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt hier bereits Artikel zu Encodern.
Schon gelesen?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei nochmaligem Lesen fällt mir erst auf, daß du von einem Betrübsystem 
redest.

Dann kann man das vielleicht abkürzen mit der Info:
Es geht mutmaßlich um inkrementelle Encoder. Aus denen bekommst du
immer eine Änderung der Position und musst ab einem Startwert
mitzählen.

D.h. du brauchst für jeden Encoder noch eine ganzzahlige Variable
(mit Vorzeichen, da der Wert auch negativ werden kann).
Die steht dann erst für die Position.
Zu Anfang wird sie mit 0 bspw. initialisiert.
Die Signale A und B werden jetzt nur genutzt, um diese Variable
jeweils um 1 zu erhöhen oder zu erniedrigen bei jeder Änderung.

Autor: Anton K. (antonius)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In den beiden Tabellen (Drehung links bzw. rechts herum) hast Du die 
vier Zustände von A und B aufgelistet. Jetzt geht's doch nur noch um die 
Auswertung: Bei welchem Zustandswechsel muss die Position um 1 erhöht 
und bei welchem vermindert werden.

Wenn Du Dir den letzten Zustand von A und B merkst, dann kannst Du mit 
drei XOR-Befehlen herausfinden, ob links- oder rechtsherum gedreht 
wurde.

Die Position muss nicht zwangsläufig vorzeichenbehaftet sein. Dies ist 
nur eine Frage der Interpretation.

Autor: donald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmmm so ganz hab ichs immer noch nicht verstanden, ich weiss wie die 
Werte aussehen, was sie zu sagen haben. Aber wie ich das im Programm 
hinbekomme, ist mir noch unklar.

Ich habs jetzt aber mit dem Code von Peter Danneger hinbekommen:
        int fd = open("/dev/drehgeber", 0);
        if (fd < 0) { perror("open device drehgeber"); exit(-1); }

        unsigned char last[2];
        char new[2], diff[2];
        char enc_delta[2];

        char vals[4];
        char left[2], right[2];
        int j;
        while(1) {
                read(fd, vals, 4);
                for(j = 0; j < 4; j++) vals[j] &= 0x01;
                left[0] = vals[0];
                left[1] = vals[2];
                right[0] = vals[1];
                right[1] = vals[3];

                new[LEFT] = 0;
                if( left[0] ) new[LEFT] = 3;
                if( left[1] ) new[LEFT] ^= 1;                                   // convert gray to binary
                diff[LEFT] = last[LEFT] - new[LEFT];                            // difference last - new
                if( diff[LEFT] & 1 ){                           // bit 0 = value (1)
                        last[LEFT] = new[LEFT];                                 // store new as next last
                        enc_delta[LEFT] += (diff[LEFT] & 2) - 1;                // bit 1 = direction (+/-)
                }

                new[RIGHT] = 0;
                if( right[0] ) new[RIGHT] = 3;
                if( right[1] ) new[RIGHT] ^= 1;                                   // convert gray to binary
                diff[RIGHT] = last[RIGHT] - new[RIGHT];                            // difference last - new
                if( diff[RIGHT] & 1 ){                           // bit 0 = value (1)
                        last[RIGHT] = new[RIGHT];                                 // store new as next last
                        enc_delta[RIGHT] += (diff[RIGHT] & 2) - 1;                // bit 1 = direction (+/-)
                }

                printf("left %d right %d\n", enc_delta[LEFT], enc_delta[RIGHT]);
        }



Danke für eure Mühe!

Autor: Anton K. (antonius)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Handelt es sich bei dem Encoder um einen Inkremetalgeber, der die beiden 
Spuren A&B um 90° phasenverschoben über dem Winkel (Position) ausgibt?

Oder handelt es sich um einen Gray-Encoder, der über eine Umdrehung 
absolute Winkel im Gray-Code ausgibt?

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
offenbar inkremental...

Autor: Anton K. (antonius)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn inkremental, dann probier's mal mit diesem einfachen Code:
bool  altA, neuA;
bool  altB, neuB;
bool  links;
int  position = 0;

// Initialisierung:
altA = read(A);  // aktueller Wert der Spur A vom Inkrementalgeber
altB = read(B);  // aktueller Wert der Spur B vom Inkrementalgeber

// nach jeder Signaländerung:
neuA = read(A);  // aktueller Wert der Spur A vom Inkrementalgeber
neuB = read(B);  // aktueller Wert der Spur B vom Inkrementalgeber

links = (altB XOR neuB) XOR (neuB XOR neuA)
if (links) {
  position +=1;
} else {
  position -=1;
}
altA = neuA;
altB = neuB;

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.