MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
karpukhin
 
Posts: 7
Joined: Sun Jul 06, 2014 11:50 am

MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by karpukhin »

Team

Like so many others on these forums and elsewhere on the net, I CANNOT GET MY STEPPER TO GO ABOVE 79 RPM. I have reviewed endless forums, and found no solution.

I'm using Arduino Uno, Adafruit Motorshield v2, regular MENA 17 bipolar stepper 200.

(If anybody has a definitive answer how to get the stepper to, say, 200RPM - please post!!)

So I am trying to analyse this systematically. I'm a novice - PLEASE HELP ME FIGURE THIS OUT!

First, I measured the time it takes to execute a single command forwardstep() in Accel library (same analysis applies to the Adafruit library). I used this simple code:

int steps;
unsigned long time;
unsigned long time200steps;

void loop()
{
steps=0;
time200steps=0;

while(steps<200){
time=millis();
forwardstep();
time200steps=time200steps+millis()-time;
steps++;
}

Serial.print("Steps: ");
Serial.print(steps);
Serial.print(" Elapsed: ");
Serial.print(time200steps);
}

The result - one step takes 3.81 milliseconds, which exactly equates to 79RPM. Each step is a blocking command, so one physically cannot execute the next step of the motor until the current command is completed.

This means it is a software/board limitation, NOT motor limitation (since there is no feedback from motor).

So we need to understand what is the bottleneck in a single step command. Three main hypotheses:

Hypothesis 1. Arduino code for one step takes so long.
I.e. the code for "forwardstep()" in Accel and "myMotor->step(1, FORWARD, DOUBLE)" in Adafruit library involves many complex calculations and thus takes so long to execute. This sounds unlikely - what calculation can take 3.81 milliseconds?? Or maybe there is a delay() or some other function gone haywire?

Does anybody know if this is the case? Where can I review the code of the command itself to see if this may be the case?

Hypothesis 2. Interaction between Arduino and Motorshield takes so long.

Sub-hypothesis 2.1 : I2C bus clock speed slows down the communication.
Even at 100kHz, this should not be a limitation at 200rpm - we are talking about mere 667 steps per second.
But of course, I tried changing to 400kHz - no impact.

Sub-hypothesis 2.2: Adafruit Motorshield v2 slows down the communication.
There is some frequency setup in AFMS.begin() - what is this? Can this be the reason?
A reliable way to test this would be to measure the time it takes to communicate directly in the Accel or Adafruit library. Has anybody done this? How to do this?

Hypothesis 3: Motorshield takes so long to execute the command, and the Arduino code for one step is waiting for confirmation of completion before proceeding.
Any ideas how to test this?

Many thanks
Stepan

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by adafruit_support_mike »

Neither the Adafruit Motor Shield v3 library nor the AccelStepper library contain a function named 'forwardstep()'. What libraries are you using?

karpukhin
 
Posts: 7
Joined: Sun Jul 06, 2014 11:50 am

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by karpukhin »

Clarification - in this example I'm using Accel library. The forwardstep() function is an underlying sub procedure. I'm using it directly in an attempt to get to the root cause of the problem.

The below is from standard Accel / Adafruit example. You can see how the forwardstep() function is defined.

#include <AccelStepper.h>
#include <AFMotor.h>

// two stepper motors one on each port
AF_Stepper motor1(200, 1);
AF_Stepper motor2(200, 2);

// you can change these to DOUBLE or INTERLEAVE or MICROSTEP!
// wrappers for the first motor!
void forwardstep1() {
motor1.onestep(FORWARD, SINGLE);
}
void backwardstep1() {
motor1.onestep(BACKWARD, SINGLE);
}
// wrappers for the second motor!
void forwardstep2() {
motor2.onestep(FORWARD, SINGLE);
}
void backwardstep2() {
motor2.onestep(BACKWARD, SINGLE);
}

// Motor shield has two motor ports, now we'll wrap them in an AccelStepper object
AccelStepper stepper1(forwardstep1, backwardstep1);
AccelStepper stepper2(forwardstep2, backwardstep2);

User avatar
adafruit_support_mike
 
Posts: 67446
Joined: Thu Feb 11, 2010 2:51 pm

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by adafruit_support_mike »

For reference, it helps to post the entire body of code you're trying to compile for the Arduino (between CODE tags to preserve the formatting). There are lots of moving pieces in software, and partial information can be less useful than no information.

In this case, we still need to know things you haven't shown, like what PWM frequency you used when configuring the motor control object, and whether you're calling onestep() directly or through step().

karpukhin
 
Posts: 7
Joined: Sun Jul 06, 2014 11:50 am

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by karpukhin »

My apologies - I'm new to this forum, but will learn. I appreciate your help.

Below is the entirety of the code I am using in order to test my problem. My problem is to get Arduino UNO + Adafruit Motor Shield v2 to run a stepper at 200-300 rpm.

Code: Select all

#include <Wire.h>
#include <AccelStepper.h>
#include <AFMotor.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"

Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
Adafruit_StepperMotor *motor1 = AFMS.getStepper(200, 2);

int steps=0;
unsigned long time;
unsigned long time200steps;

void forwardstep() {  
  motor1->onestep(FORWARD, DOUBLE);
}
void backwardstep() {  
  motor1->onestep(BACKWARD, DOUBLE);
}

AccelStepper stepper(forwardstep, backwardstep); // use functions to step

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

void loop()
{  
  steps=0;
  time200steps=0;

  while(steps<200){
    time=millis();
    forwardstep();
    time200steps=time200steps+millis()-time;
    steps++;
  }
  
  Serial.print("Steps: ");
  Serial.print(steps);
  Serial.print("   Elapsed: ");
  Serial.print(time200steps);
}

gtrMechanix
 
Posts: 12
Joined: Tue Apr 01, 2014 12:28 am

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by gtrMechanix »

Great great great thread. Am myself too swamped to participate, but just want to say I hope this thread leads to some dang "UberAccel" lib or the likes. (Myself, I set my several stepper motors aside and bought a RS-555 DC motor for it's RPM's & smoothness, but I hope to return the steppers - esp. if they can crank it up a bit.)

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by adafruit_support_bill »

I'm on the road at the moment, but I can set up a test when I get back. If you check the tutorial, there are instructions for increasing the i2c bus speed on the Arduino. This will speed things up considerably. I'm not real familiar with the accelstepper code, but there is possibly some overhead there as well.

If you really want to optimize, and are willing to give up micro step mode, there is some micro stepping overhead that can be factored out of the Adafruit library.

karpukhin
 
Posts: 7
Joined: Sun Jul 06, 2014 11:50 am

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by karpukhin »

Thank you. I will try to look into potential overhead and I2C. If any other ideas/hypotheses - please shoot, I am very keen to get stepper speeds into hundreds of RPM.

Meanwhile, if anybody out there ever managed to get any stepper into hundreds RPM on Arduino - please shout!!

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by adafruit_support_bill »

One way to get higher speeds is to use a lower step-count motor. 48 step motors are reasonably common and will rotate >4 times faster than a 200 step motor at the same step rate.

karpukhin
 
Posts: 7
Joined: Sun Jul 06, 2014 11:50 am

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by karpukhin »

Thank you bill. This would be, of course, at the expense of precision, but yes, makes sense.

Logically, the Arduino hardware is definitely fast enough to make, say, 500 or 1000 steps per second. Arduino can handle microseconds. 500 cycles per second is really not a lot, it must be doable. There is a bottleneck there somewhere, maybe overhead as you suggest.

karpukhin
 
Posts: 7
Joined: Sun Jul 06, 2014 11:50 am

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by karpukhin »

Just an update on getting a stepper to a high speed for those interested, based on my experimentation with another stepper driver - M415B (there are similar cheaper and more expensive drivers, with the same speed characteristics).

1. Connecting the M415B stepper driver to Arduino Uno, I could get the stepper motor to 214 rpm. This is a NEMA17 200 step, 48mm motor, nominal 12 volt, 1.5A. In this test I also powered it at 12 volts (ie no chopping).

2. This driver is designed for even much higher speeds (min pulse duration of 3 microseconds), but the motor limitation kicks in at nominal voltage at 214 rpm (it may be somewhat different for different motors).

3. The chopping functionality of this driver allows voltage up to 40 volts. Maybe you don't want to go that high, but even slight increase helps. Increasing the voltage clearly increases the max rpm. Even increasing from 12 volts to 15 volts will increase speed from 214 to 250 rpm in my experiments.

Conclusions so far: a stepper should physically be able to rotate at max approx 200 rpm, after which you need a chopper. Thus the reason Adafruit Motor Shield does not allow to do that is likely either (a) library soft overhead, or (b) I2C/related comms.

Will investigate more.

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: MAX STEPPER SPEED - LET'S FIGURE IT OUT!!

Post by adafruit_support_bill »


Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”