Arduino Forum

Using Arduino => Motors, Mechanics, Power and CNC => Topic started by: Robin2 on Nov 08, 2014, 01:54 pm

Title: Simple Stepper Program
Post by: Robin2 on Nov 08, 2014, 01:54 pm
I wrote a very simple program to demonstrate stepper control using a Polulu A4988 stepper driver. It should also work with any stepper driver that just needs step and direction signals from an Arduino.

I have included it in response to several queries and it seemed it would be easier to create this Thread and then just add a link to it.

Edit 10 Dec 2014  - readers may also be interested in this note about Stepper Motor Basics (http://forum.arduino.cc/index.php?topic=284828)

If all you want to do is demonstrate that a motor can work this code is ideal.
Edit 23 Jul 2016 - increased millisBetweenSteps to 250 for slower running

Code: [Select]
// testing a stepper motor with a Pololu A4988 driver board or equivalent
// on an Uno the onboard led will flash with each step
// this version uses delay() to manage timing

byte directionPin = 9;
byte stepPin = 8;
int numberOfSteps = 100;
byte ledPin = 13;
int pulseWidthMicros = 20;  // microseconds
int millisbetweenSteps = 250; // milliseconds - or try 1000 for slower steps


void setup() {

  Serial.begin(9600);
  Serial.println("Starting StepperTest");
  digitalWrite(ledPin, LOW);
  
  delay(2000);

  pinMode(directionPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  
 
  digitalWrite(directionPin, HIGH);
  for(int n = 0; n < numberOfSteps; n++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(pulseWidthMicros); // this line is probably unnecessary
    digitalWrite(stepPin, LOW);
    
    delay(millisbetweenSteps);
    
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
  
  delay(3000);
  

  digitalWrite(directionPin, LOW);
  for(int n = 0; n < numberOfSteps; n++) {
    digitalWrite(stepPin, HIGH);
    // delayMicroseconds(pulseWidthMicros); // probably not needed
    digitalWrite(stepPin, LOW);
    
    delay(millisbetweenSteps);
    
    digitalWrite(ledPin, !digitalRead(ledPin));
  }
}

void loop() {
}


More recently there has been a request for a more complete example using buttons to control a stepper motor and I have now created a new version which also uses millis() rather than delay() for timing. Following is the code for this version

EDIT (13 Nov 2014) to correct serious error. Humble apologies. Instead of 2 separate programs I had accidentally repeated the first program. The correct second program is now here

Code: [Select]

// testing a stepper motor with a Pololu A4988 driver board or equivalent

// this version uses millis() to manage timing rather than delay()
// and the movement is determined by a pair of momentary push switches
// press one and it turns CW, press the other and it turns CCW

byte directionPin = 9;
byte stepPin = 8;

byte buttonCWpin = 10;
byte buttonCCWpin = 11;

boolean buttonCWpressed = false;
boolean buttonCCWpressed = false;

byte ledPin = 13;

unsigned long curMillis;
unsigned long prevStepMillis = 0;
unsigned long millisBetweenSteps = 25; // milliseconds

void setup() {

     Serial.begin(9600);
     Serial.println("Starting Stepper Demo with millis()");

     pinMode(directionPin, OUTPUT);
     pinMode(stepPin, OUTPUT);
     pinMode(ledPin, OUTPUT);
     
     pinMode(buttonCWpin, INPUT_PULLUP);
     pinMode(buttonCCWpin, INPUT_PULLUP);
     
}

void loop() {
   
    curMillis = millis();
    readButtons();
    actOnButtons();
   
}

void readButtons() {
   
    buttonCCWpressed = false;
    buttonCWpressed = false;
   
    if (digitalRead(buttonCWpin) == LOW) {
        buttonCWpressed = true;
    }
    if (digitalRead(buttonCCWpin) == LOW) {
        buttonCCWpressed = true;
    }
}

void actOnButtons() {
    if (buttonCWpressed == true) {
        digitalWrite(directionPin, LOW);
        singleStep();
    }
    if (buttonCCWpressed == true) {
        digitalWrite(directionPin, HIGH);
        singleStep();
    }
}

void singleStep() {
    if (curMillis - prevStepMillis >= millisBetweenSteps) {
            // next 2 lines changed 28 Nov 2018
        //prevStepMillis += millisBetweenSteps;
        prevStepMillis = curMillis;
        digitalWrite(stepPin, HIGH);
        digitalWrite(stepPin, LOW);
    }
}



...R
EDIT 28 Nov 2018. I changed to using prevStepMillis = curMIllis; because with the other method the time could get out of sync if there was a long interval with no button pressed.
Title: Re: Simple Stepper Program
Post by: Cactusface on Nov 10, 2014, 09:24 pm
Hi Robin2,
                But why is the whole program in the SETUP loop??  I did some work with steppers years ago using the old Philips SAA1027 (I think), way before Arduinos and the like. But I have just ordered a couple of cheap Chinese A4899 modules (about £3 the pair) so will be playing with them again soon (3 weeks from China), and will give your code a try, I have a few old steppers from printers, etc.

I would like a robot that goes where you tell it, and not just somewhere near!

Regards


Mel.
Title: Re: Simple Stepper Program
Post by: Robin2 on Nov 10, 2014, 10:40 pm
But why is the whole program in the SETUP loop??
It is just a very basic test program to prove that the motor works. Move it one way. Move it the other way. Stop.

The second program is more typical of normal use.

...R
Title: Re: Simple Stepper Program
Post by: daniellyall on Nov 11, 2014, 12:00 am
very nice and simple will be very good for testing all the stepper I have laying around
Title: Re: Simple Stepper Program
Post by: richblus on Nov 26, 2014, 11:53 pm
Thanks for posting! I'm waiting for components but excited to try this!
Title: Re: Simple Stepper Program
Post by: dptdpt on Nov 30, 2014, 04:08 pm
I do have another question. Robin - how did you come up with the 20 microsecond second pulse duration and 25 milliseconds between pulses?  Can it be done any faster?  One of my steppers has 100 steps, so it would be good if I could step it more quickly.
Title: Re: Simple Stepper Program
Post by: Robin2 on Nov 30, 2014, 09:13 pm
I do have another question. Robin - how did you come up with the 20 microsecond second pulse duration and 25 milliseconds between pulses?  Can it be done any faster?  One of my steppers has 100 steps, so it would be good if I could step it more quickly.
This a THIRD thread where you have asked questions about your project (http://forum.arduino.cc/index.php?topic=278528.msg1981388#msg1981388). Why not keep all your own info and questions in one place?

The 20 microseconds is not really needed - most stepper drivers just need a pulse of a few microseconds and there is enough delay within the digitalWrite() function for that. Initially I tried it at 20 usecs just being cautious.

The 25 millisecs is just trial and error. Experiment with any values you like - but only AFTER you have it working with 25 msecs. Stepper motors will generally work at higher speeds if they are supplied with higher voltages.

...R
Title: Re: Simple Stepper Program
Post by: dptdpt on Nov 30, 2014, 10:27 pm
Sorry Robin!  I thought about putting my question in my other thread, but thought it might be of interest to anyone who used your program. I'd be happy to delete it if you disagree. On most forums, people prefer for you to break up questions into different topics/threads based on relevance.  It makes the forum more useful as a knowledgebase if threads stick to a single topic as much as possible.  It would make it a lot easier for me, though, if I just put everything in a single "me" thread! 
Title: Re: Simple Stepper Program
Post by: Robin2 on Nov 30, 2014, 11:18 pm
Leave things where they are now, but for the future I suggest you keep things in your main Thread.

I appreciate your consideration of other Forum users, but it does make it difficult to help you because somebody trying to answer a question in one Thread may not be aware that relevant background info is already in another Thread. You can easily include links in your Thread if you want to cross-reference other Threads.

...R
Title: Re: Simple Stepper Program
Post by: marco1990 on Feb 10, 2015, 11:23 am
Hi Robin,
I am a student and I am doing a part of the final project of master thesis. I have Arduino UNO, stepper motor Skidproof Nema17, and stepper motor driver A4988. I tried to run my motor and it is ok. Now I want to change and vary the speed. I know that the speed is linked with the frequency of the pulse signal. Can you give some advice on how to do? Need I others components in addition to the ones I have?
Thank you so much for your availabilty

Marco
Title: Re: Simple Stepper Program
Post by: Robin2 on Feb 10, 2015, 11:48 am
Now I want to change and vary the speed.
Just change the value of   millisBetweenSteps    in my demo programs

You may also be interested in stepper motor basics (http://forum.arduino.cc/index.php?topic=284828.0)

...R
Title: Re: Simple Stepper Program
Post by: daxasd on Jul 09, 2015, 02:45 pm
@Robin2

Thank you for this useful thread.
Let me know, Can we use the code with driver CWD556 and stepper motor 57HS22 ?
Title: Re: Simple Stepper Program
Post by: daxasd on Jul 09, 2015, 03:15 pm
Could you explain to me please why we use always pulse HIGH then delay and then LOW
and what if we use just HIGH
and what is the difference between the first delay and the second delay?

Code: [Select]


digitalWrite(stepPin, HIGH);

delayMicroseconds(pulseWidthMicros);

digitalWrite(stepPin, LOW);
   
delay(millisbetweenSteps);


Title: Re: Simple Stepper Program
Post by: Cactusface on Jul 09, 2015, 04:30 pm
Hi daxasd,
                 Pluse HIGH on it's own will do nothing, it's the LOW to HIGH transition that steps the motor. The time between this, controls how fast the motor moves.

Regards

Mel.
Title: Re: Simple Stepper Program
Post by: Robin2 on Jul 09, 2015, 05:33 pm
it's the LOW to HIGH transition that steps the motor. The time between this, controls how fast the motor moves.
This may be a little confusing.

It is the time between successive pulses that controls the speed.

In the example code in Reply #12 the short delayMicroseconds(pulseWidthMicros); determines the width of the HIGH pulse. With many stepper drivers this line can be omitted because the digitalWrite() is slow enough to produce a satisfactory pulse.

The delay(millisBetweenSteps); determines the speed of the motor by setting the number of milliseconds between successinge step pulses.

I'm nearly sure I answered a similar question involving a "driver CWD556 and stepper motor 57HS22" yesterday or the day before.

...R

Title: Re: Simple Stepper Program
Post by: daxasd on Jul 09, 2015, 08:35 pm
thanks guys for reply

then what is the difference between using this high and low pulses and using the
Stepper.h library

for example

Code: [Select]


#include <Stepper.h>
Stepper myStepper(StepsPerRevolution, 8,9,10,11);
Stepper myStepper(StepsPerRevolution, 9,10);
setSpeed(rpms);
step(steps);



also I have seen AccelStepper.h library is it useful?

thanks
Title: Re: Simple Stepper Program
Post by: Robin2 on Jul 09, 2015, 09:46 pm
They are just 3 different ways of doing much the same thing. Ultimately the libraries have to do what my code does. They just wrap it up in fancy clothes.

The libraries do have a value if you are using a h-bridge to drive a stepper because they take care of the complex series of pulses. But it is much more sensible IMHO to leave that task to a specialized stepper driver and take the load off the Arduino.

As its name implies the AccelStepper library is intended to apply acceleration and deceleration to the motor. If you don't need acceleration and if you have a specilized stepper driver it does not really offer much value IMHO.

...R
Title: Re: Simple Stepper Program
Post by: daxasd on Jul 10, 2015, 11:11 am
@Robin2

Thank a lot

then in the case of the stepper.h library is it convenient to use these functions when we use a specialized stepper driver that adjust the pulses and the microsteps manually
or using direct pulses without any library is better in this case.
Title: Re: Simple Stepper Program
Post by: Robin2 on Jul 10, 2015, 05:55 pm
then in the case of the stepper.h library is it convenient to use these functions when we use a specialized stepper driver that adjust the pulses and the microsteps manually
or using direct pulses without any library is better in this case.
Your question is a bit confusing - especially the bit I have highlighed

And what do you mean by "these functions" ?

I have never used the Stepper library and I am not sure whether it is suitable for controlling a specialized stepper driver. I think the options are DIY or the AccelStepper library.

...R
Title: Re: Simple Stepper Program
Post by: segg3060 on Jul 10, 2015, 09:55 pm
Be carefull to set the amps on the A4988 as we burned up 3 of them befor we caught on
Title: Re: Simple Stepper Program
Post by: MaxDan on Jan 10, 2016, 04:19 am
Hello,

Anyone have a pic for the wiring on this code for Old Burt Brains?

First Project new job.

Thank you,

Dan
Title: Re: Simple Stepper Program
Post by: MaxDan on Jan 10, 2016, 04:50 am
Hello,

Anyone have a pic for the wiring on this code for Old Burt Brains?

First Project new job.

Thank you,

Dan
Title: Re: Simple Stepper Program
Post by: Robin2 on Jan 10, 2016, 11:04 am
The Pololu web pages for their A4988 and DRV8825 stepper driver boards have good wiring diagrams - and lots of other useful info.

If you need more specific advice about your own project please start your own Thread so that your details do not distract readers of my little Tutorial.

...R
Title: Re: Simple Stepper Program
Post by: paul_larner on Aug 19, 2016, 12:05 am
will this work with an arduino and the addafruit motor shield?
Title: Re: Simple Stepper Program
Post by: Robin2 on Aug 19, 2016, 09:27 am
will this work with an arduino and the addafruit motor shield?
AFAIK the Adafruit motor shield has a simple h-bridge motor driver (rather than a specialized stepper driver) and if I am correct the answer is NO.

It is important to read this Thread in the context of Stepper Motor Basics (http://forum.arduino.cc/index.php?topic=284828.0)


...R
Title: Re: Simple Stepper Program
Post by: paul_larner on Aug 20, 2016, 07:34 am
Is there any chance you could write the code to make this work with the addafruit motor shield?,im sure a lot more people would find that usefull!,cheers Paul.
Title: Re: Simple Stepper Program
Post by: Robin2 on Aug 20, 2016, 10:26 am
Is there any chance you could write the code to make this work with the addafruit motor shield?,im sure a lot more people would find that usefull!,cheers Paul.
Sorry. None.

I don't consider that shield to be a suitable device for controlling stepper motors. Did you not read Stepper Motor Basics (http://forum.arduino.cc/index.php?topic=284828.0)

Feel free to write your own code but please don't add it to this Tutorial Thread.

...R
Title: Re: Simple Stepper Program
Post by: paul_larner on Aug 20, 2016, 03:20 pm
if its not a suitable device,why is it sold as such?,it works and delivers enough umpf for my needs,sounds like an excuse to me!
Title: Re: Simple Stepper Program
Post by: rpt007 on Aug 20, 2016, 06:06 pm
Try to dig a bit deeper into the stuff and you might understand why @Robin2 denied to modify/ extend the code.
It has nothing to do with the popularity of the shield.

Go with a "normal" bipolar stepper and the popular A4988 or DRV8825 and you will be happy.
Title: Re: Simple Stepper Program
Post by: Robin2 on Aug 20, 2016, 07:09 pm
if its not a suitable device,why is it sold as such?,
You need to address that question to the people who sell it. I have nothing to do with the sale or marketing of any Arduino related products.

...R