gin66 / FastAccelStepper

A high speed stepper library for Atmega 168/328p (nano), Atmega32u4, Atmega 2560, ESP32, ESP32S2, ESP32S3, ESP32C3 and Atmel SAM Due

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

setAutoEnable() funcitonality

devrim-oguz opened this issue · comments

@gin66 Thank you very much for this library. This is the best stepper library I have used so far. I can drive stepper motors really fast using an ESP32 thanks to this. However, there is a slight issue on the auto enable function while using the setCurrentPosition().
For example, if I try this code:

homeAxis();

fastStepper.init();
axisStepper = fastStepper.stepperConnectToPin(AXIS_MOTOR_STEP_PIN);

if( axisStepper ) {
    axisStepper->setDirectionPin(AXIS_MOTOR_DIRECTION_PIN);
    axisStepper->setEnablePin(AXIS_MOTOR_ENABLE_PIN);
    axisStepper->setAutoEnable(true);
}
else {
    ESP.restart();
}

axisStepper->setCurrentPosition(0);

delay(1500);
axisStepper->setSpeed(30);
axisStepper->setAcceleration(5000);
axisStepper->moveTo(550400);

It homes the steppers using directly turning on and off the pins and then it sets the position to 0. After that, it moves to a given position which it can't reach correctly. It always misses it with some margin. I think this is due to starting driving the motors as soon as you enable them, because some drivers takes some time to adjust before actually pushing steps. If I change the code like this:

if( axisStepper ) {
    axisStepper->setDirectionPin(AXIS_MOTOR_DIRECTION_PIN);
    axisStepper->setEnablePin(AXIS_MOTOR_ENABLE_PIN);
    //axisStepper->setAutoEnable(true); <-Commented this line
}
else {
    ESP.restart();
}

axisStepper->enableOutputs(); //Manually enabling the outputs and waiting a little after that
delay(200);
axisStepper->setCurrentPosition(0);

delay(1500);
axisStepper->setSpeed(30);
axisStepper->setAcceleration(5000);
axisStepper->moveTo(550400);

it works without a problem. I think you need to give some time to the drivers before actually pushing steps to them. I don't know if you'd have the same issue with other drivers, but this is the case with my HPD-HBS57 closed loop stepper driver. It never misses any step due to its closed loop nature, however it misses steps with autoEnable turned on. I think you should wait a little before disabling the stepper motors between the commands and wait a little before starting them. This way they can have some time to adjust, and they wouldn't get turned on and off when there isn't any command in the queue immediately.

Thank you

Thanks for opening this as a new issue.

@gin66 just a guess at this - do you think this issue might be related to the inherent delay in digitalWrite?
Would port manipulation help this?

Port manipulation would however limit which pins could be used as enable signals.

If this is an issue coming from the delay of digitalWrite then there might be an issue further down in the ISR for direction change,
Line 93 of StepperISR_avr.cpp and Line 88 of StepperISR_esp32.cpp

Kind regards,
Jarryd

commented

Actually the esp32 stepper driver is more elegant due to the much better hardware capabilities compared to the avr. So it should achieve stable high speed pulse output - even with several steppers simultaneously.

From digitalWrite I expect, that - after return from this routine - the output pin is set accordingly and in my tests I could not see any different behavior. Nevertheless it still depends on the HW, how long it takes, till the stepper output drivers are enabled/disabled. From data sheet for HPD-HBS57 in the Internet, there was nothing mentioned, how long to wait between stepping and enable on/off. If the enable turns on/off any power supply, this could take a while until it stabilizes.

Based on this and as you propose the API could provide a call to set a delay from enable to stepping and stopping to disable. What puzzles me, is the following:

  • the esp32 performs already an implicit delay for the first step. This equals the period time for the speed at beginning of the ramp
  • you are using a delay for 100ms, which is pretty long.

Could you please help with the following:

  • what do you mean with „small margin“ ?
  • what is the result, if you start with autoenable on and turn it off while stepper is moving ?
  • what is the result, if you start with autoenable off and turn it on while stepper is moving ?

What I mean by the "small margin" is when I calibrate an axis to an absolute position with an outside measurement, (for example when the axis is at a point A I set the position as 0) and when I rotate the axis lets say 10 rounds by putting a position that is absolute multiple of the steps it takes for the motor to do one revolution (for example my motor does one revolution in 3200 steps, so when I say go to 64000 [20 times 3200]) it doesn't stop at the same point, but it always misses it with the same amount. When I try the experiment again, it stops exactly at that wrong position again. But when I disable the auto enable function and enable the motor 100 ms before the movement, everything works properly. What I feel like the stepper driver is not ready to take does steps as soon as it is enabled, but I might be wrong. For the other things you said, I need to do an experiment.

commented

API has been extended to implement delays from enable stepper to first step and from last step to disable stepper:

  // In auto enable mode, the stepper is enabled before stepping and disabled
  // afterwards. The delay from stepper enabled till first step and from
  // last step to stepper disabled can be separately adjusted.
  // The delay till disable is done in period interrupt/task with 4 or 10 ms repetition rate
  // and as such is with several ms jitter.
  void setAutoEnable(bool auto_enable);
  int setDelayToEnable(uint32_t delay_us);
  void setDelayToDisable(uint16_t delay_ms);
#define DELAY_OK 0
#define DELAY_TOO_LOW -1
#define DELAY_TOO_HIGH -2

Please check

commented

The example StepperDemo provides commands for adjusting the delay values. In addition output drivers can be turned manually on/off and auto_enable mode can be turned on/off, too.

Could be suitable for testing after adapting to your HW config (Step/Direction/Enable and respective polarity).

commented

stale. if does not work, just open a new issue

hi @devrim-oguz I got issue with this driver, can you help me with this?

Hello,

This was a long time ago. But from what I remember, there is some delay needed for the stepper drivers to get enabled. You can try the solution gin66 implemented and see if it works:

int setDelayToEnable(uint32_t delay_us);
void setDelayToDisable(uint16_t delay_ms);

Use these functions to set a delay for the enable signal. If the issue persists, you can try disabling the autoEnable functionality and manually enable and disable the motors by using digitalWrite:

void setAutoEnable(bool auto_enable);

I hope this helps,
Best Regards