gin66 / FastAccelStepper

A high speed stepper library for Atmega 168/328p (nano), Atmega32u4, Atmega 2560, ESP32, ESP32S2, ESP32S3, ESP32C3 and Atmel SAM Due
MIT License
283 stars 67 forks source link

What are the limiting factors for stepper update rate? #194

Closed MichaelJFr closed 8 months ago

MichaelJFr commented 11 months ago

I've been collaborating with @ChrGri on the active pedal project (see issue #174), and I'm trying to understand what options are available to us for improving pedal response. What considerations go into deciding the DELAY_MS_BASE value for a platform? What problems might we face bringing it down to 1 or 2ms on the ESP32?

gin66 commented 11 months ago

Historic reasons. The driver started with the 328p, which happens to have a timer at 16MHz, which wraps around at approx. 4ms. So the controlling stepper task has been developed taking this into consideration. For extending support on esp32, the 4ms cycle rate was not reconsidered, because that‘s allow to have similar behavior across platform and the whole test suite is applicable to all platforms, too. If the cycle rate would be significantly different, then all test cases may need to be reworked - eventually.

So it is mainly historical reasons. Besides this, there is a limitation in regard to the queue depth, but this would come into play only by significantly lowering the cycle time. As you are interested in increasing the rate and esp32 is a fast chip, performance wise it is ok. Even though, I would not expect any difference in behavior, but this just an assumption, which is not backed up by any test.

In order to speed up things, there is one more point to note. The queue is filled, so that a minimum time into the future is covered. This is currently 20ms = TICKS _PER_MS/50. So you could first try to reduce this to e.g. 5ms aka division by 200.

MichaelJFr commented 11 months ago

OK, that's great info thanks. I'll let you know if we find any benefit from changing it.

ChrGri commented 11 months ago

Hi @gin66, wanted to test you suggestion and check the frequency behavior of speed & acceleration values. However, the getCurrentSpeed & getCurrentAcceleration functions always seem to return 0. The getCurrentPosition is the only function returning non zero values.

Tested these functions: int32_t currentStepperPos = _stepper->getCurrentPosition(); int32_t currentStepperVel = _stepper->getCurrentSpeedInUs(); int32_t currentStepperVel2 = _stepper->getCurrentSpeedInMilliHz(); int32_t currentStepperAccel = _stepper->getCurrentAcceleration();

gin66 commented 11 months ago

getCurrentAcceleration() yields a non-zero value only during acceleration or deceleration. getCurrentSpeedInUs() and getCurrentSpeedInMilliHz() should yield non-zero only, while the stepper is running.

ChrGri commented 10 months ago

Your correct @gin66 . I had to slow down the speed and acceleration in the library to get non-zero values.

I remember also having tested "TICKS_PER_MS/200" and "DELAY_MS_BASE=1", can't remember if this was the correct syntax, which resulted in lost steps. Haven't checked though, wether the lost steps were already lost on the GPIO or whether the servo had problems with increases update rate. Something which needs further testing on our side.

gin66 commented 8 months ago

stale