Go Down

Topic: Stepper Library Max speed bug (Read 3320 times) previous topic - next topic

[arch3r]

Ive recently been testing and driving some new steppers I got with the standard arduino Stepper Library, I am aware that a few bugs have been posted about this perticular Library.

If this bug has already been posted and reported my apologies but I was unable to find it in the forums and its still in the most recent release

During my test with the stepper i used a potentiometer to set the speed of the stepper,
I have a 45v powersupply @ 3A, so I know the voltage isnt the problem
and my Stepper is 1.8deg/step with total 200 steps/revolution

Here's the code I started with:

Code: [Select]

Stepper stepper(200,5,6,7,8);
void setup()  {
 
 Serial.begin(9600);
 
}

void loop()  {
 
 del = map(analogRead(0),0,1024,1,500);
 stepper.setSpeed(del)

 stepper.step(1);
}


This is suppose to map out the 0-1023 value from the analog pin to 0-500 for the rpm of the stepper library

While moving the knob through its full rotation I noticed the stepper reach a certain speed and any further the stepper stop moving and generated a semi high frequency,
I pulled out my osciliscope and noticed as I turned the knob the frequency on 1 of the 4 pins jumped from 245hz to 6000hz

This striked me as odd so i went back to the code and found that this happened when I set the setSpeed() function to 301, anything before 300 would be fine but 301+ generated alarming high frequency,

I looked through the Stepper Library code and found the problem and also came up with a solution

Heres the section of code that has the bug, where the delay is setup for the step function

Code: [Select]

void Stepper::setSpeed(long whatSpeed)
{
 this->step_delay = 60L * 1000L / this->number_of_steps / whatSpeed;
}

void Stepper::step(int steps_to_move)
{  
  if (millis() - this->last_step_time >= this->step_delay)
     this->last_step_time = millis();
}


in the setSpeed function it calculates the delay needed in milliseconds to achive the deisred switching frequency. It appears that the step_delay variable which is apparently an int-type variable freaks out when I use 301+ rpm @ 200 steps/revolution

heres why:

60 * 1000 / #ofsteps / speed
= 60 * 1000 / 200 / 301
= 60,000 / 200 / 301
= 300/301
=0.9966

due to the int-type variable the 0.996 dosnt work to well, becuase it uses that value and the millis() function to determin the delay

**FIXED**

by using the micros() function instead of the millis() function and multiplying the step_delay by 1000 it maps the 0.996 millisecond delay to 996 microsecond delay, because 1 millisecond = 1000 microseconds

CODE:

Code: [Select]

void Stepper::setSpeed(long whatSpeed)
{
 this->step_delay = 60L * 1000L / this->number_of_steps * 1000 / whatSpeed;
}

void Stepper::step(int steps_to_move)
{  
  if (micros() - this->last_step_time >= this->step_delay)
     this->last_step_time = micros();
}



This has been checked with an osciliscope and the 6000hz frequency that was being generated at 301rpm @ 200steps is now around 250hz, where as the 300rpm value that worked with the bug was around 245hz

PROBLEM FIXED!!

enjoy


Arch3r

PaulS

Quote
heres why:

60 * 1000 / #ofsteps / speed
= 60 * 1000 / 200 / 301
= 60,000 / 200 / 301
= 300/301
=0.9966

Actually, number_of_steps and step_delay are integer types, so the arithmetic is all integer. As a result, step_delay is 0, not 0.996. And the delay functions don't like being called with a value of 0.

[arch3r]

yes I know there int type variables and thats why its not working so when you switch everything over from milliseconds to microseconds then the 0.966 thats seen as 0 is now seen as 996microseconds

Go Up