Componente · Attuatore

Motore con encoder N20

N20 è un piccolo motore con ingranaggi metallici ed encoder magnetico integrato, la scelta per robot bilanciatori che richiedono coppia e posizione delle ruote.

Che cos’è

N20 è il piccolo motore con ingranaggi metallici che compare ovunque un robot necessiti di una coppia utile in pochissimo spazio. Il motore nudo è grande all’incirca come una batteria AA; il riduttore sul fronte scambia l’elevatissima velocità con una coppia utilizzabile e, nella versione con encoder, un disco magnetico sull’albero posteriore riporta quanto ha ruotato.

È proprio quest’ultima parte a guadagnargli un posto in un robot bilanciatore. Senza retroazione delle ruote, un robot bilanciatore può restare in piedi ma non sa dove si trova: resterà perfettamente verticale mentre vaga per la stanza. L’encoder colma questa lacuna.

Diagramma temporale dei due canali di uscita di un encoder in quadratura. Il canale A è disegnato sopra il canale B come onde quadre della stessa frequenza, con B in ritardo di un quarto di ciclo rispetto ad A. Quattro linee verticali tratteggiate indicano le quattro transizioni che si verificano durante un ciclo elettrico, numerate da uno a quattro, con l'annotazione che contarle tutte dà 1200 conteggi per giro da un encoder da 300 CPR. Una nota indica lo sfasamento e spiega che B in ritardo su A indica movimento in avanti e B in anticipo su A indica che la ruota sta invertendo il senso.
I due canali sfasati di un quarto di ciclo sono ciò che rende questo motore degno dei suoi fili aggiuntivi: l'ordine di fase indica la direzione e il conteggio dei fronti indica la distanza. Scarica SVG

Perché qui gli ingranaggi metallici sono importanti

Un motore con riduttore in plastica come il motore con ingranaggi TT è perfettamente adatto a un robot seguitore di linea, che per lo più avanza in linea retta. Un robot bilanciatore rappresenta un carico diverso: inverte continuamente il senso, centinaia di volte al secondo, a piccoli incrementi.

Ogni riduttore presenta un gioco di inversione — una piccola zona morta in cui gli ingranaggi sono disaccoppiati e l’uscita non si muove finché i denti non si incontrano di nuovo sul lato opposto. In un riduttore in plastica questa zona morta è ampia e, in un robot bilanciatore, si trova proprio dove la correzione conta di più: al momento dell’inversione, quando le ruote devono rispondere adesso. Il risultato è un robot che oscilla attorno alla verticale e non si stabilizza mai, per quanto attentamente siano regolati i guadagni.

Gli ingranaggi metallici non eliminano il gioco di inversione, ma lo riducono quanto basta perché il ciclo possa fare il suo lavoro. Quanto rimane puoi misurarlo in circa dieci minuti: ecco come.

Lettura dell’encoder

L’encoder produce due onde quadre sfasate di 90°, la classica quadratura. La relazione di fase indica la direzione; il conteggio dei fronti indica la distanza.

Filo (tipico) Si collega a Note
M1, M2 Uscite del driver del motore Il motore stesso; la polarità determina il senso
VCC 3.3 V o 5 V Alimentazione dell’encoder, non quella del motore
GND Terra Comune con il controllore
C1 Pin in grado di generare interrupt Canale A dell’encoder
C2 Qualsiasi pin digitale Canale B dell’encoder

I colori dei fili variano tra i fornitori, quindi controlla la scheda del prodotto invece di fare supposizioni. L’errore che coglie più persone è alimentare l’encoder dalla linea di alimentazione del motore: l’encoder vuole un’alimentazione logica pulita e la tensione del motore lo distruggerà oppure riempirà i conteggi di rumore a ogni commutazione del motore.

Collega il canale A a un pin in grado di generare un interrupt. L’interrogazione dell’encoder da loop() su un robot bilanciatore perde conteggi, e conteggi persi significano che il ciclo esterno perde lentamente il tracciamento della posizione del robot.

Scelta del rapporto

Il rapporto di riduzione stabilisce il compromesso tra coppia e velocità, e un robot bilanciatore ha bisogno di entrambe:

  • Rapporto troppo alto (da 1:250 in su) offre coppia abbondante, ma le ruote non possono accelerare abbastanza da riportare sotto controllo un corpo in caduta.
  • Rapporto troppo basso (1:30 o inferiore) gira rapidamente, ma non sposta la massa del robot con forza sufficiente.

Intorno a 1:100 a 12 V, circa 200 RPM, è un punto di partenza affidabile per un piccolo robot. Se il tuo si riprende da piccole perturbazioni ma perde quelle maggiori, probabilmente serve più velocità, non più guadagno.

Pilotaggio

Abbina N20 a un TB6612FNG anziché a un L298N. Il motivo è il calo di tensione: L298N perde circa 2 V sullo stadio di uscita, quindi una parte notevole della batteria non raggiunge mai il motore e i piccoli comandi di correzione scendono sotto la tensione minima necessaria per muoverlo. Su un robot bilanciatore questa zona morta si trova proprio dove vivono le correzioni fini.

Alimentalo con un pacco batteria in grado di fornire la corrente di stallo di entrambi i motori contemporaneamente senza che la tensione ceda: una linea di alimentazione che cala riavvia il microcontrollore durante una correzione e il robot cade per ragioni che non hanno nulla a che fare con il ciclo di controllo.

Conteggi per ogni giro della ruota

È il valore da cui dipende ogni calcolo della distanza ed è quello che le persone sbagliano più spesso, di solito di un fattore quattro.

counts per wheel revolution = PPR x 4 x gear ratio

L’encoder magnetico fornisce 7 impulsi per giro del motore su ogni canale. La quadratura significa due canali sfasati di 90°, che producono quattro fronti da contare per ciclo di impulso. Il riduttore significa inoltre che il motore compie molti giri per ogni giro della ruota.

Rapporto di riduzione Conteggi per giro della ruota (×4) Risoluzione su una ruota da 43 mm
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

Da qui la distanza segue direttamente:

mm per count = (pi x wheel_diameter_mm) / counts_per_revolution

La prima formula contiene due trappole. Il fattore ×4 è corretto solo se conti davvero quattro fronti, cioè entrambi i fronti su entrambi i canali. Molto codice di esempio conta solo i fronti di salita sul canale A, quindi usa ×1; usare una costante ×4 con un conteggio ×1 rende ogni distanza sbagliata esattamente di un fattore quattro. E il rapporto di riduzione stampato sul motore è spesso approssimativo: un N20 con rapporto «1:100» è frequentemente 1:99.5 o 1:100.37. Per l’odometria su qualsiasi distanza calibra in modo empirico: spingi il robot per esattamente 2 m e dividi.

Conteggio dei fronti senza perderne

A 200 RPM con un riduttore 1:100, l’albero del motore gira a 20000 RPM, dando 20000/60 × 7 × 4 ≈ 9300 edges per second per motor. Due motori producono quasi 19000 interrupt al secondo, a velocità massima e senza carico.

Il gestore dell’interrupt deve essere davvero minimo:

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;
}

Tre dettagli contano:

volatile e una lettura atomica. Un long occupa quattro byte su un AVR e viene letto un byte alla volta. Un interrupt che arriva a metà lettura produce un valore metà vecchio e metà nuovo, provocando un enorme salto occasionale nell’odometria, a caso, all’incirca una volta ogni poche migliaia di letture.

La tabella di ricerca decodifica la transizione invece di dedurre la direzione da un solo canale. Rifiuta anche in modo naturale le transizioni non valide, in cui entrambi i bit cambiano contemporaneamente e che indicano che ne hai perso una, contribuendo con zero.

Pressione sui pin. La decodifica ×4 completa su due motori richiede quattro pin in grado di generare interrupt e Arduino Uno ne ha esattamente due. Le opzioni sono: usare la decodifica ×2, un canale per motore con CHANGE, che dimezza la risoluzione ma indica comunque il verso; passare a una scheda con più pin di interrupt come Mega o ESP32; oppure usare gli interrupt di variazione del pin, supportati da ogni pin AVR ma che richiedono di gestire un’intera porta alla volta.

Velocità dai conteggi

La posizione è un conteggio. La velocità richiede una differenza nel tempo e il modo in cui la calcoli decide se il ciclo di controllo è utilizzabile.

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;
}

La protezione su dt è la riga importante. Campiona troppo in fretta e dividerai una differenza di uno o due conteggi per un intervallo minimo: l’errore di quantizzazione domina e la «velocità» è quasi solo rumore, che il termine derivativo di un ciclo PID amplificherà volentieri.

Esistono due metodi affidabili per misurare la velocità da un encoder, adatti a estremi diversi dell’intervallo. Contare i fronti in una finestra fissa, come nel codice precedente, è valido ad alta velocità e scadente a bassa velocità, dove arrivano pochi fronti per finestra. Misurare l’intervallo tra un fronte e l’altro funziona al contrario: è eccellente a bassa velocità e rumoroso ad alta velocità. Un robot che ha bisogno di entrambi gli estremi di solito passa da un metodo all’altro in corrispondenza di una soglia.

Risoluzione dei problemi

Sintomo Causa probabile Soluzione
I conteggi sono 4× troppo piccoli Conta un solo fronte ma usi una costante ×4 Decodifica tutti e quattro i fronti oppure correggi la costante
I conteggi aumentano in entrambe le direzioni Leggi un solo canale La quadratura richiede entrambi: usa il decodificatore a tabella
Salto enorme occasionale nella posizione Lettura non atomica di un long Racchiudi la lettura in noInterrupts()
I conteggi derivano quando il motore è fermo Rumore elettrico sulle linee dell’encoder Alimenta l’encoder con una tensione pulita, non con quella del motore; intreccia la coppia di fili
Conteggi persi ad alta velocità Gestore dell’interrupt troppo lento oppure interrogazione periodica Mantieni l’ISR minimo; non interrogare mai il chip
Distanze costantemente sbagliate del 2–3% Rapporto di riduzione nominale e diametro nominale della ruota Calibra su 2 m e ricava i millimetri per conteggio
Una ruota conta, l’altra no Canale dell’encoder non su un pin di interrupt Controlla la capacità del pin; un Uno ha soltanto D2 e D3
L’encoder è morto dopo il cablaggio Tensione del motore applicata al VCC dell’encoder L’encoder vuole logica a 3.3–5 V, mai la tensione del motore
La posizione del robot deriva durante una sessione lunga L’odometria è illimitata per natura Previsto: correggila con un riferimento assoluto

N20 o motore con ingranaggi TT?

Motore con ingranaggi TT Motore N20 con ingranaggi metallici
Riduttore Plastica Metallo
Gioco di inversione Ampio: diversi gradi all’uscita Piccolo
Dimensioni Ingombrante All’incirca una batteria AA
Tensione 3–6 V Varianti da 6–12 V
Rapporti disponibili Praticamente uno solo (~1:48) Da 1:30 a 1:298
Encoder A posteriori, scomodo Magnetico integrato, standard
Costo ~$2 ~$8
Ideale per Robot seguitori di linea, primi robot Bilanciamento, odometria precisa, spazi ridotti

Il fattore decisivo è raramente la coppia e quasi sempre il gioco di inversione e la retroazione. Un robot seguitore di linea avanza quasi sempre e sterza con un sensore che guarda il pavimento: non nota mai il gioco del riduttore e un motore TT è la scelta economica giusta. Un robot bilanciatore inverte il senso centinaia di volte al secondo a piccoli incrementi, quindi la zona morta a ogni inversione si trova proprio dove la correzione deve agire e gli ingranaggi in plastica rendono il ciclo instabile qualunque sia la regolazione.

La stessa logica vale per un risolutore di labirinti: naviga contando la distanza, quindi il gioco perso a ogni curva si accumula direttamente in errore di posizione.

Usato in

  • Robot autobilanciante — i motori di trazione, con gli encoder che alimentano il ciclo esterno di posizione

Esplora il grafo

Usato in queste costruzioni

Progetti, percorsi di apprendimento e simulatori che includono Motore con encoder N20.

Confronto

Alternative

Domande

FAQ su Motore con encoder N20

Che cos'è un motore con encoder N20?

N20 è un micromotore con ingranaggi di circa 12 per 10 per 26 mm e un riduttore metallico; la versione con encoder aggiunge un piccolo disco magnetico e un sensore sul retro dell'albero del motore. Il riduttore offre molta più coppia di quanto suggeriscano le dimensioni e l'encoder riporta quanto l'albero ha realmente ruotato, non quanto gli hai chiesto di ruotare.

Perché i robot bilanciatori usano motori N20 invece dei motori TT?

Per due motivi. Il riduttore metallico ha molto meno gioco di inversione rispetto a quello in plastica di un motore TT, e il gioco di inversione è letale per un robot bilanciatore: ogni volta che il motore inverte il senso, un riduttore con gioco spreca i primi gradi di correzione senza produrre alcun movimento. L'encoder fornisce inoltre al ciclo di controllo esterno la posizione reale delle ruote, permettendo al robot di restare fermo in un punto invece di derivare.

Quanti conteggi fornisce un N20 per ogni giro della ruota?

Moltiplica gli impulsi dell'albero del motore per il rapporto di riduzione. Un encoder tipico fornisce 7 impulsi per giro del motore su ogni canale; con un riduttore 1:100 sono 700 impulsi per giro in uscita, oppure 2800 conteggi se decodifichi tutti i quattro fronti in quadratura. Verifica sempre il valore per il tuo motore specifico, perché sia il numero di impulsi sia il rapporto esatto variano tra i fornitori.

Posso pilotare un N20 direttamente da un pin di Arduino?

No. Un N20 consuma qualche centinaio di milliampere in funzione e circa 700 mA a stallo, ben oltre quanto possa fornire un pin, e la scarica induttiva lo danneggerebbe. Usa un driver del motore come TB6612FNG, la cui caduta di tensione è abbastanza bassa da consentire che anche i piccoli comandi di correzione muovano davvero il motore.

Quale rapporto di riduzione devo scegliere per un robot bilanciatore?

Qualcosa nell'intervallo da 1:50 a 1:150 è il solito compromesso. Un rapporto troppo alto offre molta coppia, ma le ruote non possono accelerare abbastanza rapidamente da interrompere una caduta; uno troppo basso non fornisce la coppia necessaria a spostare la massa del robot. Intorno a 1:100 a 12 V, circa 200 RPM, è adatto a un tipico piccolo robot bilanciatore.

Per approfondire

Fonti