C++ Blynk (Legacy) - Code Examples for Basic Tasks

#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 :thinking:

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 :thinking:

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 :thinking:

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
7 Likes