Go Down

Topic: Simple Stepper Program (Read 157456 times) previous topic - next topic

Robin2

Nov 08, 2014, 01:54 pm Last Edit: Nov 28, 2018, 10:51 pm by Robin2
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

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.
Two or three hours spent thinking and reading documentation solves most programming problems.

Cactusface

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.
Open your mind! But not too far, your brains might fall out.
Also like Photography, model building and my 300+ Cacti and Succs.

Robin2

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
Two or three hours spent thinking and reading documentation solves most programming problems.

daniellyall

very nice and simple will be very good for testing all the stepper I have laying around

richblus

Thanks for posting! I'm waiting for components but excited to try this!

dptdpt

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.

Robin2

#6
Nov 30, 2014, 09:13 pm Last Edit: Nov 30, 2014, 09:15 pm by Robin2
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. 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
Two or three hours spent thinking and reading documentation solves most programming problems.

dptdpt

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! 

Robin2

#8
Nov 30, 2014, 11:18 pm Last Edit: Nov 30, 2014, 11:19 pm by Robin2
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
Two or three hours spent thinking and reading documentation solves most programming problems.

marco1990

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

Robin2

#10
Feb 10, 2015, 11:48 am Last Edit: Feb 10, 2015, 11:49 am by Robin2
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

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

daxasd

@Robin2

Thank you for this useful thread.
Let me know, Can we use the code with driver CWD556 and stepper motor 57HS22 ?

daxasd

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);



Cactusface

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.
Open your mind! But not too far, your brains might fall out.
Also like Photography, model building and my 300+ Cacti and Succs.

Robin2

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

Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up