EasyDriver/stepper: Wrong behavior when using stepper.h or AccelStepper.h

Hi Everyone,

I’m a beginner, first post.I read the “how to use this forum” a couple times, and i’ll try to stick to the rules.
Please let me know if there is something i’m not doing right, (i think you will!) and i’ll make the corrections.
I also spent days looking for a solution on this forum and elsewhere (the AccelStepper Google group for example)

================

setup
Arduino uno + easy drivers + Nema17 (specs/datasheets below)

Problem
The unexpected behavior with the Arduino example “stepper_oneRevolution”:

>>> The motor doesn’t go backward.
After setting the step per revolution to 1600, it goes counter-clock wise half a revolution, then again counter-clock wise 1 full revolution.

================

To start with and match the wiring (Easy Driver Hook-up Guide - learn.sparkfun.com), I changed the pins number from this:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);
to this:
Stepper myStepper(stepsPerRevolution, 2, 3, 4, 5);

I also tried to swap 2 and 3 and a few other combinations with no success. I got it going backward at some point (2,4,3,5 if i remember) but the Forward and backward moves weren’t symmetric.

I looked at the Stepper.h file but couldn’t find anything obvious. (not much coding knowledge here)

================

Questions:

Since the demo Sparkfun code seems to work (as well as other codes from this forum, as long as they don’t use the Stepper.h or AccelStepper.h:

  1. Is it a wiring issue that wouldn’t show up with simpler codes (pins not used …)?
  2. Do i need to tweak the stepper.h library?
  3. Is it something else i’m not seeing/aware of?

Thanks in advance, any help will be greatly appreciated.
Please let me know if i need to provide more or different informations in order to be helped.

================

More infos, specs …

Attached is a Fritzing Breadboard wiring diagram.

Stepper motor (Nema17) : https://images-na.ssl-images-amazon.com/images/I/91nlDJYWTQL.pdf
Stepper Driver: EasyDriver: https://www.amazon.com/gp/product/B004G4XR60/ref=oh_aui_detailpage_o05_s00?ie=UTF8&psc=1

================

All seems to work as expected using different simple codes (from easydriver or from this forum), as long as they don’t use another library like the Stepper.h or the AccelStepper.h

For example, this works well:

================

For quicker looks at code:

  • Copy/paste from Arduino IDE, these are the codes i actually upload to the Arduino Uno.
  • I did not change the comments so we can see the changes (Pin numbers and StepPerRevolution)

What (seems to) works:

SparkFun Easy Driver Basic Demo
Toni Klopfenstein @ SparkFun Electronics
March 2015
https://github.com/sparkfun/Easy_Driver

Simple demo sketch to demonstrate how 5 digital pins can drive a bipolar stepper motor,
using the Easy Driver (https://www.sparkfun.com/products/12779). Also shows the ability to change
microstep size, and direction of motor movement.

Development environment specifics:
Written in Arduino 1.6.0

This code is beerware; if you see me (or any other SparkFun employee) at the local, and you've found our code helpful, please buy us a round!
Distributed as-is; no warranty is given.

Example based off of demos by Brian 4
Schmalz (designer of the Easy Driver).
http://www.schmalzhaus.com/EasyDriver/Examples/EasyDriverExamples.html
******************************************************************************/
//Declare pin functions on Redboard
#define stp 2
#define dir 3
#define MS1 4
#define MS2 5
#define EN  6

//Declare variables for functions
char user_input;
int x;
int y;
int state;

void setup() {
  pinMode(stp, OUTPUT);
  pinMode(dir, OUTPUT);
  pinMode(MS1, OUTPUT);
  pinMode(MS2, OUTPUT);
  pinMode(EN, OUTPUT);
  resetEDPins(); //Set step, direction, microstep and enable pins to default states
  Serial.begin(9600); //Open Serial connection for debugging
  Serial.println("Begin motor control");
  Serial.println();
  //Print function list for user selection
  Serial.println("Enter number for control option:");
  Serial.println("1. Turn at default microstep mode.");
  Serial.println("2. Reverse direction at default microstep mode.");
  Serial.println("3. Turn at 1/8th microstep mode.");
  Serial.println("4. Step forward and reverse directions.");
  Serial.println();
}

//Main loop
void loop() {
  while(Serial.available()){
      user_input = Serial.read(); //Read user input and trigger appropriate function
      digitalWrite(EN, LOW); //Pull enable pin low to allow motor control
      if (user_input =='1')
      {
         StepForwardDefault();
      }
      else if(user_input =='2')
      {
        ReverseStepDefault();
      }
      else if(user_input =='3')
      {
        SmallStepMode();
      }
      else if(user_input =='4')
      {
        ForwardBackwardStep();
      }
      else
      {
        Serial.println("Invalid option entered.");
      }
      resetEDPins();
  }
}

//Reset Easy Driver pins to default states
void resetEDPins()
{
  digitalWrite(stp, LOW);
  digitalWrite(dir, LOW);
  digitalWrite(MS1, LOW);
  digitalWrite(MS2, LOW);
  digitalWrite(EN, HIGH);
}

//Default microstep mode function
void StepForwardDefault()
{
  Serial.println("Moving forward at default step mode.");
  digitalWrite(dir, LOW); //Pull direction pin low to move "forward"
  for(x= 1; x<200; x++)  //Loop the forward stepping enough times for motion to be visible
  {
    digitalWrite(stp,HIGH); //Trigger one step forward
    delay(2);
    digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
    delay(2);
  }
  Serial.println("Enter new option");
  Serial.println();
}

//Reverse default microstep mode function
void ReverseStepDefault()
{
  Serial.println("Moving in reverse at default step mode.");
  digitalWrite(dir, HIGH); //Pull direction pin high to move in "reverse"
  for(x= 1; x<200; x++)  //Loop the stepping enough times for motion to be visible
  {
    digitalWrite(stp,HIGH); //Trigger one step
    delay(2);
    digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
    delay(2);
  }
  Serial.println("Enter new option");
  Serial.println();
}

// 1/8th microstep foward mode function
void SmallStepMode()
{
  Serial.println("Stepping at 1/8th microstep mode.");
  digitalWrite(dir, LOW); //Pull direction pin low to move "forward"
  digitalWrite(MS1, HIGH); //Pull MS1, and MS2 high to set logic to 1/8th microstep resolution
  digitalWrite(MS2, HIGH);
  for(x= 1; x<1600; x++)  //Loop the forward stepping enough times for motion to be visible
  {
    digitalWrite(stp,HIGH); //Trigger one step forward
    delay(2);
    digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
    delay(2);
  }
  Serial.println("Enter new option");
  Serial.println();
}

//Forward/reverse stepping function
void ForwardBackwardStep()
{
  Serial.println("Alternate between stepping forward and reverse.");
  for(x= 1; x<5; x++)  //Loop the forward stepping enough times for motion to be visible
  {
    //Read direction pin state and change it
    state=digitalRead(dir);
    if(state == HIGH)
    {
      digitalWrite(dir, LOW);
    }
    else if(state ==LOW)
    {
      digitalWrite(dir,HIGH);
    }
    
    for(y=1; y<200; y++)
    {
      digitalWrite(stp,HIGH); //Trigger one step
      delay(2);
      digitalWrite(stp,LOW); //Pull step pin low so it can be triggered again
      delay(2);
    }
  }
  Serial.println("Enter new option:");
  Serial.println();
}

And what doesn’t seem to work:

/*
 Stepper Motor Control - one revolution

 This program drives a unipolar or bipolar stepper motor.
 The motor is attached to digital pins 8 - 11 of the Arduino.

 The motor should revolve one revolution in one direction, then
 one revolution in the other direction.


 Created 11 Mar. 2007
 Modified 30 Nov. 2009
 by Tom Igoe

 */

#include <Stepper.h>

const int stepsPerRevolution = 1600;  // 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, 2, 3, 4, 5);

void setup() {
  // set the speed at 60 rpm:
  myStepper.setSpeed(60);
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one revolution  in one direction:
  Serial.println("clockwise");
  myStepper.step(stepsPerRevolution);
  delay(500);

  // step one revolution in the other direction:
  Serial.println("counterclockwise");
  myStepper.step(-stepsPerRevolution);
  delay(500);
}

Thanks again.

Stefan

[Edit] = Redundant post

Image from Original Post so we don’t have to download it. See this Image Guide

737721fa512ba65933d22c9614309a2cb1bab896.png

…R

Your motor requires a driver that can provide 2 amps per coil. An Easydriver can provide a max of 0.75 amps. Unfortunately the BigEasydriver is unlikely to provide 2 amps either and you may need a more expensive driver that can supply 3 or 4 amps so as not to be right at its limit. I guess you could use a BigEasydriver or a Pololu DRV8825 with the current set low (say 1.5 amps) but then you won't get the full value from your motor.

When you have sorted that out this Simple Stepper Code should be good for testing,

The standard Stepper library is not intended for drivers that take step and direction inputs. Use the AccelStepper library with the DRIVER option.

Fritzing diagrams are so easy to misunderstand as to be almost useless for anything other than art. A photo of a simple pencil drawing is almost always more useful.

...R Stepper Motor Basics

Thank you for your (lightning fast!) answers Robin2.

I will do more research to find a good match (motor/driver) that meet my needs (camera slider for Mid weight camera rigs)

Although there is something i don't understand.

1)Why does it seem to work as expected with the EasyDriver Demo code if the driver is not capable of driving that specific motor?

2) Could it be that the amazon link is pointing to the wrong motor specs?

3) Can i measure how much the coils are expecting myself and would you happen to have a link (handy) that would explain how to please?


Next time i'll try do do "a simple pencil drawing" Although i'm not sure of how better it will be, since i sort of digitally did the same (wired from scratch) in Fritzing, but i'll try anyway.


Thanks again. Stefan

Also, the same unexpected behavior happens with the “Bounce” example from the AccelStepper lib.

Meaning the motor is not going backward to 0 position once at the end of travel.

But the motor turns, and i can crank up the speed with no apparent other issues.

Is it supposed to be the case anyway?
Even if the Driver is not theoretically able to drive the motor (too low amps from driver to motor)?

Thanks
Stefan


// Bounce.pde
// -*- mode: C++ -*-
//
// Make a single stepper bounce from one limit to another
//
// Copyright (C) 2012 Mike McCauley
// $Id: Random.pde,v 1.1 2011/01/05 01:51:01 mikem Exp mikem $

#include <AccelStepper.h>

// Define a stepper and the pins it will use
AccelStepper stepper; // Defaults to AccelStepper::FULL4WIRE (4 pins) on 2, 3, 4, 5

void setup()
{  
  // Change these to suit your stepper if you want
  stepper.setMaxSpeed(100);
  stepper.setAcceleration(20);
  stepper.moveTo(500);
}

void loop()
{
    // If at the end of travel go to the other end
    if (stepper.distanceToGo() == 0)
      stepper.moveTo(-stepper.currentPosition());

    stepper.run();
}

Robin2: Your motor requires a driver that can provide 2 amps per coil

Hi again Robin,

I have a couple A4988 and looking at the specs it says: "It is designed to operate bipolar stepper motors in full-, half-, quarter-, eighth-, and sixteenth-step modes, with an output drive capacity of up to 35 V and ±2 A

Do you think that be enough to start with? At least to have the AccelStepper code to work properly?

ps: i'll make a drawing of my EasyDriver setup now.

Thanks, Stefan

Here is the drawing of the EasyDriver Wiring.

EasyDriver_Wiring_drawing.jpg

Hi again Robin,

Thanks a bunch!

I made a second setup (kept the other one as is for now) with an A4988 (from reprap).

I started by following the wiring found in this post (message #10)

Then reading through the discussion, i followed your suggestion to wire MS1, MS2 and MS3 to the ground.

Next i changed the pin values in your simple stepper code and uploaded it. First it did something a bit strange at the very beginning, turning one way and reverse a few dozen steps, before going 200 steps full revolution one way, then the other way.

After tweaking the driver pot a bit i got it to not do the weird thing before executing the program.

Bingo!

Now, may i ask you about the AccelStepper way of controlling the motor?

Would you have/share a link to some simple stepper motor control (like yours, going 1 rev back and forth) but using the AccelStepper library? One that you have tested with success with the same setup of yours?

Or is the "Bounce" example form AccelStepper is supposed to do that already?

I tried it and it just keeps going forward by 1,25 rev chunks (accelerates and decelerates, brief stop, go again ... )

I will look more into the DRIVER mode you mentioned ( i briefly did already), although it might be beyond my skills as of now.

Thanks again for your time, it helped me solve a problem and learn a bit more already!

Stefan

Hurray!!!

I found how to set the DRIVER mode in this link

Quote from MikeM you need to set up AccelStepper in the 'stepper driver' mode. This means it will control 2 output pins, one for direction and one for step. You will need to construct your AccelStepper something like this: AccelStepper stepper(1, 10, 11); the 1 means 'stepper driver' mode 10 is the pin to be used to step 11 is the pin to be used to direction

I set mine to (1,3,2) and very much enjoyed looking at the result right away!!!

I guess i'm on my way.

I'd call this a solved problem. I'll safely wait a couple days before i add "Solved" to the title.

Let me know if i need to share more details for others to benefit (we never know) from this.

THANKS!!!

Stefan

I don't have any AccelStepper examples. There are several on the Accelstepper website. Take some time to study them because some people find the concept of the motor operating asynchronously a little confusing.

And slow down the Posts. Give people time to reply - keeping in mind that you may live in a different time zone.

...R

All good.

Sorry if i sounded impatient or too demanding, it was not intended. I thought it was a good thing to post updates, since some problems were solved and didn't need answers anymore, and other (new) questions appeared. I'll take the advice though.

Cheers, Stefan

Robin,

Going back reading your first answer. I'm impressed! You replied in no time, and really gave all the informations needed to go further, with a little work on my side. Big up sir!!!

Stefan

ps: i know, i've exceeded the amount of posts i can make in a 5 minutes period, my bad, apologies, i guess i can be qualified as impatient.

Stefan-sg: ps: i know, i've exceeded the amount of posts i can make in a 5 minutes period, my bad, apologies, i guess i can be qualified as impatient.

That limit is only there to stop spammers. It goes away after you make 100 Posts (IIRC).

The problem with making lots of posts is that you are spending far more time thinking about your problem than I am and if I start reading and thinking about your next Reply (I do things chronologically :) ) it is very confusing to then move on to another Post by you that has more and different information.

...R