Allegro A4988 e Arduino (3)

luca 30 maggio 2013 11

In questa ultima parte del tutorial relativo al driver A4988, vedremo come realizzare un controller per regolare velocità e direzione di rotazione di un motore stepper.

Circuito

Utilizzeremo lo stesso circuito del post precedente:

  • un Arduino Uno;
  • un LCD Keypad shield;
  • un driver Pololu A4988 montato su breadboard;
  • un motore stepper NEMA17.

GUI

Il nostro controller darà la possibilità di regolare la velocità (da 0 a 70 RPM, giri/minuto) e la direzione di rotazione.

Sul display LCD verranno visualizzati velocità e direzione corrente e una progress bar:

La regolazione avviene tramite i 5 pulsanti disponibili:

  • UPDOWN regolano la velocità;
  • LEFTRIGHT regolano la direzione;
  • SELECT attiva lo stop di emergenza (velocità = 0).

Rotazione continua

Per garantire una rotazione continua, lo sketch di Arduino dovrà inviare al driver Pololu i comandi di step ad una frequenza costante.

Vediamo un esempio: per una velocità di 60RPM e con un motore da 200 passi / giro, Arduino deve inviare al driver (60*200)/60 = 200 comandi / sec ovvero un comando ogni 5ms.

Per garantire un timing così preciso, utilizzo gli interrupt generati dal Timer1 di Arduino come spiegato in questo articolo.

Su Playground esiste una comoda libreria per configurare tale Timer:

#include 
[...]
Timer1.initialize(100);
Timer1.attachInterrupt(timerIsr);

Con queste istruzioni, si configura il Timer1 per generare un interrupt ogni 100 millisecondi (0.1ms) e per chiamare, ad ogni interrupt, la funzione timerIsr().

La distanza temporale tra un comando di step e il successivo dipende dalla velocità attuale (nell’esempio sopra per 60RPM tale distanza è di 5ms). Visto che le velocità possibili sono soltanto 15 (da 0 a 70RPM con passo 5RPM), ho calcolato tale distanza (in ticks di 0.1ms) per le varie velocità e l’ho inserita in un array:

const int speed_ticks[] = {
-1, 600, 300, 200, 150, 120, 100, 86, 75, 67, 60, 55, 50, 46, 43};

All’interno della funzione timerIsr() incremento un contatore e – se ho raggiunto il numero di ticks per la velocità impostata – invio un comando di step al driver:

void timerIsr() {
 
  if(actual_speed == 0) return;
 
  tick_count++;
 
  if(tick_count == ticks) {  
 
    // make a step
    digitalWrite(PIN_STEP, HIGH);
    digitalWrite(PIN_STEP, LOW);
 
    tick_count = 0;
  }
}

Nella prossima pagina vedremo il resto dello sketch e un esempio di funzionamento…

Pagine: 1 2

11 Comments »

  1. Nikolai 20 agosto 2013 at 07:42 - Reply

    Hi Luca!
    Thank you very much. But there is one big prolema, I have it hangs does not work, the engine is spinning and the buttons are not controlled.
    Do “reset” button is working again controlled, then again hanging is not controlled by buttons.
    Using the Arduino Uno, tried Arduino Mega 2560 also does not work.
    Please help solve the problem

  2. Nikolai 26 agosto 2013 at 05:15 - Reply

    37 int previous_time;

    change to
    37 unsigned long previous_time;

  3. berlon 17 novembre 2013 at 09:33 - Reply

    Hi !
    Can i use your scheme with EasyDriver 4.4 ?
    Example here http://bildr.org/2011/06/easydriver/

    I think that 3 inputs from arduino is the same ..?!

    • luca 17 novembre 2013 at 10:38 - Reply

      Hi, it should work because the EasyDriver has the same STEP/DIR interface as the controller I used.
      Let me know!

  4. Paolo 15 dicembre 2013 at 15:24 - Reply

    Caro Luca,
    Vorrei usare il tuo programma per collegare i seguenti componenti

    un Arduino Uno;
    un LCD Keypad shield;
    un driver Pololu DRV8825 montato su breadboard;
    un motore stepper NEMA 23

    Potresti darmi qualche suggerimento per i collegamenti?
    Grazie
    Paolo

    • luca 16 dicembre 2013 at 14:14 - Reply

      Ciao Paolo,

      sostanzialmente i collegamenti sono gli stessi del mio esempio perché il driver DRV8825 è pin compatibile con quello usato da me (chip A4988).

  5. Antonio 9 gennaio 2014 at 19:14 - Reply

    Salve Luca, in anzi tutto complimenti per i tutorial sono veramente interessanti e molto chiari.
    vorrei usare il tuo programma facendogli qualche modifica ma non ci riesco, potresti darmi una mano?
    Le modifiche sono le seguenti:
    1 dovrei pilotare in microsecondi anzi che in milisecondi
    2 sul display lcd anzi che visualizzare la velocità in RPM dovrei visualizzare il ritardo tra un passo e l’altro
    Spero che tu possa darmi una mano perché non ci riesco proprio.
    Grazie.

    • luca 14 gennaio 2014 at 18:51 - Reply

      Ciao Antonio

      partiamo dalla prima richiesta perché mi “preoccupa”… difficilmente riuscirai ad avere passi della durata di microsecondi a causa dell’inerzia e della corrente; volevi ottenere una elevata velocità?

  6. Antonio 15 gennaio 2014 at 09:24 - Reply

    Ciao Luca Grazie per avermi risposto, no non è per aumentare la velocità
    Ma per avere più scelta.
    Mi spiego meglio
    Sto usando
    Nema17 a 12v 1,2A 200 passi
    Arduino 2009
    Display lcd con tasti
    DRV8825
    Il tutto assemblato su una montatura equatoriale di un telescopico.
    Il motore deve far si che il telescopio compia un giro completo di 360 gradi in 24 ore sul asse AR, secondo la demoltiplica che ho usato per aumentare i giri e diminuire lo sforzo, il motore deve compiere un giro i circa 65 secondi e fin che vado a passi interi o a mezzi passi tutto ok ma se piloto a micropassi diciamo a 1/16 o 1/32 di passo con i millisecondi non riesco ad ottenere la rotazione nel tempo giusto.
    Praticamente dovrei impostare diverse velocità di rotazione aumentando di un secondo per ogni velocità e con i microsecondi dovrei riuscirci.
    Spero di essermi spiegato bene e grazie per la pazienza.
    Ciao

    • luca 27 gennaio 2014 at 22:05 - Reply

      Ciao Antonio

      un giro in 65 secondi vuol dire che devi fare 200 passi in 65 secondi. Se anche vai a 32 microsteps, si parla sempre di 6400 “impulsi” ogni 65 secondi quindi circa 100 impulsi al secondo = 10ms a impulso… come mai ti serve invece lavorare con interrupt più frequenti?

  7. Marco 3 marzo 2014 at 20:04 - Reply

    Ciao Luca,
    Per prima cosa vorrei farTi i complimenti per questo progetto che formidabile!
    Forse ho sbagliato qualche cosa perchè ho comprato tutti i componenti hardware da Te usati, ma il programma non mi funziona bene.
    Infatti all’inizio il motorino va che è una meraviglia, ma se dopo un pó che , per esempio va a 45 rpm , decido di cambiare la velocità o invertire il senso in cui il motorino gira , accade che la tastiera della LCD keypad shield si blocca ed il motore non si puó più controllare.
    Potresti dirmi cosa sbaglio?
    Grazie in anticipo
    Marco

Leave A Response »