Controllo di velocità e verso di un motore DC con Arduino

Per controllare un motore DC (funzionante in corrente continua) con Arduino, devi utilizzare il circuito integrato “Ponte H” (nel mio caso un L293NE della Texas Instruments).

Il ponte H può, invertendo la polarità dell’uscita a cui è collegato il motore, variarne il verso di rotazione.tab2

Il ponte H possiede 16 pin:

  • Pin 1 (1,2EN) attiva/disattiva il motore a seconda che sia HIGH o LOW
  • Pin 2 (1A) pin logico per il motore
  • Pin 3 (1Y) a cui viene collegato un terminale del motore
  • Pin 4-5 collegati a GND
  • Pin 6 (2Y) a cui viene collegato l’altro terminale del motore
  • Pin 8 (VCC2) alimentazione per il motore 9-15V
  • Pin 9-11 servono per controllare un altro motore
  • Pin 12-13 collegati a GND
  • Pin 14-15 non sono connessi (servono per controllare un altro motore)
  • Pin 16 (VCC1) é connesso a 5V

Nella tabella sottostante puoi vedere il comportamento del motore a seconda dei settaggi dei pin dell’integrato e lo schema del circuito.

tba1

Schema

schema_bb

Il primo pulsante serve ad accendere o spegnere il motore, il secondo cambia la direzione di rotazione, mentre il potenziometro aumenta o diminuisce la velocità di rotazione.

Sketch:

const int controlPin1 = 2;                    //costanti di riferimento
const int controlPin2 = 3;                    //ai pin
const int accendiMotore = 9;
const int pulsanteDirezione = 4;
const int pulsanteOnOff = 5;
const int potenziometro = A0;
 
int statoPulsanteOnOff;                       //variabili di stato
int statoPulsanteOnOffPrecedente;
int statoPulsanteDirezione;
int statoPulsanteDirezionePrecedente;
 
int motoreAttivo;
int velocitaMotore;
int direzioneMotore = 1;
 
void setup() {
  pinMode(pulsanteDirezione, INPUT);          //inizializzazione della modalità dei pin
  pinMode(pulsanteOnOff, INPUT);
  pinMode(controlPin1, OUTPUT);
  pinMode(controlPin2, OUTPUT);
  pinMode(pulsanteOnOff, OUTPUT);
                                              //imposto accendiMotore su LOW
  digitalWrite(accendiMotore, LOW);           //inizialmente il motore sarà spento
}
 
void loop() {
  statoPulsanteOnOff = digitalRead(pulsanteOnOff);
  delay(1);
  statoPulsanteDirezione = digitalRead(pulsanteDirezione);
  velocitaMotore = analogRead(potenziometro)/4;
  
  if (statoPulsanteOnOff != statoPulsanteOnOffPrecedente) {
    if (statoPulsanteOnOff == HIGH) {
      motoreAttivo =! motoreAttivo;
    }
  }
 
  if (statoPulsanteDirezione != statoPulsanteDirezionePrecedente) {
    if (statoPulsanteDirezione == HIGH) {
      direzioneMotore =! direzioneMotore;
    }
  }
 
  if (direzioneMotore == 1) {
    digitalWrite(controlPin1, HIGH);
    digitalWrite(controlPin2, LOW);
  }
  else {
    digitalWrite(controlPin1, LOW);
    digitalWrite(controlPin2, HIGH);
  }
 
  if (motoreAttivo == 1) {
    analogWrite(accendiMotore, velocitaMotore);
  }
  else {
    analogWrite(accendiMotore, 0);
  }

  statoPulsanteDirezionePrecedente = statoPulsanteDirezione;
  statoPulsanteOnOffPrecedente = statoPulsanteOnOff;
}

All’inizio ho definito le costanti e le variabili poi recuperate nel loop().

Nel setup() ho inizializzato i pin dei pulsanti in INPUT e quelli collegati al ponte H in OUTPUT.

Nel loop() associo dei valori a delle variabili, con digitalRead().

Alla variabile velocitaMotore viene associata la lettura analogica di potenziometro, che genera un numero che va da 0 a 1023. Siccome la funzione analogWrite() che verrà utilizzata più avanti (riga 55) vuole un numero compreso tra 0 e 255, il valore restituito da analogRead() è diviso per 4.

Sono poi presenti tre quattro if:

  • Se lo stato del pulsante di accensione del motore è diverso da quello precedente ed ha stato logico alto, lo stato logico del motore cambia (se prima era acceso ora è spento e viceversa)
  • Stesso ragionamento per il pulsante di cambio direzione
  • Se direzioneMotore corrisponde a 1, il primo pin di controllo ha stato logico alto, mentre il secondo ha stato logico basso. Altrimenti viceversa
  • Se il motore è attivo viene eseguita la funzione analogWrite() sul pin accendiMotore (9) ed associato il valore di velocitaMotore. In questo modo, grazie ad una modulazione in PWM, la velocità cambia

Infine associamo alle variabili in “-Precedente” le corrispondenti dell'”attuale” loop(). In questo modo nel successivo possono essere richiamate.

Video

Questo circuito è presente in un qualsiasi modellino di trenino elettrico in cui possiamo variare la velocità del treno e la sua direzione.

12 Risposte a “Controllo di velocità e verso di un motore DC con Arduino”

  1. Premetto che non sono un tecnico elettronico, e ricordo a mala pena qualcosa che ho studiato 35 anni fa all’istituto tecnico…
    Vorrei informazioni su come pilotare un motorino della Maxon a 48 V 10W, (eventualmente ho scheda tecnica…, provvisto di encoder per captare n di giri, controllandone la velocità anche in presenza di variazione di carico.
    Sono un autocostruttore (di un giradischi di un questo caso), e il motore deve trascinara un piatto piuttosto pesante deve quindi tenere la velocità costante a 33,33 giri/min ma in presenza di variazioni di carico (riscalamento dei cuscinetti, o attrito della testina sul disco) deve aumentare la coppia per riportare la velocità al giusto n di giri. anche in presenza di variazioni di alimentazione deve mantenere costante la velocità
    Si può fare con scheda Arduino e… qualcos’altro?
    Grazie della pazienza e gentilezza se può rispondere.
    Mauro Forlani – Vicenza

      1. Grazie 🙂
        Ma se usassi un motore più piccolo che ho recuperato da un vecchio giocattolo che si aggira sui 3-5volt?
        Non è la stessa cosa se lo alimento con la dovuta alimentazione?

  2. Ciao…. ho rifatto il questo schema pari pari e mi funziona tutto a parte il cambio di rotazione del motore, cioè quando premo il pulsante per il cambio di rotazione non mi cambia niente il motore continua a girare nel solito verso. secondo voi quale può essere il problema??

  3. si puo fare l’inversione del verso di rotazione senza ponte ma solo con il codice?

  4. Molto bello, ma se io invece di un motore DC vorrei comandate un motore passo passo, come cambierebbe lo schetch? Grazi

  5. Ciao
    Volevo chiederti se utilizzando un lm339 al posto del lm293 posso riuscire a pilotare un motore 36 v 250 w

  6. Ragazzi un aiuto.
    Sto montando il circuito ma vedo in figura che la massa è collegata nella breadbord dove dovrebbe esserci l’alimentazione, e il 5v collegato alla massa della breadboard. Come mai? è giusto come in figura?

I commenti sono chiusi.