gin66 / FastAccelStepper

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

Using setSpeed() quickly while the stepper is moving causes position loss/incorrect position #24

Closed laminarturbulent closed 3 years ago

laminarturbulent commented 3 years ago

(I am using a TTGO T-Display ESP32 and a TMC5160 SilentStepStick v1.5)

Below is the relevant code that triggers the issue; it just moves the stepper back and forth between 0 and a set position "StepsToNext" when I have a button pressed (the code is in the main loop). When "UseSpeedSwitcher" is on, it changes the speed every 100 milliseconds which causes the position loss. When the speed isn't changed, the stepper returns to the correct position each time.

if (analogRead(BUTTON_2) < 1000)
{
  if(!B2Pressed)
    Serial.println("b2 pressed!");
  B2Pressed = true;
  if (millis() > LastMoveToMillis + TimeToNext*1000)
  {
    LastMoveToMillis = millis();
    Serial.println("movespeedmicros: " + String(MoveSpeedMicros));
    Serial.println("movespeed: " + String(MoveSpeed));
    Serial.println("movespeedMax: " + String(MoveSpeedMax));
    MovingToZero = !MovingToZero;
    if (MovingToZero)
    {
      FAS->moveTo(0);
    }
    else
    {
      FAS->moveTo(StepsToNext);
    }
  }
  if (millis() > LastSpeedSwitchMillis + 100 && UseSpeedSwitcher)
  {
    LastSpeedSwitchMillis = millis();
    SwitchedSpeed = !SwitchedSpeed;
    SpeedSwitchedTimes++;
    if (SwitchedSpeed)
      FAS->setSpeed(MoveSpeedMicros*0.9);
    else
      FAS->setSpeed(MoveSpeedMicros);
  }
}
gin66 commented 3 years ago

Thanks for the bug report. I have added a similar test case in StepperDemo as number 06 in the master branch. Can be executed with 't M1 06 R', if using motor 1. Same issue with avr, but not identical result.

Need to find the root cause, still.

gin66 commented 3 years ago

Looks like there are no steps lost, just it runs to the wrong position. In addition, constantly changing the speed during ramp down seems to cause like a sudden stop (no nice deceleration).

If executing 't M1 06 R' on esp32, then the position after the test is @-5746. Exiting test mode with 'x' and issuing 'M1 P0', then the stepper goes back to zero position

Still wondering about the root cause.

gin66 commented 3 years ago

Please check version 0.16.4 in your setup. In my test looks fine.

laminarturbulent commented 3 years ago

It looks like 0.16.4 has fixed it, great work!

laminarturbulent commented 3 years ago

This issue seems to be back with 0.16.5, the position gets wrong with my test code again. On 0.16.4 it keeps the position correctly.

gin66 commented 3 years ago

Right. It's annoying to have a regression in the avr code.

Now I have set up a new type of test for avr using simavr. For example executing test sequence 01 from StepperDemo yields not enough steps produced. Same behaviour as on the real HW. Hopefully this way, I have a good basis to make regression tests on something close to real hw.

gin66 commented 3 years ago

I have found a situation in the avr interrupt code, which could lead to lost steps. This has been fixed in 0.16.6

My test executed under simavr contains the sequence with varying speed. Expectation is to watch the requested amount of L->H-transitions. Locally this is checked. Hope that github actions goes through smoothly, too.

laminarturbulent commented 3 years ago

Tested on 0.16.8, position is kept correctly