Zum Hauptinhalt springen

Bestimung des Fahrtwegs mit dem Motorencoder

Inkrementalgeber (Incremental Encoder)

Eine der ersten Aufgaben für den selbstgebauten Roboter war es, den Roboter eine Strecke von 1,5 Meter fahren zu lassen. Die Lösung konnte nur durch Probieren von unterschiedliche langen Fahrzeit ermittelt werden. Was dem selbstgebauten Roboter fehlte, war die Möglichkeit den zurückgelegten Fahrtweg zu messen.

Sind die Motoren (oder Räder) mit einem Inkrementalgeber (Radencoder) ausgestattet, kann mit diesen bestimmt werden, wie weit sich die einzelnen Motoren zwischen zwei Messungen gedreht haben. Dadurch wird es möglich sowohl die Geschwindigkeit auch als die gefahrene Strecke oder auch die aktuelle Position des Roboters zu bestimmen

Der Zumo 32u4 hat an jedem Motor einen Quadratur-Encoder, welcher mit einer magnetischen Scheibe pro Motorwelle und zwei Hall-Effekt-Sensoren für jeden Motor realisiert ist. Der Quadratur-Encoder hat eine Auflösung von 12 Schritten pro Umdrehung.

Da die Räder nicht direkt, sondern mit einem Getriebe mit der Motorwelle verbunden sind (Übersetzung 75.81:1), führt das zu einer Auflösung von 12×75.81909,712\times 75.81 \approx 909,7 Impulsen pro Umdrehung (CPR - counts per revolution).

Ein Radencoder für die Odometrie

Quadratur-Encoder (Quadrature Encoder)

Der oben dargestellte Rad-Encoder ist ein sehr einfacher Inkrementalgeber. Was diesem Encoder fehlt, ist die Möglichkeit die Drehrichtung des Rades zu bestimmen. Ein Quadratur-Encoder schafft hier Abhilfe.

Bei einem Quadratur-Encoder wird das Rad nicht mit einem Sensor, sondern mit zwei räumlich versetzten Sensoren abgetastet. Dadurch ergibt sich nicht nur eine Impulsfolge, welche angibt, wie weit sich das Rad gedreht hat, sondern zwei Impulsfolgen (A und B) aus welchen zusätzlich auch die Drehrichtung bestimmt werden kann.

Drehrichtung im Uhrzeigersinn

In der dargestellten Abbilung sind die beiden Encoder-Sensoren mit den Buchstaben A und B bezeichnet. Der rechte Sensor (A) ist bei einer Drehung im Uhrzeigersinn der Sensor, welcher zuerst die Zustandsänderungen (von 0 auf 1 oder andersrum) detektiert. Der Sensor B wird die selbe Zustandsänderung kurz danach detektieren. Das bedeutet, dass direkt nach dem Zustandswechsel des Sensors A, der Sensor B noch im alten Zustand ist.

Bei einer Drehung im Uhrzeigersinn gilt bei der Zustandsänderung des Sensors B: B=!A.

Quadratur Encoder

Drehrichtung entgegen dem Uhrzeigersinn

Dreht sich das Rad entgegen dem Uhrzeigersinn ist der Sensor B der führende Sensor und erkennt die Zustandsänderung als erstes. Aus Sicht des Sensors A bedeutet das, dass der Sensor A bei einer Zustandsänderung den bereits detektierten Zustand vom Sensor B annimmt.

Bei einer Drehung entgegen dem Uhrzeigersinn gilt bei der Zustandsänderung des Sensors B: B=A.

Quadratur Encoder

Auslesen der Rad-Encoder beim Zumo 32u4

In der Zumo32u4-Bibliothek wird die Klasse Zumo32U4Encoders bereitgestellt, welche es mit den Methode getCountsLeft() und getCountsRight() ermöglicht, die vom Encoder gemessenen Impulse auszugeben.

Die Methoden zum Auslesen der Rad-Encoder verwenden im Hintergrund so genannte Interrupt-Funktionen, welches jedesmal, wenn die Encoder einen Impuls erhalten, eine globale Variable im eins erhöhen oder verringern (abhängig von der Drehrichtung). Die Methoden getCountsLeft() und getCountsRight() geben dann die aktuelle Anzahl der aufsummierten Impulse pro Rad an.

Die Methoden getCountsAndResetLeft() und getCountsAndResetRight() verhalten sich wie die anderen beiden Funktionen, setzten jedoch die entsprechende globale Variable für die aufsummierten Impulse zurück.

caution

Damit die globalen Zähler für die Encoder-Impulse nicht überlaufen, sollten regelmäßig die Funktionen getCountsAndResetLeft() und getCountsAndResetRight() aufgerufen werden.

// Anzeigen der Encoder-Werte auf dem Display 

#include <Wire.h>
#include <Zumo32U4.h>

Zumo32U4Encoders encoders; // Encoder-Objekt deklarieren
Zumo32U4LCD lcd;

unsigned long lastDisplayTime = 0;

void setup() {
// bleibt leer
}

void loop() {
if ((millis() - lastDisplayTime) > 100) {

int countsLeft = encoders.getCountsLeft(); // Auslesen des globalen Impuls-Zählers
int countsRight = encoders.getCountsRight(); // Die Impulse werden im Hintergrund gezählt

lcd.clear();
lcd.print(countsLeft);
lcd.gotoXY(0, 1);
lcd.print(countsRight);

lastDisplayTime = millis();
}
}
Aufgaben
  1. Die Radencoder haben eine Auflösung von 909,7 Impulsen pro Rad-Umdrehung. Bestimmen Sie rechnerisch, wie weit der zurückgelegte Weg zwischen zwei Encoder-Impulsen ist (Millimeter pro Impuls). Hinweis: Messen Sie den Durchmesser der Räder.
  2. Messen Sie die Anzahl der Encoder-Impulse die benötigt werden, um eine Strecke von exakt 20 cm zurückzulegen. Bestimmen Sie hieraus die Encoder-Auflösung (in Millimeter pro Impulse).
  3. Schreiben Sie ein Programm, welches den Roboter mit Hilfe der Rad-Encoder exakt 20 cm weit fahren lässt. Geben Sie auf dem Display die gefahrene Strecke in Millimetern an. Vergleichen Sie Ihr Ergebnis mit der Aufgabe 2. (Die zurückgelegt Strecke sollte als Mittelwert aus den beiden Rad-Encodern berechnet werden.)
  4. Wiederholen Sie die letzte Aufgabe. Versuchen Sie jedoch den Roboter die 20 cm so schnell wie möglich zurücklegen zu lassen. Messen Sie die Zeit. (Hinweis: Nutzen Sie einen geeigneten Regler)