Bauteil · Aktor
N20-Getriebemotor mit Encoder
Der N20: kleiner Motor mit Metallgetriebe und eingebautem Magnetencoder – üblicher Antrieb für Balancierroboter, die Drehmoment und Radposition brauchen.
Was es ist
Der N20 ist der kleine Metallgetriebemotor, der überall auftaucht, wo ein Roboter echtes Drehmoment auf kleinstem Raum braucht. Der nackte Motor ist etwa so groß wie eine AA-Batterie; das Getriebe vorne tauscht seine sehr hohe Drehzahl gegen brauchbares Drehmoment, und in der Encoderversion meldet eine Magnetscheibe auf der hinteren Welle, wie weit er sich gedreht hat.
Der letzte Teil verschafft ihm seinen Platz im Balancierroboter. Ohne Rad-Feedback kann ein Balancierroboter aufrecht bleiben, weiß aber nicht, wo er ist – er hält die Vertikale wunderbar und wandert dabei durch den Raum. Der Encoder schließt diese Lücke.
Warum das Metallgetriebe hier zählt
Ein Kunststoffgetriebemotor wie der TT-Getriebemotor reicht völlig für einen Linienfolger, der meist vorwärts fährt. Ein Balancierroboter ist eine andere Last: Er kehrt die Richtung fortlaufend um, hunderte Male pro Sekunde, in kleinen Schritten.
Jedes Getriebe hat Spiel – eine kleine Totzone, in der die Zahnräder ausgehängt sind und der Abtrieb sich nicht bewegt, bis die Zähne auf der anderen Seite wieder greifen. In einem Kunststoffgetriebe ist diese Totzone groß – und im Balancierroboter landet sie genau dort, wo die Korrektur am meisten zählt: im Umkehrmoment, wenn die Räder jetzt reagieren müssen. Heraus kommt ein Roboter, der um die Vertikale schwingt und sich nie ganz beruhigt – egal wie sorgfältig die Verstärkungen abgestimmt wurden.
Metallzahnräder beseitigen Spiel nicht, verringern es aber so weit, dass die Schleife ihre Arbeit tun kann. Wie viel übrig ist, lässt sich in etwa zehn Minuten messen – so geht es.
Den Encoder auslesen
Der Encoder erzeugt zwei um 90° versetzte Rechteckwellen – Standard-Quadratur. Die Phasenbeziehung sagt die Richtung; Flankenzählen sagt die Strecke.
| Leitung (typisch) | Geht an | Hinweise |
|---|---|---|
M1, M2 |
Motortreiberausgänge | Der Motor selbst; Polarität setzt die Richtung |
VCC |
3,3 V oder 5 V | Encoderversorgung, nicht die Motorversorgung |
GND |
Masse | Gemeinsam mit dem Controller |
C1 |
Interruptfähiger Pin | Encoderkanal A |
C2 |
Beliebiger Digitalpin | Encoderkanal B |
Leitungsfarben streuen zwischen Lieferanten – also die Artikelbeschreibung prüfen statt annehmen. Der Fang ist, den Encoder an der Motorschiene zu versorgen: Der Encoder will eine saubere Logikversorgung – Motorspannung darauf zerstört ihn entweder oder füllt die Zählwerte bei jedem Motorschalten mit Rauschen.
Kanal A auf einen interruptfähigen Pin legen. Einen Encoder in loop() zu pollen verliert an einem Balancierroboter Zählwerte – und verlorene Zählwerte heißen: Die äußere Schleife verliert langsam den Überblick, wo der Roboter ist.
Eine Untersetzung wählen
Die Untersetzung setzt den Tausch zwischen Drehmoment und Drehzahl – und ein Balancierroboter braucht beides:
- Zu hohe Untersetzung (1:250 und mehr) liefert reichlich Drehmoment, aber die Räder drehen nicht schnell genug hoch, um unter einen fallenden Körper zurückzukommen.
- Zu niedrige Untersetzung (1:30 und darunter) dreht schnell, bewegt die Robotermasse aber nicht mit Autorität.
Um 1:100 an 12 V – grob 200 U/min – ist ein verlässlicher Startpunkt für einen kleinen Roboter. Fängt deiner kleine Störungen ab, verliert aber größere, brauchst du wahrscheinlich mehr Drehzahl, nicht mehr Verstärkung.
Ansteuern
Den N20 mit einem TB6612FNG paaren statt L298N. Der Grund ist Dropout: Der L298N verliert grob 2 V über seiner Ausgangsstufe – ein großer Teil der Batterie erreicht den Motor also nie, und kleine Korrekturbefehle fallen unter die Spannung, ab der sich der Motor überhaupt bewegt. Am Balancierroboter sitzt diese Totzone genau dort, wo die feinen Korrekturen leben.
Von einem Akkupack versorgen, das den Blockierstrom beider Motoren zugleich liefern kann, ohne dass seine Spannung einbricht – eine einbrechende Schiene setzt den Mikrocontroller mitten in der Korrektur zurück, und der Roboter fällt aus Gründen um, die nichts mit deiner Regelschleife zu tun haben.
Zählwerte pro Radumdrehung ausrechnen
Das ist die Zahl, von der jede Streckenrechnung abhängt – und die, die Leute am häufigsten falsch haben, meist um Faktor vier.
counts per wheel revolution = PPR x 4 x gear ratio
Der Magnetencoder liefert 7 Impulse pro Motorumdrehung auf jedem Kanal. Quadratur heißt: zwei Kanäle um 90° versetzt, was vier zählbare Flanken pro Impulsperiode ergibt. Und das Getriebe heißt: Der Motor dreht sich vielfach pro Radumdrehung.
| Untersetzung | Zählwerte pro Radumdrehung (×4) | Auflösung an 43-mm-Rad |
|---|---|---|
| 1:30 | 840 | 0,16 mm |
| 1:50 | 1400 | 0,10 mm |
| 1:100 | 2800 | 0,048 mm |
| 1:150 | 4200 | 0,032 mm |
| 1:298 | 8344 | 0,016 mm |
Daraus folgt die Strecke direkt:
mm per count = (pi x wheel_diameter_mm) / counts_per_revolution
Zwei Fallen stecken in der ersten Formel. Das ×4 gilt nur, wenn man wirklich vier Flanken zählt – beide Flanken auf beiden Kanälen. Mancher Beispielcode zählt nur steigende Flanken auf Kanal A, was ×1 ist – und eine ×4-Konstante mit ×1-Zählung legt jede Strecke um exakt vier daneben. Und die aufgedruckte Untersetzung ist oft näherungsweise: Ein „1:100“-N20 ist häufig 1:99,5 oder 1:100,37. Für Odometrie über Strecke stattdessen empirisch kalibrieren: Den Roboter exakt 2 m schieben und teilen.
Die Flanken zählen, ohne eine zu verlieren
Bei 200 U/min über ein 1:100-Getriebe dreht die Motorwelle 20000 U/min, was 20000/60 × 7 × 4 ≈ 9300 Flanken pro Sekunde pro Motor ergibt. Zwei Motoren sind fast 19000 Interrupts pro Sekunde – und das bei Volldrehzahl ohne Last.
Der Interrupthandler muss wirklich klein sein:
volatile long countL = 0;
// Full x4 decoding, table-driven. Both channels, both edges.
const int8_t QUAD_TABLE[16] = {0,-1,1,0, 1,0,0,-1, -1,0,0,1, 0,1,-1,0};
volatile uint8_t prevL = 0;
void isrLeft() {
uint8_t now = (digitalRead(ENC_L_A) << 1) | digitalRead(ENC_L_B);
countL += QUAD_TABLE[(prevL << 2) | now];
prevL = now;
}
void setup() {
pinMode(ENC_L_A, INPUT_PULLUP);
pinMode(ENC_L_B, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENC_L_A), isrLeft, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENC_L_B), isrLeft, CHANGE);
}
long readCount() { // long is not atomic on an 8-bit AVR
noInterrupts();
long v = countL;
interrupts();
return v;
}
Drei Details, auf die es ankommt:
volatile und atomares Lesen. Ein long sind vier Bytes auf einem AVR, byteweise gelesen. Ein Interrupt mitten in der Lesung liefert einen halb alten, halb neuen Wert – was gelegentlich einen riesigen Sprung in der Odometrie erzeugt, zufällig, grob einmal in wenigen tausend Lesungen.
Die Nachschlagetabelle dekodiert den Übergang statt die Richtung aus einem Kanal zu raten. Sie verwirft ungültige Übergänge (beide Bits wechseln zugleich – was heißt: einen verpasst) von Natur aus, indem sie null beiträgt.
Pindruck. Volle ×4-Dekodierung an zwei Motoren braucht vier interruptfähige Pins, und ein Arduino Uno hat exakt zwei. Die Optionen: ×2-Dekodierung (ein Kanal pro Motor, CHANGE) – halbiert Auflösung, liefert weiter Richtung; auf ein Board mit mehr Interrupts wechseln wie Mega oder ESP32; oder Pin-Change-Interrupts, die jeder AVR-Pin unterstützt, aber einen ganzen Port auf einmal zu behandeln verlangen.
Drehzahl aus Zählwerten
Position ist ein Zählwert. Drehzahl braucht eine Differenz über Zeit – und wie man sie nimmt, entscheidet, ob die Regelschleife brauchbar ist.
long lastCount = 0;
unsigned long lastMicros = 0;
float speedMmPerSec() {
long c = readCount();
unsigned long t = micros();
float dt = (t - lastMicros) * 1e-6f;
if (dt < 0.005f) return lastSpeed; // too short: quantisation dominates
float mm = (c - lastCount) * MM_PER_COUNT;
lastCount = c; lastMicros = t;
lastSpeed = mm / dt;
return lastSpeed;
}
Die dt-Wache ist die wichtige Zeile. Zu schnell abgetastet, und man teilt eine Differenz von ein, zwei Zählwerten durch ein winziges Intervall – der Quantisierungsfehler dominiert und die „Drehzahl“ ist meist Rauschen, das ein D-Anteil in einer PID-Schleife dann begeistert verstärkt.
Es gibt zwei ehrliche Arten, Drehzahl aus einem Encoder zu messen, und sie passen zu verschiedenen Enden des Bereichs. Flanken in einem festen Fenster zählen (der Code oben) ist gut bei hoher Drehzahl und schwach bei niedriger, wo wenige Flanken pro Fenster eintreffen. Das Intervall zwischen Flanken messen ist umgekehrt: hervorragend bei niedriger Drehzahl, verrauscht bei hoher. Ein Roboter, der beide Enden braucht, schaltet meist an einer Schwelle um.
Fehlersuche
| Symptom | Wahrscheinliche Ursache | Lösung |
|---|---|---|
| Zählwerte 4× zu klein | Eine Flanke gezählt, ×4-Konstante verwendet | Alle vier Flanken dekodieren oder Konstante richten |
| Zählwerte wachsen in beide Richtungen | Nur ein Kanal gelesen | Quadratur braucht beide – den Tabellendekoder verwenden |
| Gelegentlicher Riesensprung in der Position | Nichtatomares Lesen eines long |
Lesung in noInterrupts() wickeln |
| Zählwerte driften bei stehendem Motor | Elektrisches Rauschen auf den Encoderleitungen | Encoder an saubere Versorgung, nicht Motorschiene; das Paar verdrillen |
| Zählwerte gehen bei hoher Drehzahl verloren | Interrupthandler zu langsam oder Pollen | ISR winzig halten; nie pollen |
| Strecken konstant 2–3 % daneben | Nennuntersetzung und Raddurchmesser | Über 2 m kalibrieren und mm-pro-Zählwert ableiten |
| Ein Rad zählt, das andere nicht | Encoderkanal an keinem Interruptpin | Pinfähigkeit prüfen; ein Uno hat nur D2 und D3 |
| Encoder starb nach Verdrahtung | Motorspannung an Encoder-VCC | Der Encoder will 3,3–5-V-Logik, nie die Motorschiene |
| Roboterposition driftet über lange Fahrt | Odometrie ist naturgemäß unbegrenzt | Erwartet – mit absoluter Referenz korrigieren |
N20- oder TT-Getriebemotor?
| TT-Getriebemotor | N20-Metallgetriebemotor | |
|---|---|---|
| Getriebe | Kunststoff | Metall |
| Spiel | Groß – mehrere Grad am Abtrieb | Klein |
| Größe | Sperrig | Etwa eine AA-Batterie |
| Spannung | 3–6 V | 6–12-V-Varianten |
| Verfügbare Untersetzungen | Im Wesentlichen eine (~1:48) | 1:30 bis 1:298 |
| Encoder | Nachgerüstet, umständlich | Integriert magnetisch, Standard |
| Kosten | ~2 $ | ~8 $ |
| Am besten für | Linienfolger, erste Roboter | Balancieren, präzise Odometrie, enge Räume |
Der entscheidende Faktor ist selten Drehmoment und fast immer Spiel und Feedback. Ein Linienfolger fährt meist vorwärts und lenkt nach einem Sensor, der auf den Boden schaut – Getriebespiel bemerkt er nie, und ein TT-Motor ist die richtige, billige Antwort. Ein Balancierroboter kehrt die Richtung hunderte Male pro Sekunde in winzigen Schritten um – die Totzone bei jeder Umkehr liegt also exakt dort, wo seine Korrektur wirken muss, und Kunststoffzahnräder machen die Schleife instabil, egal wie sie abgestimmt ist.
Dieselbe Logik gilt für einen Labyrinthlöser: Er navigiert per Streckenzählung – verlorene Bewegung an jeder Drehung summiert sich also direkt in Positionsfehler.
Verwendet in
- Selbstbalancierender Roboter – die Antriebsmotoren, mit den Encodern in der äußeren Positionsschleife
Den Graphen erkunden
Verwendet in diesen Bauprojekten
Projekte, Lernpfade und Simulatoren, die N20-Getriebemotor mit Encoder verwenden.
- ProjektEinen Mecanum-Roboter bauen, der seitwärts fährt
- ProjektEinen Raumabdeckungsroboter bauen, der Böden kehrt
- ProjektEinen ROS-2-Roboter bauen, der sieht und zu einem Marker fährt
- ProjektGPS-Wegpunkt-Rover bauen: Fährt seine Route selbst
- ProjektMicromouse bauen: Labyrinth-Roboter mit Flood-Fill
- ProjektMini-Sumo-Roboter bauen: Grip, Keil, Kantensensorik
- ProjektSelbstbalancierender Roboter: MPU6050 und PID
- LernpfadHolonomer Antrieb: Seitwärts fahren ohne Drehen
Vergleich
Alternativen
Fragen
FAQ zu N20-Getriebemotor mit Encoder
Was ist ein N20-Encodermotor?
Ein N20 ist ein Mikrogetriebemotor von etwa 12 mal 10 mal 26 mm mit Metallgetriebe – die Encoderversion ergänzt eine kleine Magnetscheibe mit Sensor auf der hinteren Motorwelle. Das Getriebe liefert weit mehr Drehmoment, als seine Größe vermuten lässt, und der Encoder meldet, wie weit sich die Welle wirklich gedreht hat, statt wie weit man sie zu drehen verlangte.
Warum nutzen Balancierroboter N20-Motoren statt TT-Motoren?
Aus zwei Gründen. Das Metallgetriebe hat deutlich weniger Spiel als das Kunststoffgetriebe eines TT-Motors – und Spiel ist Gift für einen Balancierroboter: Bei jeder Motorumkehr vergeudet ein loses Getriebe die ersten paar Grad Korrektur mit Nichtstun. Der Encoder liefert der äußeren Regelschleife außerdem echte Radposition – womit der Roboter einen Fleck halten kann statt zu driften.
Wie viele Encoderzählwerte liefert ein N20 pro Radumdrehung?
Motorwellenimpulse mal Untersetzung multiplizieren. Ein typischer Encoder liefert 7 Impulse pro Motorumdrehung und Kanal; an einem 1:100-Getriebe sind das 700 Impulse pro Abtriebsumdrehung oder 2800 Zählwerte bei Auswertung aller vier Quadraturflanken. Die Zahl des eigenen Motors immer bestätigen – Impulszahl wie exakte Untersetzung streuen zwischen Lieferanten.
Kann ich einen N20 direkt an einem Arduinopin treiben?
Nein. Ein N20 zieht laufend mehrere hundert Milliampere und blockiert rund 700 mA – weit jenseits dessen, was ein Pin liefert –, und die induktive Rückwirkung beschädigt ihn. Einen Motortreiber wie den TB6612FNG verwenden, dessen Spannungsabfall außerdem klein genug ist, dass kleine Korrekturbefehle den Motor wirklich noch bewegen.
Welche Untersetzung soll ich für einen Balancierroboter wählen?
Etwas im Bereich 1:50 bis 1:150 ist der übliche Kompromiss. Zu hohe Untersetzung liefert reichlich Drehmoment, aber die Räder beschleunigen nicht schnell genug, um einen Fall abzufangen; zu niedrige dreht schnell, bewegt die Robotermasse aber nicht mit Autorität. Um 1:100 an 12 V mit grob 200 U/min passt zu einem typischen kleinen Balancierroboter.
Weiterführende Literatur