From 4fa8d7fa80e84de99bc51e724f1864895c9f0fdc Mon Sep 17 00:00:00 2001 From: Richie Vos Date: Sat, 1 Apr 2023 15:57:16 -0700 Subject: [PATCH 1/2] Use safer & faster min/max functions Two issues here. First, the default min/max that this is dependening on uses min/max as a macro. That means the `min` call was actually evaluating `sqrt` and float cast twice, with a minor perf penalty (unless the optimizer catches it). Second, not all environments have min/max available in the global namespace (particularly platformio's native env). This avoids that implicit dependency. Therefore this fixes: ``` /StepperDriver/src/BasicStepperDriver.cpp:141:25: error: use of undeclared identifier 'min'; did you mean 'fmin'? ``` The original purpose of this diff was the second issue, but researching other people running into this made me realize the first issue. So I went down a different fix. Another fix is just use native c++'s std::min and std::max, but that gets into various arduino-cli related compiler complications. --- src/BasicStepperDriver.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/BasicStepperDriver.cpp b/src/BasicStepperDriver.cpp index beaa798..83f3b0a 100644 --- a/src/BasicStepperDriver.cpp +++ b/src/BasicStepperDriver.cpp @@ -13,6 +13,23 @@ */ #include "BasicStepperDriver.h" + +/* + * Min/Max functions which avoid evaluating the arguments multiple times. + * See also https://github.com/arduino/Arduino/issues/2069 + */ +template +constexpr const T& stepperMin(const T& a, const T& b) +{ + return b < a ? b : a; +} + +template +constexpr const T& stepperMax(const T& a, const T& b) +{ + return a < b ? b : a; +} + /* * Basic connection: only DIR, STEP are connected. * Microstepping controls should be hardwired. @@ -138,7 +155,7 @@ void BasicStepperDriver::startMove(long steps, long time){ float a2 = 1.0 / profile.accel + 1.0 / profile.decel; float sqrt_candidate = t*t - 2 * a2 * d; // in √b^2-4ac if (sqrt_candidate >= 0){ - speed = min(speed, (t - (float)sqrt(sqrt_candidate)) / a2); + speed = stepperMin(speed, (t - (float)sqrt(sqrt_candidate)) / a2); }; } // how many microsteps from 0 to target speed @@ -177,7 +194,7 @@ void BasicStepperDriver::alterMove(long steps){ if (steps >= 0){ steps_remaining += steps; } else { - steps_remaining = max(steps_to_brake, steps_remaining+steps); + steps_remaining = stepperMax(steps_to_brake, steps_remaining+steps); }; break; case DECELERATING: @@ -228,7 +245,7 @@ long BasicStepperDriver::getTimeForMove(long steps){ startMove(steps); cruise_steps = steps_remaining - steps_to_cruise - steps_to_brake; speed = rpm * motor_steps / 60; // full steps/s - t = (cruise_steps / (microsteps * speed)) + + t = (cruise_steps / (microsteps * speed)) + sqrt(2.0 * steps_to_cruise / profile.accel / microsteps) + sqrt(2.0 * steps_to_brake / profile.decel / microsteps); t *= (1e+6); // seconds -> micros From 0a1fe7dd1037c4aeb1882ada41c42f4aa7c6676a Mon Sep 17 00:00:00 2001 From: Richie Vos Date: Sat, 1 Apr 2023 15:59:22 -0700 Subject: [PATCH 2/2] Patch fix for compilation tweak --- library.properties | 2 +- platformio.ini | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/library.properties b/library.properties index b221a8f..368abe5 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=StepperDriver -version=1.4.0 +version=1.4.1 author=Laurentiu Badea maintainer=Laurentiu Badea sentence=A4988, DRV8825 and generic two-pin stepper motor driver library. diff --git a/platformio.ini b/platformio.ini index 69a4b63..9db153d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -44,3 +44,6 @@ board = teensylc [env:uno] board = uno platform = atmelavr + +[env:native] +platform = native