Come usare il driver L298N con Arduino: motori, collegamenti e codice
Il modulo L298N motor driver permette ad Arduino di controllare due motori DC con spazzole oppure un motore passo-passo bipolare. Arduino decide direzione e velocità, mentre il modulo fornisce ai motori la corrente proveniente da un'alimentazione esterna. Questa separazione è fondamentale: i pin di Arduino generano soltanto segnali logici e non devono alimentare direttamente i motori.
Che cos'è il modulo L298N?
Il circuito integrato L298N contiene due ponti H completi, chiamati canale A e canale B. Ogni ponte H può invertire la polarità applicata a un motore: in questo modo lo stesso motore può girare in entrambi i versi. I due canali sono indipendenti, quindi puoi controllare separatamente due motori.
Il modulo aggiunge al chip i morsetti a vite, i diodi di ricircolo, i condensatori, un dissipatore e, nei modelli più comuni, un regolatore da 5 V. Non è però un regolatore di velocità autonomo: riceve da Arduino i comandi IN1-IN4 ed ENA/ENB.
Come funziona un ponte H
Un ponte H usa quattro interruttori elettronici disposti attorno al motore. Attivando una coppia di interruttori, la corrente attraversa il motore in una direzione; attivando la coppia opposta, la corrente si inverte e il motore cambia verso.
Quando i due ingressi di un canale hanno valori opposti, il motore gira. Quando gli ingressi sono uguali e il canale è abilitato, il L298N esegue un arresto rapido. Quando invece ENA o ENB viene portato a LOW, il ponte corrispondente viene disabilitato e il motore si arresta lasciandosi trascinare più liberamente.
Pinout e componenti del modulo L298N
Output A e Output B
Sono le due coppie di morsetti per i motori. Output A è comandata da IN1, IN2 ed ENA; Output B è comandata da IN3, IN4 ed ENB. L'ordine dei due fili determina quale verso viene considerato “avanti”. Se un motore gira al contrario, puoi invertire i suoi fili oppure cambiare la logica nel programma.
Morsetti di alimentazione: VS, GND e 5V
Il morsetto spesso indicato come 12V o VS riceve l'alimentazione di potenza dei motori. La scritta 12V non significa che devi usare sempre 12 V: la tensione va scelta in base ai motori e ai limiti del modulo. Il morsetto centrale è GND; il terzo è il collegamento logico da 5 V associato al regolatore presente sulla scheda.
IN1, IN2, IN3 e IN4
Sono gli ingressi logici di direzione. IN1 e IN2 controllano il canale A; IN3 e IN4 controllano il canale B. Vengono collegati a normali pin digitali di Arduino e pilotati con digitalWrite().
ENA ed ENB
Abilitano i due ponti H. Con il relativo jumper inserito, il pin è mantenuto HIGH e il motore funziona alla massima velocità disponibile. Per regolare la velocità, rimuovi il jumper e collega ENA o ENB a un pin PWM di Arduino; nel circuito allegato ENA usa il pin 10 ed ENB il pin 5.
Jumper “5V onboard enable”
Nei comuni moduli questo jumper collega il regolatore integrato alla logica del L298N. Quando il jumper è inserito e l'alimentazione motori è compatibile con il regolatore della scheda, la logica viene alimentata internamente e il morsetto 5V può comportarsi come uscita. Non collegare contemporaneamente a quel morsetto il 5V di Arduino senza aver verificato la configurazione del modulo.
Quando il jumper viene rimosso, la logica deve generalmente ricevere un 5 V regolato dall'esterno attraverso il morsetto 5V. I moduli commerciali non sono tutti identici: controlla sempre le scritte sulla scheda e la documentazione del tuo modello.
Diodi, condensatori e dissipatore
I motori sono carichi induttivi e possono generare picchi di tensione quando la corrente cambia rapidamente. I diodi montati sul modulo forniscono un percorso di ricircolo per questa corrente. I condensatori stabilizzano l'alimentazione, mentre il dissipatore aiuta a rimuovere il calore prodotto dal L298N.
Tabella di controllo di un motore
| Enable | Ingresso 1 | Ingresso 2 | Risultato |
|---|---|---|---|
| HIGH | HIGH | LOW | Rotazione in un verso |
| HIGH | LOW | HIGH | Rotazione nel verso opposto |
| HIGH | LOW | LOW | Arresto rapido |
| HIGH | HIGH | HIGH | Arresto rapido |
| LOW | Qualsiasi | Qualsiasi | Ponte disabilitato, arresto libero |
La stessa tabella vale per IN3 e IN4 del canale B. I nomi “avanti” e “indietro” dipendono da come hai collegato fisicamente il motore.
Come si regola la velocità con il PWM
Arduino UNO non produce una tensione analogica continua sui normali pin PWM. La funzione analogWrite() genera invece una sequenza rapida di impulsi: aumentando la percentuale di tempo in cui il segnale rimane HIGH, aumenta la potenza media fornita al motore.
Il valore può andare da 0 a 255: 0 disabilita il canale, 255 richiede la massima potenza e valori intermedi producono velocità intermedie. Per questo ENA ed ENB devono essere collegati a pin contrassegnati dal simbolo ~ e i relativi jumper devono essere rimossi.
Circuito base con Arduino UNO e due motori
- ENA → Arduino pin 10 PWM
- IN1 → Arduino pin 9
- IN2 → Arduino pin 8
- IN3 → Arduino pin 7
- IN4 → Arduino pin 6
- ENB → Arduino pin 5 PWM
- Output A → primo motore
- Output B → secondo motore
- positivo alimentazione motori → morsetto VS/12V del modulo
- negativo alimentazione → GND del modulo
- GND del modulo → GND di Arduino
La massa comune è indispensabile: Arduino e L298N devono interpretare HIGH e LOW rispetto allo stesso riferimento. Arduino può essere alimentato tramite USB o con una propria alimentazione adatta; non collegare la tensione dei motori al pin 5V di Arduino.
Scegli l'alimentazione in base alla tensione nominale e soprattutto alla corrente di spunto dei motori. Il disegno mostra l'ingresso di potenza del modulo, ma non significa che ogni motore debba essere alimentato a 12 V.
Codice fondamentale per due motori
// https://nemiatools.com
// Canale A - motore sinistro
const byte ENA = 10; // Pin PWM per la velocita
const byte IN1 = 9;
const byte IN2 = 8;
// Canale B - motore destro
const byte IN3 = 7;
const byte IN4 = 6;
const byte ENB = 5; // Pin PWM per la velocita
void setMotorA(int speed) {
speed = constrain(speed, -255, 255);
if (speed > 0) {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, speed);
}
else if (speed < 0) {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA, -speed);
}
else {
analogWrite(ENA, 0);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}
}
void setMotorB(int speed) {
speed = constrain(speed, -255, 255);
if (speed > 0) {
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(ENB, speed);
}
else if (speed < 0) {
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(ENB, -speed);
}
else {
analogWrite(ENB, 0);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}
}
void stopMotors() {
setMotorA(0);
setMotorB(0);
}
void setup() {
pinMode(ENA, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENB, OUTPUT);
stopMotors();
}
void loop() {
// Entrambi i motori in avanti a velocita media
setMotorA(180);
setMotorB(180);
delay(2000);
stopMotors();
delay(1000);
// Entrambi i motori indietro
setMotorA(-180);
setMotorB(-180);
delay(2000);
stopMotors();
delay(1000);
// Rotazione sul posto: i motori girano in versi opposti
setMotorA(180);
setMotorB(-180);
delay(2000);
stopMotors();
delay(1000);
}
Le funzioni setMotorA() e setMotorB() accettano valori da -255 a 255. Un valore positivo seleziona un verso, un valore negativo inverte gli ingressi e 0 disabilita il canale. La funzione constrain() impedisce che il valore superi l'intervallo ammesso da analogWrite().
Nel loop i motori avanzano, si fermano, girano indietro e infine ruotano in versi opposti. Su un piccolo robot, l'ultima combinazione provoca una rotazione sul posto.
Esempio minimo per un solo motore
// Un solo motore sul canale A
const byte ENA = 10;
const byte IN1 = 9;
const byte IN2 = 8;
void setup() {
pinMode(ENA, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
}
void loop() {
// Avanti
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, 200);
delay(2000);
// Arresto libero: ENA a 0
analogWrite(ENA, 0);
delay(1000);
// Indietro
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA, 200);
delay(2000);
analogWrite(ENA, 0);
delay(1000);
}
Caduta di tensione e riscaldamento
Il L298N utilizza transistor bipolari e introduce una caduta di tensione significativa. Il motore riceve quindi una tensione inferiore rispetto a quella applicata al morsetto VS, soprattutto quando la corrente aumenta. Questo riduce l'efficienza e trasforma parte dell'energia in calore.
Il chip può raggiungere correnti elevate nelle condizioni previste dal datasheet, ma un piccolo modulo commerciale non deve essere considerato automaticamente capace di fornire 2 A continui per canale. La corrente realmente utilizzabile dipende da dissipatore, ventilazione, tensione, cablaggio e qualità della scheda. Controlla sempre la corrente di stallo del motore, non soltanto la corrente a vuoto.
Regole importanti di alimentazione
- non alimentare i motori dal pin 5V di Arduino;
- collega sempre insieme il GND di Arduino e il GND del modulo;
- usa una sorgente capace di fornire la corrente di avviamento dei motori;
- non cambiare cablaggio mentre il circuito è alimentato;
- rimuovi i jumper ENA/ENB quando vuoi controllare la velocità via PWM;
- verifica la funzione del jumper del regolatore prima di usare il morsetto 5V;
- se il dissipatore diventa molto caldo, interrompi la prova e riduci il carico.
Applicazioni del modulo L298N
- robot a due ruote e rover Arduino;
- piccoli veicoli telecomandati;
- nastri trasportatori e meccanismi reversibili;
- attuatori con motori DC;
- controllo di un motore passo-passo bipolare con la corretta sequenza.
Il L298N è adatto a motori DC con spazzole e ad alcuni motori passo-passo bipolari. Non è il driver corretto per motori brushless trifase.
Problemi comuni
I motori non si muovono
Controlla l'alimentazione esterna, il GND comune e i collegamenti ENA/ENB. Se hai rimosso i jumper enable, Arduino deve generare un valore PWM maggiore di zero.
Un motore gira al contrario
Inverti i due fili del motore oppure scambia HIGH e LOW nella funzione relativa a quel canale.
Arduino si riavvia quando parte il motore
La sorgente potrebbe non fornire abbastanza corrente oppure i disturbi dei motori possono raggiungere la logica. Separa correttamente le alimentazioni, mantieni il GND comune e usa cablaggi corti e robusti.
Il motore è molto più lento del previsto
Considera la caduta di tensione del L298N, la carica della batteria e la corrente richiesta dal motore. Verifica anche che analogWrite() non stia usando un valore troppo basso.
Il modulo diventa molto caldo
Il motore potrebbe richiedere troppa corrente o essere bloccato. Spegni il circuito, misura la corrente di stallo e valuta un driver più efficiente se il carico è elevato.