# Allegro A4988 and Arduino (3)

In the last part of myÂ tutorialÂ about the A4988 driver, I’m going to explain how to build a controller to adjust speed and rotation direction of a stepper motor.

#### Schematics

I used the same setup introduced in aÂ previous post:

• an Arduino Uno;
• a LCD Keypad shield;
• a Pololu A4988 driver mounted on a breadboard;
• a NEMA17Â stepper motor.

#### GUI

Using the controller, you can adjust the speed (from 0 to 70 RPM, revolutions per minute) and the rotation direction.

On the LCD are displayed the actual speed, direction and a progress bar:

The 5 available buttons are used to control the motor:

• UP andÂ DOWNÂ adjust the speed;
• LEFT andÂ RIGHTÂ adjust the direction;
• SELECTÂ activates the emergency stop (speed = 0).

#### Continuous rotation

To achieve a continuous rotation, yourÂ sketchÂ must send the step commands to the Pololu driverÂ at constant frequency.

Let’s see an example: for a speed of 60RPM and for a motor with 200 steps / revolution, Arduino must send to the driver (60*200)/60 =Â 200 commands / secÂ or a command everyÂ 5ms.

To ensure an accurateÂ timing, I’m going to use the interrupts generated by theÂ Timer1Â as explained inÂ this article.

From theÂ PlaygroundÂ you can download a convenient libraryÂ to configure that Timer:

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

With the instructions above, you configure the Timer1 to trigger an interrupt everyÂ 100 millisecondi (0.1ms) and to invoke, at each interrupt, theÂ timerIsr() function.

The “temporal distance” between a step command and the next one depends on the current speed (in the example above for a speed of 60RPM the distance is 5ms). Given that the possible speeds are only 15 (from 0 to 70RPM with a 5RPM increment), I calculated that distance (in ticksÂ of 0.1ms) for the different speeds and stored the values in anÂ array:

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

Within the timerIsr() function a counter is incremented and – if it has reached the ticks for the current speed – a step command is sent to the 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; } }```

In the next page, I’ll explain the rest of the sketch and show an example of its working…

#### Related Posts

Tuesday August 20th, 2013 - 07:42 AM

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.

Monday August 26th, 2013 - 05:15 AM

37 int previous_time;

change to
37 unsigned long previous_time;

Sunday November 17th, 2013 - 09:33 AM

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 ..?!

Sunday November 17th, 2013 - 10:38 AM

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

Sunday December 15th, 2013 - 03:24 PM

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

Monday December 16th, 2013 - 02:14 PM

Ciao Paolo,

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

Thursday January 9th, 2014 - 07:14 PM

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.

Tuesday January 14th, 2014 - 06:51 PM

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Ã ?

Wednesday January 15th, 2014 - 09:24 AM

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

Monday January 27th, 2014 - 10:05 PM

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?

Monday March 3rd, 2014 - 08:04 PM

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

Friday April 25th, 2014 - 05:16 PM

This code… is beautiful! You have no idea how useful this was (as I have many steppers and A4988’s lying around from various Repraps!)

Thank you very much for posting a very concise and understandable set of tutorials!

ðŸ˜€

Thursday July 10th, 2014 - 08:41 AM

Buongiorno Luca

Ho provato il tuo tutorial, ma il motore invece che girare effettua un passo avanti e uno indietro rimanendo sempre nella stessa posizione. Vorrei capire se e’ il motore che e’ rotto o la pcb della Pololu.

grazie mille

saluti

Monday July 14th, 2014 - 03:24 PM

ciao Luca

Ã¨ possibile che sia collegato sbagliato al driver? uno step avanti e uno indietro sembra indicare che gli avvolgimenti del motore non sono collegati bene…

Wednesday January 21st, 2015 - 01:13 PM

Hi Luca!
Greetings from Berlin ðŸ™‚

I was very glad to have seen your project, very great! I use it for my automatic Camera Slider
I have downloaded and install the sketsch, it works but only in one direction. What’s wrong with it?

lg. Alex

Wednesday January 21st, 2015 - 08:03 PM

Hi Alex,

the “arrow” on the LCD changes its direction? Check the connection between PIN3 of Arduino and the DIR pin of the stepper driver…

Thursday January 22nd, 2015 - 12:30 AM

ciao luca!
volevo chiederti riusciresti a fare una variante del firmware dove e possibile usare un lcd 16×2 con convertitore ic2 ? ho chiedo troppo saluti antony attendo risposta !

Saturday January 24th, 2015 - 03:54 PM

wow ðŸ™‚

you are right, the pin has bad contact
now it moves in all directions

one question…
at 70 RPM is the motor rotation to slow for my slider, how can i more speedup the turns of the motor?

i have already experiment..
at higher speed i canÂ´t change the direction the motor stops and hums

Saturday January 31st, 2015 - 10:11 AM

Hi Alex! what did you change in the sketch to add higher speeds?

Tuesday February 3rd, 2015 - 12:10 PM

i have change folowing lines:

// debounce time (milliseconds)
#define DEBOUNCE_TIME 70

// lookup table speed – ticks (interrupts)
const int speed_ticks[] = {-1, 4000, 300, 200, 100, 80, 70, 60, 65, 60, 50, 48, 35, 25, 20};
(4000 is for the timelapse operation)

int unsigned long previous_time;

// init the timer1, interrupt every 0.1ms
Timer1.initialize(23);
Timer1.attachInterrupt(timerIsr);

when i change the timer1 value to higher the motor freaks out at higher speeds/turns.. can it be, that the motordriver is not fast enough?

Wednesday February 4th, 2015 - 09:53 PM

Hi Alex: ticks is the number of “interrupts” between one step and the next one, so try reducing the last value and at the same time reduce also the Timer1.initialize() value

Saturday February 21st, 2015 - 06:13 PM

Hi, Luka!
Thank you very much for your project, everything works fine. I have only one question, how to make the rotation of the stepper motor (FL57STH76-1006 1.8*) faster and reduce vibration?
I changed the code and it helped a little:
// init the timer1, interrupt every 0.05 ms
Timer1.initialize(18);
Timer1.attachInterrupt(timerIsr);

Tuesday February 24th, 2015 - 09:06 PM

Hi Ruslan,

you can also decrease the values in the speed_ticks[] vector… for example if you configure Timer1 to trigger every 0.02ms (`Timer1.initialize(20)`) a speed_ticks[] value of 100 makes the motor rotate 1 step / 2ms that is (for a 200 steps/rev motor) a revolution every 0.4 seconds = 150RPM

Thursday February 26th, 2015 - 07:33 PM

Luca, many thanks!!!
I played around with “values in the speed_ticks[] vector” and reached the speed limit for my motor. Now I am happy ðŸ™‚
Originally, my project was based on this: http://www.minie.airiclenz.com/hardware-2/hardware/ . Now I have 2 codes for timelapse and for video footage.

Monday April 13th, 2015 - 09:28 PM

Ciao come posso adattare il tuo fantastico progetto alla mia motor shield r3 e keypad lcd? ho reso tutto impilabile e perfettamente compatibile facendo tagliando A0 etc etc.

Grazie del futuro supporto.

Monday April 13th, 2015 - 09:35 PM

Ciao Paolo, purtroppo la r3 non consente un controllo “facile” dei motori stepper rispetto al driver che ho usato io quindi penso (non ho la shield) che richieda diverse modifiche perchÃ© funzioni.

Monday April 13th, 2015 - 10:02 PM

Ok, ti ringrazio davvero molto per la tempestiva risposta! incredibile!

Grazie Molte.

Tuesday April 21st, 2015 - 12:22 PM
Monday September 7th, 2015 - 09:43 PM

Hello

I apologize for my English.

I have a problem with the functioning of Arduino.
I have Arduino UNO R3 + LCD Shield. After starting set the speed of 5 RPM for 1 minute Arduino error. Arduino freezes. What is wrong ?

Thanks Pidrman

Tuesday September 8th, 2015 - 07:22 AM

Hi! after exactly one minute or is the time random? Could be some noise coming from the motor…

Wednesday January 27th, 2016 - 09:13 PM

Luca,

I need your help.
I need to control a bipolar, 2 phase stepper.

I would like to use your setup which I find it brilliant…
But… I need really low RPM…..0.25 – 0.5 – 1 rpm…

Is this achievable with this project ?

Sunday January 31st, 2016 - 01:31 PM

Hi Florin, if you increase the delay between two interrupts (`Timer1.initialize(xxx)`) you can achieve lower RPMs

Friday June 3rd, 2016 - 10:37 AM

Ciao Luca! Bel lavoro.. io ho i tuoi stessi pezzi, LCD pololu etc.. mi spieghi i collegamenti? In particolare da dove prendi i segnali di uscita per il motore? Sono due?

Wednesday June 29th, 2016 - 05:48 PM

hey, might want to declare prev_time as unsigned long in arduino 1.

Friday July 7th, 2017 - 10:19 PM

Hi luke, very nice project,i am happy to found you. but i need your help my LCD keypad shield is freezes after several minutes and the engine can no longer control.
Could you tell me what is wrong?

Thanks

Saturday July 8th, 2017 - 09:30 AM

Hi, it’s very difficult to tell you what’s happening… it seems that Arduino freezes: does it happen at the same time? I mean every n minutes or is it random?

Saturday July 8th, 2017 - 02:52 PM

Its happen randomly, all key buttons didn’t work. except, restart button to make lcd keypad works again but when i pressed restart button,the lcd is flickering and stepper motor make strange motion

Thanks Luke

Thursday July 13th, 2017 - 08:46 PM

Ma che bravo! Mi sta tornando la voglia di rimettermi a giocare con Arduino

Wednesday August 23rd, 2017 - 06:09 PM

Ciao Luca,
complimenti per i tuoi tutorial!
Mi servirebbe arrivare intorno ai 1000rpm. E’ possibile con questo setup?
Grazie.

Thursday August 24th, 2017 - 08:50 AM

Ciao! 1000 rpm significa (motore da 200 passi / giro) un impulso del timer ogni 5uS… in teoria (se il motore lo supporta) si puÃ² fare modificando `Timer1.initialize(5);`

Thursday August 24th, 2017 - 10:14 AM

Ahh ho capito, grazie mille Luca. Ora devo capire se tiene il carico, senza scaldare troppo, per qualche ora di rotazione continua.

Monday September 4th, 2017 - 01:08 PM

Ciao Luca, complimenti per la guida. ti vorrei chiedere come dovrei comportarmi per creare sketch per muovere a piccoli passi un motore nema 17 fino a compiere un giro completo (e poi fermarsi)..ho giÃ  impostato i microstep a 1/16..mi servirebbe per test di fotogrammetria, quindi che si muovesse a piccoli step e una pausa lunga tra di essi. grazie in anticipo

Thursday September 7th, 2017 - 01:36 PM

grazie Federico, per fare quello che serve a te basta che scrivi uno sketch che fa compiere al motore il numero esatto di step che compongono un giro… se il motore Ã¨ da 220 step/giro e hai impostato un microstepping 1/16 significa fare uno sketch che esegue 3520 (220*16) “avanzamenti”.

Monday September 25th, 2017 - 03:47 PM

Ciao, intanto Complimenti, ottimo tutorial e grazie per la condivisione.
Volevo chiederti avrei esigenza di spazio e vorrei collegare questo lcd keybord ad arduino nano, devo per farlo comunque collegare tutti i pin?
Tipo come quando sovrapponi la scheda ad arduino uno ?
Oppure posso collegare solo alcuni pin ?
Se si, quali devo collegare?

Tuesday September 26th, 2017 - 08:52 AM

Ciao Angelo, ti rimando al sito ufficiale del produttore dello shield. In sintesi, “Pins 4, 5, 6, 7, 8, 9 and 10 are used to interface with the LCD. Just one Analog Pin 0 is used to read the five pushbuttons.” quindi almeno questi devi sicuramente collegarli.

Saturday March 24th, 2018 - 11:25 AM

sono alfeo dovrei fare una centralina per acquario che piloti pompa luce e ossigenatore la parte rele allo stato solido ce lo gia mi occorre la parte di programmazione un orologio con programmazione ora e giorno e accensione e spegnimento volevo un consiglio per il programma utilizzando arduino grazie

Sunday March 25th, 2018 - 09:43 AM

ciao Alfeo, la tua esigenza Ã¨ molto comune… se cerchi con google “arduino timer” o simili trovi centinaia di progetti pronti da utilizzare

Thursday January 24th, 2019 - 09:47 AM

Ciao Luca, anche io come altri utenti ho il problema che si freeza tutto e si puÃ² solo resettare arduino.
La cosa Ã¨ random e accade anche senza collegare driver e motore, ho provato a fare la stessa cosa anche usando lcd su i2c ma idem, funziona tutto, ma dopo pochi secondi si blocca tutto

Friday February 1st, 2019 - 02:37 PM

ciao! molto strano, ho appena riprovato lo sketch e va tranquillamente per decine di minuti…

Friday January 25th, 2019 - 08:44 PM

I am getting an error when compiling, can you please help?

redefinition of ‘void setup()’

Friday February 1st, 2019 - 02:37 PM

I’ve just tested my “cntrSpeedDir.ino” sketch and it compiles perfectly… did you download it from my github repo?

Friday February 22nd, 2019 - 07:27 PM

I had an extra bracket, sorry about that.

Im trying to get your sketch to work with a TB6600 driver controller but having 0 luck. It just keeps locking up regardless of what speed I run at. Not having any knowledge of Arduino programming or C+ this has been frustrating to say the least. Im hoping you may be able to point me in the right direction for obtaining information on the changes needed to make your sketch work with my hardware. Im sure you are really busy and if you dont have the time I completely understand. Im very grateful for the information and the sketch you have provided the public.

Hardware
Single Axis TB6600 0.2-5A CNC Two-phase hybrid Driver Controller Stepper Motor

Dual Shaft Nema 23 CNC Stepper Motor Bipolar 3Nm(425oz.in) 4.2A 57x114mm 4 Wires

30:1 Geared Speed Reducer Nema23 Planetary Gearbox

1602 Serial Blue Backlight LCD Display Keypad 4 Arduino Uno R3 Mega 2560 Shield

ARDUINO UNO R3

Thank You