Skip to content

Commit

Permalink
nextAction() now waits until the right time
Browse files Browse the repository at this point in the history
This makes the code less non-blocking but simplifies what the caller has to do while still allowing control to pass back to the caller for each step.
  • Loading branch information
laurb9 committed Sep 30, 2017
1 parent 3f49f4e commit 2524c89
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 19 deletions.
1 change: 0 additions & 1 deletion examples/AccelTest/AccelTest.ino
Expand Up @@ -45,7 +45,6 @@ void loop() {
Serial.print(" dt="); Serial.print(wait_time);
Serial.print(" rpm="); Serial.print(stepper.getCurrentRPM());
Serial.println();
microWaitUntil(micros() + wait_time);
} else {
stepper.disable();
Serial.println("END");
Expand Down
4 changes: 2 additions & 2 deletions library.properties
@@ -1,9 +1,9 @@
name=StepperDriver
version=1.1.2-beta
version=1.1.2-beta2
author=Laurentiu Badea
maintainer=Laurentiu Badea
sentence=A4988, DRV8825 and generic two-pin stepper motor driver library.
paragraph=Control steppers via a driver board providing STEP+DIR. Microstepping is supported. Acceleration is supported. Supported drivers are A4988, DRV8824, DRV8825, DRV8834, DRV8880.
paragraph=Control steppers via a driver board providing STEP+DIR like the ones from Pololu. Microstepping is supported. Acceleration is supported. Supported drivers are A4988, DRV8824, DRV8825, DRV8834, DRV8880.
category=Device Control
url=https://github.com/laurb9/StepperDriver
architectures=*
17 changes: 10 additions & 7 deletions src/BasicStepperDriver.cpp
Expand Up @@ -85,12 +85,8 @@ void BasicStepperDriver::setSpeedProfile(Mode mode, short accel, short decel){
* positive to move forward, negative to reverse
*/
void BasicStepperDriver::move(long steps){
long next_event;
startMove(steps);
do {
next_event = nextAction();
microWaitUntil(micros() + next_event);
} while (next_event);
while (nextAction());
}
/*
* Move the motor a given number of degrees (1-360)
Expand Down Expand Up @@ -252,10 +248,14 @@ void BasicStepperDriver::calcStepPulse(void){
}
}
/*
* Yield to step control
* Toggle step and return time until next change is needed (micros)
*/
long BasicStepperDriver::nextAction(void){
static unsigned long next_action_time = 0;
long next_action_interval = 0;
if (steps_remaining > 0){
microWaitUntil(next_action_time);
/*
* DIR pin is sampled on rising STEP edge, so it is set first
*/
Expand All @@ -272,10 +272,13 @@ long BasicStepperDriver::nextAction(void){
};
digitalWrite(step_pin, LOW);
// account for calcStepPulse() execution time
return pulse - m;
next_action_interval = pulse - m;
} else {
return 0; // end of move
// end of move
next_action_interval = 0;
}
next_action_time = micros() + next_action_interval;
return next_action_interval;
}
enum BasicStepperDriver::State BasicStepperDriver::getCurrentState(void){
enum State state;
Expand Down
4 changes: 2 additions & 2 deletions src/BasicStepperDriver.h
Expand Up @@ -144,7 +144,7 @@ class BasicStepperDriver {
* Methods for non-blocking mode.
* They use more code but allow doing other operations between impulses.
* The flow has two parts - start/initiate followed by looping with nextAction.
* See AccelTest example.
* See NonBlocking example.
*/
/*
* Initiate a move over known distance (calculate and save the parameters)
Expand All @@ -157,7 +157,7 @@ class BasicStepperDriver {
void startRotate(long deg);
void startRotate(double deg);
/*
* Toggle step and return time until next change is needed (micros)
* Toggle step at the right time and return time until next change is needed (micros)
*/
long nextAction(void);
/*
Expand Down
17 changes: 10 additions & 7 deletions src/MultiDriver.cpp
Expand Up @@ -32,6 +32,11 @@ void MultiDriver::startMove(long steps1, long steps2, long steps3){
* Trigger next step action
*/
long MultiDriver::nextAction(void){
static unsigned long next_action_time = 0;
long next_action_interval = 0;

microWaitUntil(next_action_time);

// Trigger all the motors that need it (event timer = 0)
FOREACH_MOTOR(
if (event_timers[i] == 0){
Expand All @@ -40,23 +45,23 @@ long MultiDriver::nextAction(void){
);
// Find the time when the next pulse needs to fire
// this is the smallest non-zero timer value from all active motors
long next_event = 0;
ready = true;
FOREACH_MOTOR(
if (event_timers[i] > 0){
ready = false;
if (event_timers[i] < next_event || next_event == 0){
next_event = event_timers[i];
if (event_timers[i] < next_action_interval || next_action_interval == 0){
next_action_interval = event_timers[i];
}
}
);
// Reduce all event timers by the current left time so 0 marks next
FOREACH_MOTOR(
if (event_timers[i] > 0){
event_timers[i] -= next_event;
event_timers[i] -= next_action_interval;
}
);
return (ready) ? 0 : next_event;
next_action_time = micros() + next_action_interval;
return next_action_interval;
}
/*
* Optionally, call this to begin braking to stop early
Expand Down Expand Up @@ -91,8 +96,6 @@ void MultiDriver::move(long steps1, long steps2, long steps3){
startMove(steps1, steps2, steps3);
while (!ready){
next_event = nextAction();
// wait until the next event
microWaitUntil(micros() + next_event);
}
}

Expand Down

0 comments on commit 2524c89

Please sign in to comment.