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.

Zeitdiagramm der zwei Ausgangskanäle eines Quadraturencoders. Kanal A ist über Kanal B als gleichfrequente Rechteckwellen gezeichnet, B um eine Viertelperiode versetzt. Vier vertikale Strichellinien markieren die vier Übergänge innerhalb einer elektrischen Periode, nummeriert eins bis vier, mit Anmerkung, dass Zählen aller vier aus einem 300-CPR-Encoder 1200 Zählwerte pro Umdrehung ergibt. Ein Hinweis an der Phasenverschiebung erklärt, dass B-hinter-A Vorwärtsfahrt und B-vor-A Rückwärtsfahrt des Rads heißt.
Die zwei Kanäle im Viertelperiodenversatz machen diesen Motor seine Extradrähte wert: Die Phasenfolge liefert die Richtung, die Flankenzahl die Strecke. SVG herunterladen

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

Den Graphen erkunden

Verwendet in diesen Bauprojekten

Projekte, Lernpfade und Simulatoren, die N20-Getriebemotor mit Encoder verwenden.

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

Quellen