Motore Stepper Bipolare con Arduino e A4988

Il motore stepper (o passo-passo) è un particolare motore elettrico sincrono senza spazzole (brushless) che funziona in corrente continua. La posizione di un motore stepper può essere controllato in modo molto precisa senza l’utilizzo di particolari circuiti per un controllo ad anello chiuso e quindi senza l’utilizzo di sensori come encoder per il rilevamento della posizione dell’albero motore, questo rappresenta uno dei principali vantaggi di questo motore. Grazie al controllo del posizionamento molto preciso aggiunto alla possibilità di funzionare a velocità precisa e costante, il motore stepper viene utilizzato in tutte quelle applicazioni che necessitano un controllo stabile e preciso del movimento e quindi della posizione, un esempio comune è quello delle stampante 3D, ma spesso anche nella robotica, in specifiche applicazioni, viene preferito al motore brushless. 

Motore Stepper Bipolare

Così come altri tipi di motori, il motore stepper è formato da uno statore che è la parte esterna fissa formata da diversi avvolgimenti di rame, e da un rotore che è la parte rotante interna formata normalmente da magneti permanenti.
La rotazione angolare dell’albero avviene tramite una precisa sequenza di impulsi di corrente che fanno spostare a scatti (passo) il rotore in un senso, per questo motivo il nome “stepper”. Lo scopo principale di un motore stepper è quello di mantenere fermo in equilibrio l’albero del motore, infatti alimentando il motore, questo si limiterà a bloccare l’albero in un precisa posizione e la posizione desiderata può essere poi raggiunta tramite appunto una serie di impulsi.

In questo articolo non spiegherò il principio di funzionamento di un motore stepper in quanto sul web già esiste molta documentazione ma mi limiterò solo a mostrarti un’applicazione pratica, in ogni caso ti consiglio la lettura dell’articolo di Michele Maffucci.

Esistono diversi tipi di motore stepper che si differiscono in base alla loro costruzione, in questo articolo tratterò solo il motore stepper bipolare con magneti permanenti (4 cavi).
Normalmente una rotazione dell’albero di 360° di un motore stepper bipolare è divisa in 200 passi, quindi ogni passo può avere una precisione angolare di 1,8°, può sembrare bassa come risoluzione ma in realtà con specifici driver è possibile aumentare la risoluzione senza l’utilizzo di riduttori meccanici.

Riepilogando, i principali vantaggi di questo motore sono:

  • Posizionamento molto preciso senza l’utilizzo di sensori di posizione.
  • Velocità di rotazione molto bassa senza l’utilizzo di riduttori meccanici.
  • Alta stabilità sulla posizione a rotore bloccato.
  • Momento di inerzia molto basso.
  • Privo di spazzole quindi meno soggetto ad usura meccanica.
  • Può avere un costo molto basso a parità di prestazioni con altri tipi di motore.

Però non è tutto rose e fiori, i motori stepper purtroppo hanno anche degli svantaggi come:

  • Forti vibrazioni durante la rotazione.
  • Velocità massima di rotazione di circa 1500 rpm. Esistono motori che possono raggiungere anche 5000 rpm tramite sistemi di retroazione ad anello chiuso ma a discapito della coppia.
  • Molto calore prodotto già dopo pochi minuti di funzionamento.
  • Necessitano di circuiti elettronici per il pilotaggio.

La maggior parte dei motori stepper bipolari vengono prodotti con dimensioni delle flange definiti dallo standard NEMA. Quelli più diffusi sono i NEMA17 con dimensione di flangia di 42x42mm, NEMA23 (57x57mm), NEMA34 (86x86mm) e NEMA42 (108x108mm), ma esistono anche altre dimensioni. Ciò che può cambiare tra due motori con potenza diversa ma stessa dimensione della flangia è la lunghezza che appunto dipende dalla potenza del motore. 
Per questo articolo utilizzerò un motore stepper bipolare NEMA17, il classico motore utilizzato nelle stampanti 3D.

Il pilotaggio di un motore stepper con una board Arduino è molto semplice e non si ha bisogno di algoritmi particolari grazie anche all’utilizzo di chip driver per motori stepper.
Un motore stepper bipolare a 4 cavi può essere comandato anche con due ponti ad H, ma visto che a me piace fare le cose in modo preciso, semplice e veloce, in questo articolo mi limito ad utilizzare il driver A4988 di Allegro Microsystem. Fortunatamente per la prototipazione esistono in commercio delle breakout board molto compatte ed economiche di questo driver, come questa.

Di seguito riporto alcuni prodotti in vendita su Amazon:

Schema

Di seguito riporto lo schema elettrico di una breakout board.

Collegamenti

Il collegamento del driver A4988 è molto semplice, il driver ha diversi pin come illustrato nell’immagine successiva, i pin STEP e DIR sono due input (del driver) e vengono utilizzati per pilotare il motore stepper. Il pin DIR serve ad indicare il verso di rotazione (orario/antiorario), mentre il pin STEP viene utilizzato per far avanzare il motore di uno scatto di rotazione (un passo). Ogni impulso di tensione trasmesso al pin STEP corrisponderà ad un passo. Quindi per esempio se si vuole far effettuare una rotazione dell’albero motore di 360° bisognerà inviare 200 impulsi al pin STEP. La velocità di rotazione dipenderà dall’intervallo temporale tra un’impulso e il successivo.

Il driver A4988 possiede anche altri input come ENABLE, RESET e SLEEP, che servono rispettivamente per abilitare il driver, resettarlo e metterlo in sleep mode (risparmio energetico). 

Inoltre i pin MS1, MS2 e MS3 vengono utilizzati per aumentare la risoluzione del passo, seguendo lo schema seguente:

MS1MS2MS3Microstep Resolution
LowLowLow1
HighLowLow1/2
LowHighLow1/4
HighHighLow1/8
HighHighHigh1/16

Quindi portandoli tutte e 3 alti, si può pilotare il motore con un passo di 1/16, chiamati microsteps. Questo vuol dire che un singolo passo non avrà più una risoluzione di 1,8° bensì di 0,1125°.

Tengo a precisare che il driver può essere alimentato con una tensione da 3.0V a 5.5V tramite i pin VDD e GND. Mentre i pin VMOT e GND (quelli in alto a destra dall’immagine) servono per l’alimentazione del solo motore stepper, infatti supporta tensioni da 8.0V a 35V. Il picco di corrente per ogni avvolgimento è di 2A ma se si vuole raggiungere questa corrente (cioè 4A in totale) occorrerà dissipare il calore prodotto dal driver A4988 con un dissipatore metallico per evitare di romperlo. In ogni caso la corrente di erogazione può essere controllata tramite il piccolo potenziometro. Attento a non esagerare con la corrente che si rischia di bruciare gli avvolgimenti del motore. Sulla pagina di Pololu del suo prodotto viene descritto in dettaglio come settare la giusta corrente.

Per i miei esperimenti ho utilizzato una scheda Arduino Zero (SAMD21G18A) ma i collegamenti sono i medesimi anche con un Arduino UNO o simile, la cosa importante è rispettare la tensione di alimentazione. Come motore invece ho utilizzato un 17HS13-0404S.

NEMA17 17HS13-0404S

Di seguito una tabella con i relativi collegamenti tra breakout A4988 e Arduino:

A4988Arduino
DIR8
STEP9
VDD3.3V (Zero) o 5V (UNO)
GNDGND
MS110
MS211
MS312
VMOT12V (Alimentazione motore)
GNDGND (Alimentazione motore)
RESETSLEEP (A4988)
SLEEPRESET (A4988)

Di seguito la tabella con i collegamenti tra A4988 e il Motore.

A4988Stepper Motor
2BBlack
2AGreen
1ABlue
1BRed

I colori dei cavi dipendo dal motore, quindi ti consiglio di consultare la scheda tecnica del tuo motore prima di effettuare i collegamenti.

Sketch

Lo sketch seguente per Arduino utilizza la libreria AccelStepper, quindi prima di provarlo bisogna installare la libreria.

#include <AccelStepper.h>

#define MS01  1
#define MS02  2
#define MS04  4
#define MS08  8
#define MS16  16

// Define microstep value
#define MICROSTEPS 16

// Define pin connections
const int dirPin = 8;
const int stepPin = 9;
const int ms1Pin = 10;
const int ms2Pin = 11;
const int ms3Pin = 12;

// Define motor interface type
#define motorInterfaceType 1

// Creates an instance
AccelStepper myStepper(motorInterfaceType, stepPin, dirPin);

void setMicroSteps(int MS) {
  switch (MS) {
    case MS01:
      digitalWrite(ms1Pin, LOW);
      digitalWrite(ms2Pin, LOW);
      digitalWrite(ms3Pin, LOW);
      break;

    case MS02:
      digitalWrite(ms1Pin, HIGH);
      digitalWrite(ms2Pin, LOW);
      digitalWrite(ms3Pin, LOW);
      break;

    case MS04:
      digitalWrite(ms1Pin, LOW);
      digitalWrite(ms2Pin, HIGH);
      digitalWrite(ms3Pin, LOW);
      break;

    case MS08:
      digitalWrite(ms1Pin, HIGH);
      digitalWrite(ms2Pin, HIGH);
      digitalWrite(ms3Pin, LOW);
      break;

    case MS16:
      digitalWrite(ms1Pin, HIGH);
      digitalWrite(ms2Pin, HIGH);
      digitalWrite(ms3Pin, HIGH);
      break;

    default:
      digitalWrite(ms1Pin, LOW);
      digitalWrite(ms2Pin, LOW);
      digitalWrite(ms3Pin, LOW);
      break;
  }
}

void setup() {
  // initial microstep pin
  pinMode(ms1Pin, OUTPUT);
  pinMode(ms2Pin, OUTPUT);
  pinMode(ms3Pin, OUTPUT);

  setMicroSteps(MICROSTEPS);

  // set the maximum speed, acceleration factor,
  // initial speed and the target position
  myStepper.setMaxSpeed(1000 * MICROSTEPS);
  myStepper.setAcceleration(200 * MICROSTEPS);
  myStepper.setSpeed(200 * MICROSTEPS);
  myStepper.moveTo(800 * MICROSTEPS);
}

void loop() {
  // Change direction once the motor reaches target position
  if (myStepper.distanceToGo() == 0)
    myStepper.moveTo(-myStepper.currentPosition());

  // Move the motor one step
  myStepper.run();
}

Se i collegamenti sono corretti, dopo aver caricato lo sketch sulla scheda Arduino, il motore inizierà a ruotare in un senso, fino a raggiungere la posizione desiderata, per poi ruotare nell’altro senso. E’ possibile impostare la velocità e l’accelerazione con i metodi setSpeed() e setAcceleration(), passandogli il valore rispettivamente in steps/sec e steps/sec2. Inoltre con il metodo moveTo() si setta il valore di destinazione in steps, per esempio, se viene impostato un valore di 200 steps, il motore farà una rotazione di 360°. Per concludere, ricordati di richiamare nel loop() sempre il metodo run() altrimenti il motore non ruoterà.

La libreria citata prima include diversi esempi che ti consiglio di analizzare e provare. Per qualsiasi problema non esitare a lasciare un commento. Grazie per la lettura! 😀