#4 Slow & Variable Servo Sweep Without ‘delay()’ (Yay Timers!)
This is one I dug out of my archive and tweaked a bit to make it variable and stable.
I also have another method of varing a timer, shown in a later post: 20 - Easy Variable Timer
This example will allow you to control the sweep speed of a servo motor… normally they run at one speed, from where they are to where you want them to go. Traditional methods to slow that down is move the servo in incremental steps with a delay between each step.
This is that, but without the blocking delay()
command. NOTE: Due to the intermittent steps, even at 1ms timing between steps, the sweep will still be much slower then normal.
1st Challenge for you: Use logic to determine if the incremental speed is low enough to skip the intermittent steps all together
2nd Challenge for you: This code is a bit clunky and even though starting the same timer again should normal reset it’s instance, I found I needed to use timer delete to keep them from building up same timer instances (once it reached 16 instances, that timer stopped). See if you can devise a cleaner way of processing the timers and the sweeps
3rd Challenge for you: When adjusting the speed, the sweep will restart from the beginning… Try to make the adjustment in the timing without needing a reset of the sweep loop
For Widgets, you will need:
- Button in Switch mode (V0) to start and stop the sweep
- Display (V1) to show the servo position 10-160
- Slider (V2) to adjust the sweep speed interval in ms - I recommend setting the range from 1-500 for up to a 1/2 second step interval.
Servo motor with signal pin on pin 12 (D6 on Wemos).
//#define BLYNK_PRINT Serial // This prints to Serial Monitor
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <Servo.h>
char auth[] = "xxxxxxxxxx";
char ssid[] = "xxxxxxxxxx";
char pass[] = "xxxxxxxxxx";
//char server[] = "xxx.xxx.xxx.xxx"; // IP for your Local Server
char server[] = "blynk-cloud.com"; // URL for Blynk Cloud Server
int port = 8080;
Servo myservo;
BlynkTimer timer;
BlynkTimer UpTimer;
int SrvoPin = 12;
int SrvoPos;
int SrvoButton;
int SrvoSpeed = 30;
int SrvoTimer; // ID for timer, allows the ability to enable, disable, delete, etc.
void setup() {
//Serial.begin(9600); // BLYNK_PRINT data
WiFi.begin(ssid, pass);
Blynk.config(auth, server, port);
Blynk.connect();
Blynk.virtualWrite(V2, SrvoSpeed);
}
void loop() {
Blynk.run();
timer.run();
}
BLYNK_CONNECTED() {
Blynk.syncAll(); // Synchronize hardware with App widgets when connected
}
//----- Slow Servo Sweep Button -----
BLYNK_WRITE(V0) { // START Blynk Function
SrvoButton = param.asInt();
if (SrvoButton == 1) { // If button ON start servo sweep
myservo.attach(SrvoPin); // Enable Servo
SrvoPos = 10; // Start servo at position 10
timer.deleteTimer(SrvoTimer); // Delete timer so it can start over without taking up resources
SrvoTimer = timer.setTimer(SrvoSpeed, moveServoUP, 160); // Call moveServoUP() function 160 times
} else { // If button OFF stop servo sweep
myservo.detach(); // Disable Servo - prevents jittering when not activly running
timer.deleteTimer(SrvoTimer); // Delete timer so it can start over without taking up resources
} // END else
} // END Blynk Function
//----- Slow Servo Sweep Speed -----
BLYNK_WRITE(V2) { // START Blynk Function
timer.deleteTimer(SrvoTimer); // Delete timer so it can start over without taking up resources
SrvoSpeed = param.asInt();
Blynk.syncVirtual(V0); // Check Button status to restart the loop
} // END Blynk Function
void moveServoUP() { // START Arduino Function
myservo.write(SrvoPos); // tell servo to go to position in variable 'pos'
SrvoPos++; // Increment servo position 1 step
Blynk.virtualWrite(V1, SrvoPos);
if (SrvoPos >= 160) { // check if servo has reached endstop
timer.deleteTimer(SrvoTimer); // Delete timer so it can start over without taking up resources
SrvoTimer = timer.setTimer(SrvoSpeed, moveServoDOWN, 160); // Call moveServoDown() function 160 times
} // END else
} // END Arduino Function
void moveServoDOWN() { // START Arduino Function
myservo.write(SrvoPos); // tell servo to go to position in variable 'pos'
SrvoPos--; // Decrement servo position 1 step
Blynk.virtualWrite(V1, SrvoPos);
if (SrvoPos <= 10) { // check if servo has reached endstop
timer.deleteTimer(SrvoTimer); // Delete timer so it can start over without taking up resources
Blynk.syncVirtual(V0); // Check Button status to restart the sweep loop
} // END if
} // END Arduino Function