Code for controlling Nema17 Stepper

Hi there!

I have hear an stepper motor nema17 (http://www.aliexpress.com/store/product/4-lead-Nema-17-stepper-motor-42BYGHM809-4200g-cm-59oz-in-1-68A-CE-ROHS-ISO/511874_562360153.html)

and Big Easy Driver (Version 1.2)

Well, I was experimenting with these codes (Easy Driver Examples)

but I have many problems. These codes does not work for me.

One big problem is that I can't get the opposite direction. I haven't seen my motor turns counterclockwise yet!

The whole project I want to achieve, is similar to the 5th example of the above page. With analogue value from a potentiometer for speed change, and pushbuttons to control start/stop, and direction.

Well my first query:

Should I use "Accelstepper" Library for something like this ? Is there any way to do it without the library?

2nd:
I was trying to do it without "Library" and I wrote this:

/*
  Trying to control the motor with pushbuttons.
 */
 
const int buttonPin = 2; // set my buttons in Arduino Board
const int buttonPin2 = 3;
const int buttonPin3 = 4;

const int stepperstep = 9; // set the motor wires to the arduino board
const int stepperdirection = 8;

int buttonState = 0; // set my buttons in 0 or LOW position.
int buttonState2 = 0;
int buttonState3 = 0;


void setup() {
  pinMode(buttonPin, INPUT); //set my Inputs and Outputs
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  
  pinMode(stepperstep, OUTPUT);
  pinMode(stepperdirection, OUTPUT);
  
  digitalWrite(stepperstep, LOW);  // Set the outputs from Arduino to BigEasyDriver to LOW.
  digitalWrite(stepperdirection, LOW);
}


void loop() {
  int sensorValue = analogRead(A0);
  int buttonState = digitalRead(buttonPin);
  int buttonState2 = digitalRead(buttonPin2);
  int buttonState3 = digitalRead(buttonPin3);
  
  
 if (buttonState == HIGH){
  digitalWrite(stepperstep, HIGH); //try to push the button and start the rotation of the motor
 }
 else{
   digitalWrite(stepperstep, LOW);
 }
 
  if (buttonState2 == HIGH){  // try to push the 2nd button and change the rotation of the motor
 digitalWrite(stepperdirection, HIGH);
  }
  else {
  digitalWrite(stepperdirection, LOW);
  }
          
}

Nothing Happens when I upload this in my Arduino!!!

As I have read in the manual of Big Easy Driver, the STEP and DIR pin of BigEasyDriver accepts HIGH and LOW values.

That's why I'm trying to set these values with pushbuttons.

So, Am I in the right path? Or I should look in different ways?

Well, maybe I'm extremely wrong but I am a newbie, so please be kind with me.

Thank you.

Is there any way to do it without the library?

Of course. But why? Someone has already gone to the trouble of figuring out how to control a stepper motor in a reasonable way. Why not use that?

Have you looked at the Stepper library? If not, why not?

Yes, Maybe you are right. I 'm asking to do it without the Accelstepper Library because it is very confusing to me.

Is the "stepper" Library should work with the BigEasyDriver?

Is the "stepper" Library should work with the BigEasyDriver?

Yes, and it is far simpler than AccelStepper.

Ha! ok! I will experiment with it.

But, is the "stepper" function can set the outputs of arduino to the "step" and "dir" inputs of BigEasyDriver?

Anyway, I will experiment and I will right again.

Thanks!

Have a look at stepper motor basics and this simple stepper code that does not use any library. If you have a BigEasydriver or equivalent the libraarires do not offer much benefit, unless you want to use the acceleration feature of the AccelStepper library.

...R

Hi again,

The Stepper Library has the function "Stepper".

The parametres are :

"pin1, pin2: two pins that are attached to the motor (int)

pin3, pin4: optional the last two pins attached to the motor, if it's connected to four pins (int)"

Are these pins reffered to the motor coil pairs?

If yes, how can i set my pins for the BigEasyDriver?

The 4 wires of motor are connected to the BigEasyDriver.
Then the 2 outputs of arduino is connected to BigEaseDriver Step and Dir.

How can I set the "step" and "direction" parametres for the BigEasyDriver from the Stepper function?

Sparkfun has a link to this on the Big Easy page:
http://bildr.org/2012/11/big-easy-driver-arduino/

Thanks for you replies!

I've already check the sparkfun's page about BigEasyDriver.

When I upload the one_stepper_example I have a nice and smooth clockwise rotation with almost no vibrations!

BUT

I ve got no counterclockwise rotation!

Even if I try any of the "stepper" library examples...

Is the problem from the BigEasyDriver? Or my wire connections?

Ok.. Forget the AccelStepper Library.

I just try the "stepper_speedControl" example, of stepper library.

#include <Stepper.h>

const int stepsPerRevolution = 400;  // change this to fit the number of steps per revolution
// for your motor


// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8,9,10,11);            

int stepCount = 0;  // number of steps the motor has taken

void setup() {
 Serial.begin(9600);
}

void loop() {
  // read the sensor value:
  int sensorReading = analogRead(A0);
  // map it to a range from 0 to 100:
  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  // set the motor speed:
  if (motorSpeed > 0) {
    myStepper.setSpeed(motorSpeed);
    // step 1/100 of a revolution:
    myStepper.step(stepsPerRevolution/100);
    
  } 
  Serial.println(motorSpeed);
}

Well, this is work for me, but in extremely slow speeds.

What to do if I want a little bit faster speeds?

Firstly, I change the "const int stepsPerRevolution" in 400 to get more steps.

Secondly, I change the map of sensorReading from 0 to 200, but nothing happens. (failed, so I put it back to 0-100)

I Print in SerialMonitor the values of sensor, to see what happens.

Below the value "50" there is a smooth change of the speed.
Above the value "50" there is something like 2 speeds. one from "50-75" and another one, from "75-100"

So, my questions are:

  • How can I achieve faster speeds?
  • How can I control these speeds more accurately from the potentiometer?

Also, as I said to my previous post, with the example of AccelStepper Library, the motion was too smooth.

This is not happening with the above code. A lot of vibration occurred.

So, another question:

  • Is there a way to get more silent movement or with less vibrations from the motor?

Thank you

  int motorSpeed = map(sensorReading, 0, 1023, 0, 100);
  // set the motor speed:
  if (motorSpeed > 0) {
    myStepper.setSpeed(motorSpeed);

So, why set the speed so low? If you are going, why are you complaining about slow?

    myStepper.step(stepsPerRevolution/100);

Why? Taking 4 steps, then reading the potentiometer, and outputting serial data are NOT ways to achieve speed.

sifis83:
Well, this is work for me, but in extremely slow speeds.

Did you read stepper motor basics ?

...R

Well, yes I have read it. It's very impressive article and I learn a lot. Thank you.

So, I have this code below, that is approximately work for me.

The speeds now are faster, but I want to have more precise control from the potentiometer.

Also, I want to double the selected value of the potentiometer with a pushbutton.

#include <Stepper.h>


Stepper stepper(400, 8, 9);

const int buttonPin = 2;
int buttonState = 0;

const int led1 = 12;


void setup()
{
  pinMode(buttonPin, INPUT);
  pinMode(led1, OUTPUT);
  
   stepper.setSpeed(160);
  // set the speed of the motor to 160 RPMs
  }

void loop()
{
 int buttonState = digitalRead(buttonPin);
 
  // get the sensor value
  int val = analogRead(0);
  
  int motorSpeed = map(val, 0, 1023, 0, 20);
  
  val = motorSpeed; // maybe this is wrong

  // move a number of steps equal to the change in the
  // sensor reading
  stepper.step(motorSpeed);
  
  
  if (buttonState == HIGH){
 motorSpeed *= 2;  // this is supposed to double my steps...
                   // it doubles it only in lower speeds
  digitalWrite(led1, HIGH);
  }
  else {
    digitalWrite(led1, LOW); // the led is working normally with the button
  }
   
}
  • Can you suggest me something to achieve double speed with the button?

  • Also, Is there any function to change the direction of the motor?

I appreciate your time and your replies.
Thanks again.

sifis83:
Well, yes I have read it. It's very impressive article and I learn a lot.

Thank you for your kind words.
However it looks like you did not try the simple stepper code that it linked to.

...R

  if (buttonState == HIGH){
 motorSpeed *= 2;  // this is supposed to double my steps...
                   // it doubles it only in lower speeds
  digitalWrite(led1, HIGH);
  }
  else {
    digitalWrite(led1, LOW); // the led is working normally with the button
  }

You've already assigned motorSpeed as the number of steps of the motor. It would make more sense to do this FIRST. It would also make sense to name the variable in relation to the value that is contains/how it is used.

The number of steps has NOTHING to do with speed.

  • Also, Is there any function to change the direction of the motor?

Step a negative number of steps.

Well, Robin2 your code unfortunately doesn't work for me ... But I did't experiment with it a lot.
(sorry, I don't have so much time these days). I will try it again and I will tell you more.

PaulS, I can't understand why the number of steps has nothing to do with Speed. As I read the stepper functions of "stepper" library "the RPM doesn't make the motor turn, just sets the speed at which it will when you call step().

Ok. I agree with you, but when I'm trying to change the RPM via my potentiometer (having a constant step) the motor does something weird...

...Above a value it starts to run quickly and below a value it has a very very slow run without having accurate control.

This is again my code that it seems that I have better control of the speed of the motor.

#include <Stepper.h>


Stepper stepper(400, 8, 9);

const int buttonPin = 3;
const int buttonPin2 = 5;
int buttonState = 0;
int buttonState2 = 0;

const int led1 = 12;


void setup()
{
  
  pinMode(buttonPin, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(led1, OUTPUT);
  
   stepper.setSpeed(151);      // below 151 the motor runs extremely slow
  // set the speed of the motor RPM.
  }

void loop()
{
 int buttonState = digitalRead(buttonPin);
 int buttonState2 = digitalRead(buttonPin2);
 
 
  // get the sensor value
  int val = analogRead(0);
  
  int motorSpeed = map(val, 0, 1023, -50, 20);
  
  if (buttonState2 == LOW){
    motorSpeed = 0;              // I just set a switch to start/stop the motor  
    digitalWrite(led1, LOW);
  }
  else {
    digitalWrite(led1, HIGH);
  }
 
  
  
  
  if (buttonState == HIGH){
 motorSpeed *= 6;            // When I am at high value of motorSpeed, it doesn't work.
  digitalWrite(led1, HIGH);
  }
  else {
    digitalWrite(led1, LOW); // the led is working normally with the button
  }

  // move a number of steps equal to the change in the
  // sensor reading
  stepper.step(motorSpeed);  
}

I have to mention that if I set the RPM below 151, the above code doesn't work.
I can't understand why...

Any suggestion on that?

Secondly, the *6 "steps" line works only when I am in low values in the potentiometer.
E.G. : When the potentiometer is a the highest value (-50 or 20) the *6 button doesn't work.

In other words I can't understand how can I achieve MAX and MIN speed for my motor.

Can you explain me more on this ?

Thirdly, to achieve my whole project to work...
Do you suggest me to change (with a variable) the number of steps or the RPM number?

(As I said before, the whole code (and project) is to control the speed of the motor with a potentiometer, and then multiply that value with a button and/or change the direction with another button at the given speed.)

Thank you again,
I really appreciate your replies and your patience.

sifis83:
Well, Robin2 your code unfortunately doesn't work for me ... But I did't experiment with it a lot.
(sorry, I don't have so much time these days). I will try it again and I will tell you more.

If you are using a BigEasydriver and my code does not work it is because you have something wrong which can be (and should be) fixed.
There seems little point trying anything more complicated until you have the simplest system figured out.

Post the code that you have used AND a diagram showing how everything is connected.

...R

PaulS, I can't understand why the number of steps has nothing to do with Speed.

If i tell you to head east for 4 kilometers, and call me when you get there, when should I expect you to call?

If you are in a car, i might expect a call in 4 minutes. If you are on a bicycle, perhaps 8 minutes. On foot, using crutches, with a bad case of the flu, perhaps 8 hours.

So, distance (number of steps) is NOT speed. Seed is number of steps divided by the time needed to take the steps.

Haha! That's a great way to explain "steps".

Ok, I don't disagree with you. I have already understand the theory.
The problem is, in the practical part.

Well, let's say you walk in a road with 10km/hour. And I tell you to cover a 1kilometer distance, in 1 minute.
To do that, you must increase your steps in time. I other words, you have to run, to achieve that.

That's the one reason that I choose to control the "steps" in my code. (for controlling "speed")
The other reason is, what I had already said in my previous post.

When I try to control the RPM (stepper.setSpeed) with my potentiometer, when the value goes below 151, the motor starts to move extremely slowly with too much vibration. Over 151, works normally.

The problem here is that I have set my controls (with potentiometer and buttons) as I want, BUT the range of the speed of the motor is to fast for my project. So, I just try to reduce the RPM... but... as I said I have the "151 value" problem that I explained in the upper lines.

Could you please tell me what is going on when set my motor speed below 151???

I also try to change the number of steps in one revolution of my motor (the 400 number), to have more analysis in steps. (My motor is 400/rev). FAILED AGAIN.

Today I was trying again to learn the accelstepper library.. but it's too early to write about this...haha!

So, any advice is welcome...

Thank you again

P.S. Probably, I will post a diagram of my connections, that weekend.

The setSpeed() function is NOT necessary. Timing between the steps is, as you noted. If you want to complete n steps in t time, it is not difficult to determine how much time needs to pass between steps. Only step ONCE when that time has passed.