Drehgeber
Als Drehgeber (auch als Inkrementaldrehgeber, IGR, Drehencoder, Drehimpulsgeber genannt) werden Sensoren zur Erfassung von Lage- oder Winkeländerungen bezeichnet. Dabei wird jeweils die Wegstrecke und Wegrichtung des Sensors erfasst. Drehgeber werden zur Positionsbestimmung in der Automatisierungstechnik sowie zur Bedienung von elektronischen Geräten verwendet. Bei einer Drehung der Achse wird am Ausgang der zwei Datenleitungen ein sogenanntes Gray-Code-Signal erzeugt. Durch die Auswertung dieses Signals kann die Richtung und die Anzahl der zurückgelegten Inkremente bestimmt werden. Mit dem Inkrementalverfahren ist keine absoluten Positionsbestimmung (Weg, Winkel) möglich, wie dies mit Absolutwertgebern möglich ist. Im Gegensatz zu Absolutwertgebern, wie Potentiometern müssen Inkrementalgeber nach dem Einschalten referenziert werden, da Änderungen der Position im ausgeschaltetem Zustand nicht erfasst werden.
Zur Erfassung des Gray-Code-Signals müssen die Datenleitungen in bestimmten Intervallen abgetastet werden. Für eine manuelle Eingabe bei Encodern ist ein Abfrageintervall von 1ms ausreichend. Das Auslesen im Hauptprogramm mit den Funktionen encode_read() muss mit mindesten ~ 8Hz erfolgen, da ansonsten können Überläufe der Variable enc_delta auftreten und zu Fehlfunktionen des Programms führen können.
Vorteile und Anwendung
- einfache Realisierung von Bedienknöpfe für Displays
- Erfassung erfolgt mit Inkrementen und nicht absolut wie bei einem Poti
- einfache Abfrage und Auswertung über 2 Pins am Controller
- keine Begrenzung der Einstellung
Mit dem folgenden Code von www.mikrocontroller.net kann man ganz einfach einen Drehencoder auswerten. Nach der Definition der Pins des Encoders muss nur dafür gesorgt werden, dass die Funktion encode_run() oft genug aufgerufen wird um das Gray-Code Signal auszuwerten. Die erfasste Information kann über encode_read() abgefragt werden. Der zurückgegebene Wert liefert dabei die Anzahl der Inkremente, um welche der Encoder gedreht wurde. Das Vorzeichen gibt Aufschluss darüber in welche Richtung der Encoder gedreht wurde.
//#################################### Encoder #define PHASE_A (PINC & 1<<PC0) // Pins anpassen #define PHASE_B (PINC & 1<<PC1) // Pins anpassen int encoder_value = 50; volatile int enc_delta; // -128 ... 127 static int last; //#################################### void encode_init( void ) { sbi(DDRC,0); sbi(PORTC,0); // Eingang + pullup - Pins anpassen sbi(DDRC,1); sbi(PORTC,1); // Eingang + pullup - Pins anpassen int8_t new; new = 0; if( PHASE_A ) new = 3; if( PHASE_B ) new ^= 1; // convert gray to binary last = new; // power on state enc_delta = 0; } //#################################### encoder read int encode_read( void ) { int8_t val; cli(); val = enc_delta; enc_delta = val & 3; sei(); return val >> 2; } //#################################### encoder auswerten void encode_run(void) { int new, diff; new = 0; if( PHASE_A ) new = 3; if( PHASE_B ) new ^= 1; // convert gray to binary diff = last - new; // difference last - new if( diff & 1 ) { // bit 0 = value (1) last = new; // store new as next last enc_delta += (diff & 2) - 1; // bit 1 = direction (+/-) } } //#################################### Timer in Millisekunden ISR(SIG_OVERFLOW0) { TCNT0 = 131; encode_run(); } //#################################### Hauptprogramm int main(void) { int value = 0; cli(); DDRA = 0xff; PORTA = 0xff; encode_init(); sei(); while(1) { value += encode_read(); PORTA = val; } //end while }
Links |
|
|
Forum - Drehgeber
|
|
Downloads |
|
|
|
|