From 0d3f5ee696866b9a11364f62255f4069de907259 Mon Sep 17 00:00:00 2001 From: David Huss <dh@atoav.com> Date: Thu, 30 Jan 2025 16:14:24 +0100 Subject: [PATCH] Fix discontinuity issues, add comments --- precipitationctl.ino | 60 ++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/precipitationctl.ino b/precipitationctl.ino index a04c731..cd83f4a 100644 --- a/precipitationctl.ino +++ b/precipitationctl.ino @@ -20,14 +20,21 @@ double blend = 0.0f; Ticker ticker; -double lerp(double a, double b, double t) { - t = max(0.0, min(1.0, t)); - return a + t * (b - a); +unsigned long current_time, last_target_time; + +/// Linear Interpolation between a and b +double lerp(double a, double b, double blend) { + // Clamp blend to 0.0 and 1.0 + blend = max(0.0, min(1.0, blend)); + // Return blended values + return a + blend * (b - a); } + +// Normalized Servo function void setServoNormalized(double pos) { pos = min(1.0, max(0.0, pos)); - // + // SQRT to emphasize small values pos = sqrt(pos); int span = abs(SERVO_MAX - SERVO_MIN); int servo_pos = SERVO_MIN + span * pos; @@ -35,6 +42,7 @@ void setServoNormalized(double pos) { // Serial.print(pos); // Serial.print(" --> "); // Serial.println(servo_pos); + Serial.print(SERVO_MIN); // To freeze the lower limit Serial.print(" "); Serial.print(SERVO_MAX); // To freeze the upper limit @@ -43,15 +51,26 @@ void setServoNormalized(double pos) { servo.write(servo_pos); } + +// Function to select a new target from the list void setNewTarget() { + // Store time since power up (milliseconds) + last_target_time = millis(); + + // Store the previous target ptarget = target; + + // Select a new target from the data array (see data.h) target = data[data_index]; + + // Set a new current value current = target; // Serial.print("New Target is ["); // Serial.print(data_index); // Serial.print("]: "); // Serial.print(target); + // Increment data_index (count up +1) data_index++; // Reset index when longer than the data (loop over) @@ -61,8 +80,7 @@ void setNewTarget() { } } -float testval = 0.0f; -float increment = 0.01f; + void setup() { Serial.begin(115200); @@ -73,6 +91,8 @@ void setup() { ESP32PWM::allocateTimer(2); ESP32PWM::allocateTimer(3); + + // Servo setup servo.setPeriodHertz(50);// Standard 50hz servo servo.attach(servoPin, 1000, 2000); // attaches the servo on pin 18 to the servo object // using SG90 servo min/max of 500us and 2400us @@ -80,24 +100,26 @@ void setup() { // which are the defaults, so this line could be // "myservo.attach(servoPin);" - // Set new Target every 28.44 seconds (leads to 3 days) + // Set new Target every INTERVAL seconds (see define statement above) ticker.attach(INTERVAL, setNewTarget); // Interval in seconds } + +// Loop is run forever, repeated void loop() { - unsigned long currentMillis = millis(); - blend = fmod(float(currentMillis), (INTERVAL * 1000.0f)) / (INTERVAL * 1000.0f); + // Store current time + current_time = millis(); + // Calculate blend value (0.0 directly after new target selected, counts up till 1.0) + // (this uses the modulo operation (division remainder) to create a repeating pattern) + blend = fmod( + float(current_time - last_target_time), + (INTERVAL * 1000.0f)) + / (INTERVAL * 1000.0f); current = lerp(ptarget, target, blend); - // Serial.print(ptarget); - // Serial.print(" ("); - // Serial.print(int(blend*100)); - // Serial.print("%) "); - // Serial.print(target); - // Serial.print(" ("); - // Serial.print(int((1.0-blend)*100)); - // Serial.print("%) = "); - // Serial.println(current); + // Set servo position setServoNormalized(current); - delay(2); + + // Wait for x milliseconds + delay(20); } -- GitLab