pkerspe / ESP-FlexyStepper

This library is used to control one or more stepper motors from an ESP32 device. It is based on the FlexyStepper library by S.Reifel but provides some additional functionality
MIT License
152 stars 32 forks source link

Slow speed seem not to work: Step Frequency lower than 32 Hz not supported #17

Open TPD95100 opened 3 years ago

TPD95100 commented 3 years ago

I am working on a project where I need speed of 1 to 100 steps per second. I use the following code in a test:

const int DISTANCE_TO_TRAVEL_IN_STEPS = 2000;

const int SPEED_IN_STEPS_PER_SECOND = 300;
const int ACCELERATION_IN_STEPS_PER_SECOND = 800;
const int DECELERATION_IN_STEPS_PER_SECOND = 800;
...
stepper.connectToPins(MOTOR_STEP_PIN, MOTOR_DIRECTION_PIN);
  stepper.setSpeedInStepsPerSecond(SPEED_IN_STEPS_PER_SECOND);
  stepper.setAccelerationInStepsPerSecondPerSecond(ACCELERATION_IN_STEPS_PER_SECOND);
  stepper.setDecelerationInStepsPerSecondPerSecond(DECELERATION_IN_STEPS_PER_SECOND);
  stepper.startAsService();
.......
stepper.setSpeedInStepsPerSecond(10);
  stepper.setTargetPositionRelativeInSteps(1000);
  SpeedPercent = 10;
  ShowDisplay();
  delay(5000);
  stepper.setSpeedInStepsPerSecond(20);
  stepper.setTargetPositionRelativeInSteps(1000);
  SpeedPercent = 20;
  ShowDisplay();
  delay(5000);
  stepper.setSpeedInStepsPerSecond(50);
  stepper.setTargetPositionRelativeInSteps(1000);
  SpeedPercent = 30;
  ShowDisplay();
  delay(5000);
  stepper.setSpeedInStepsPerSecond(0);
  stepper.setTargetPositionRelativeInSteps(0);
  SpeedPercent = 0;
  ShowDisplay();
  delay(5000);

There is no difference at speed 10, 20 and even with 30 I saw no increase. Only with 50 I saw a slightly fester movement.

Is there a problem with slow speeds?

pkerspe commented 3 years ago

are you using microstepping on your stepper driver? Also for testing set maybe a larger position value to rule out problems with the acceleration on a short trip

TPD95100 commented 3 years ago

I somehow solved the problem by enabling microsteps so that I do not need the very low frequency. The motor has lost torque due to the microsteps but it still works.

So, from my side all OK but I just wanted to report this issue as it is a quit unexpected behaviour (I would assume that high frequency’s are more challenging than very slow ones ...)

In also made the experienced that setting the steps per second to zero does not stop the motor in all cases - it sometimes continues to rotate very slow. Only setting the relative target position to zero as well will stop the motor (it actually turns a bit backward after deceleration which is actually helpful for my application (dosing pump, this feature prevents dropping)

Is there a simple command to stop the motor immediately?

Again, my application now works perfect - just for you to know that it had some surprises in the package.

thank you very much for creating this library,

Thomas

pkerspe commented 3 years ago

I guess what you are experiencing with the motor still spinning is either a problem of combining blocking and non blocking functions (see doc) or the deceleration algorithm has issues with the low speeds and overshoot. Did you check if the stepper eventually stops after some time of spinning slowly?

There is an emergency stop function with Should rapidly stop the motor. After all when you set a target you tell the library to move to this target and maybe I did not foresee this case ever that someone wants to move to a specific position with the speed 0...after all a bit of a weird use case ;-) So Setting target position to the current position is one possible way to achieve a more or less immediate stop (it still might try to gently decelerate depending on the current speed)

pkerspe commented 2 years ago

After a long time I digged out the Oscilloscope and verified your observations. It seems that around 32 hz is the lowest step frequency that is working. Values below that will always result in at least 32 hz stepping frequency. Values above seem to be fine.

felixwelsch commented 1 year ago

Hello, all together, I am running into the same problem :-/ In a bottling application, I need velocities going near zero (1Hz). Any suggestions on how/where to change the source to make that possible?

I think it happens due to 'periodOfSlowestStep_InUS = 1000000.0 / sqrt(2.0 * acceleration_InStepsPerSecondPerSecond);' in line 771/772 of /src/ESP_FlexyStepper.cpp. But don't know the math/reason of this calculation, would it be OK to simply set 'periodOfSlowestStep_InUS' to a higher value?

pkerspe commented 1 year ago

If you need such low step speeds, why not simply use a timer interrupt function at 1 hz to get a precise slow step speed. I assume you do not need acceleration feature at such low speeds

MikesMachines commented 2 months ago

I've been experiencing a similar issue. I need to be able to change the speed, acceleration, deceleration while running. I can hit higher speeds (>800rpm) using any acceleration / deceleration. I can only hit slow speeds (~ <80 rpm) by dropping the acceleration and deceleration under 200. So I just modify the accel / decel when the speed slows under a given amount.

Many thanks for publishing this library!!!