Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support non-blocking nextAction() #122

Open
ddowling opened this issue Dec 22, 2023 · 0 comments
Open

Support non-blocking nextAction() #122

ddowling opened this issue Dec 22, 2023 · 0 comments

Comments

@ddowling
Copy link

Is there any interest in a non-blocking version of the nextAction() method?
I have been testing the following replacement that can be called with nextAction(false) from the main loop or an interrupt handler to drive all of the step pulses without blocking the caller. I also modified how the last_action_end value was calculated to base this off the calculated times as this significantly reduces the accumulation of jitter on the step pulses which was affecting the maximum speeds I could achieve.

long BasicStepperDriver::nextAction(bool block)
{
    if (steps_remaining > 0)
    {
        if (block)
            delayMicros(next_action_interval, last_action_end);
        else
        {
            unsigned long now = micros();

            long delay =  (last_action_end + next_action_interval) - now;

            if (delay > 0)
                return delay;
        }
        
        // DIR pin is sampled on rising STEP edge, so it is set first
        digitalWrite(dir_pin, dir_state);
        digitalWrite(step_pin, HIGH);

        // save value because calcStepPulse() will overwrite it
        unsigned long pulse = step_pulse;
        calcStepPulse();

        // Rely on the the calStepPulse function to produce a small delay
        // for the step high pulse
        digitalWrite(step_pin, LOW);

        // Base last_action_end on the expected time the event should
        // happen to smooth out jitter caused by timing clicks arriving late
        if (last_action_end == 0)
            last_action_end = micros();
        else
            last_action_end += next_action_interval;

        next_action_interval = pulse;
    }
    else
    {
        // end of move
        last_action_end = 0;
        next_action_interval = 0;
    }
    return next_action_interval;
}

I can work this into a pull request if there is some interest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant