BLYNK
BLYNK.IO       📲 GETTING STARTED       📗 DOCS       👉 SKETCH BUILDER

How to change SimpleTimer timer interval remotely?

SimpleTimer library’s timer object is heavily used in Blynk examples to prevent too heavy communication between hardware and Blynk cloud. Now I want for example periodically decrease and increase the the timing interval. While testing the sampling interval would be for example 10 seconds and in final version half hour.

Question: How can I change SimpleTimer’s timer interval remotely? The basic solution would be to replace the interval constant (eg. 30000) with variable, say “interval” and call the function with the new value every time the interval change is needed.

   long interval = 30000;
   timer.setInterval(interval, notifyUptime);

I have tried that, and the sketch compiles, but the interval doesn’t change from the original value set at setup().

Yes, I can see there already are some topics about this question, but I can’t find simple working example.

Step 1.
You need a global variable so that you can easily track your timer by using its ID

int timerID;

Step 2.
In your function where you call setInterval do like this

timerID = timer.setInterval(interval, notifyUptime);

Step 3.
In your “change interval” function delete the existing then create a new one.

timer.deleteTimer(timerID);
// set new interval
timerID = timer.setInterval(interval, notifyUptime); // now contains new interval
7 Likes

Thank you @Fettkeewl - Got it working!.
For someone else planning to use this solution here is a small fix:
Comma must be added as follows:
timerID = timer.setInterval(interval, notifyUptime)

Ay I missed that thank you, I just copy pasted your code, I have edited my reply.

Glad it worked out

Ciao,
could you post the code for the “change interval” function.
I have also this requirement
Thanks

Choose widget, slider or stepper, use seconds or millis as resolution

If widget is V10

BLYNK_WRITE(V10) 
{
   int seconds = param.asInt();
   timer.deleteTimer(timerID);
   timerID = timer.setInterval(seconds * 1000L, notifyUptime);
} 

Ciao - come sei?

I am using the Terminal widget to change timer intervals. Consequently my “change interval function” is BLYNK_WRITE(V1) function where V1 is the virtual pin to Terminal:

int timerID; This must be added before functions

BLYNK_WRITE(V1)       //Terminal at V1)
{

    Serial.print("\nTerminal: BLYNK_WRITE(V1)\n");   //Debug to see commands coming from Terminal

    String cmd = param[0].asStr();
    Serial.println(cmd);
  
    if (cmd=="interval10") {
       
       timer.deleteTimer(timerID);
       timerID = timer.setInterval(10000, notifyUptime);
  
    } else if (cmd=="interval30") {

       timer.deleteTimer(timerID);
       timerID = timer.setInterval(30000, notifyUptime);

    } else if (cmd=="interval60") {

       timer.deleteTimer(timerID);
       timerID = timer.setInterval(60000, notifyUptime);
       
    } else {
     
    }

}    //Blynk.write END

In the void setup() I am setting the initial value for timer:

  // Setup a function to be called every 10 sec
  timerID = timer.setInterval(10000, notifyUptime);

This will simplify your code

String cmd = param[0].asStr();
if (cmd.length() > 8 && cmd.substring(0,8).equalsIgnoreCase("interval") && cmd.substring(8).toInt() > 0)
{
   timer.deleteTimer(timerID);
   timerID = timer.setInterval(cmd.substring(8).toInt() *  1000L, notifyUptime);
}

It works like this providing the syntax of substring to int works as should

  1. Check if your command starts with the word interval, non case sensitive so interval, Interval, INTERVAL all works.

  2. Tries to cast everything from character position 8 and forward to an integer. If it succeds you get a number back as int, if not you get a 0.

  3. Sets your interval.

This setup allows you to set any interval within the size of an integer. In 4 lines of code.

Take it or leave it, let me know if it works :slight_smile:

Typo edited
It’s substring not substr

1 Like

Thanks @Fettkeewl! Nice code to use “general purpose” commands. Timer interval commands are not the only “text” commands I am using to control the hardware - so this helps a lot!

1 Like

The syntax might be off somewhere I’m still having issues with c++ having coded c# for some years.
But the logic is there :slight_smile:

You can also replace the keyword “interval” with
a variable and use .length for it where the 8s are instead should you want to quickly change the keyword

Code you sent works fine! I also made replacements you suggested:

String cmd = param[0].asStr();  //eg. 'int60'
String kwd = "int";             //keyword


    if (cmd.length() > kwd.length() && cmd.substring(0,kwd.length()).equalsIgnoreCase(kwd) && cmd.substring(kwd.length()).toInt() > 0)
    {
       timer.deleteTimer(timerID);
       timerID = timer.setInterval(cmd.substring(kwd.length()).toInt() *  1000L, notifyUptime);
    }

Have a nice day!

1 Like

Sweet. Well done :smile:

I’m still learning so here goes:

I’ve added void setup()

timerID = timer.setInterval(10000, notifyUptime);

and then I have:

BLYNK_WRITE(V0){   // add a slider on V0 range 0 to 30 (minutes)
  int seconds = param.asInt();
  Serial.println(seconds);
  timer.deleteTimer(timerID);
  timerID = timer.setInterval(10000, notifyUptime);

But i get

C:\Users\test\Documents\Arduino\libraries\Blynk\src/Blynk/BlynkTimer.h:57:9: error: initializing argument 2 of ‘int BlynkTimer::setInterval(long int, timer_callback)’ [-fpermissive]

 int setInterval(long d, timer_callback f);
     ^

exit status 1
invalid conversion from ‘int’ to ‘timer_callback {aka void (*)()}’ [-fpermissive]

Have I missed something?

Seems it insists on geting a Long value

timerID = timer.setInterval(10000L, notifyUptime);

add the L to the time

No difference

Void setup()

timerID = timer.setInterval(10000L, notifyUptime);

The function

BLYNK_WRITE(V0){   // add a slider on V0 range 0 to 30 (minutes)
  int seconds = param.asInt();
  Serial.println(seconds);
  timer.deleteTimer(timerID);
  timerID = timer.setInterval(seconds * 10000L, notifyUptime);
  Serial.print("V0 Slider value is: ");
  Serial.print("CountdownValue will be: ");

The error is picked up from the line in the void setup()

@AusUser5 I suspect you haven’t defined the timerID.

I use:

int timerID =1;

others just use:

int timerID;

I’ve cut the sketch back just to the minimum, which i think should work

#include <SimpleTimer.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <Blynk.h>

int timerID =1;
int notifyUptime;
 
SimpleTimer timer;

BLYNK_WRITE(V0){   // add a slider on V0 range 0 to 30 (minutes)
  int seconds = param.asInt();
  Serial.println(seconds);
  timer.deleteTimer(timerID);
  timerID = timer.setInterval(seconds * 10000L, notifyUptime);
  Serial.print("V0 Slider value is: ");
  Serial.print("CountdownValue will be: ");

void setup() {
timerID = timer.setInterval(10000L, notifyUptime));
}

void loop() {
  Blynk.run();
  timer.run();
}

I really hope its nothing obvious :flushed:

No, no, no.

void notifyUptime(){
   // whatever code you want to repeat at timed intervals here
}

There is an extra right paranthesis, before the semicolon

Edit: or missing a left. Can’t think straight atm

The extra parenthesis was finger trouble, and my last attempt before calling it a night…

I think I’m missing something as I’ve taken snippets from different parts of the post so here is the complete sketch.

It compiles fine, however I would like the relays_off timer here:

timer.setTimeout(10000, relays_OFF); // delay 10sec (10000) from first action and turn off

to be dynamic using the slider widget. Currently its fixed at 10secs

I’ve been experimenting with a Countdown variable but hasn’t been working.

BLYNK_WRITE(V0){ // add a slider on V0.

The complete sketch

#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <Blynk.h>

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "XXXX";
char pass[] = "XXXXXXXXXX";

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "XXXXXXXXXX";

// Set your LED and physical button pins here
// const int ledPin = 0;
// const int relay2 = 0; // Currently not used
const int btnPin = 2;
const int relay1 = 0;

SimpleTimer timer;
void checkPhysicalButton();
void actionRelays();
void relay1_ON();
void relay2_ON();
void relays_OFF();

int ledState = LOW;
int btnState = LOW;
// int relay1 = LOW;
int relay2 = LOW;
int Countdown;                // Stores Slider Widget Value
int Counter = 0;              // Set counter to 0. Use to count # of runs
int CountdownValue;           // Variable Used for Relay Timer

// Every time we connect to the cloud...
BLYNK_CONNECTED() {
  // Request the latest state from the server
  // Blynk.syncAll();

  // Alternatively, you could override server state using:
  //Blynk.virtualWrite(V14, ledState);
}

// When App button is pushed - switch the state
BLYNK_WRITE(V14) {
  ledState = param.asInt();
  // digitalWrite(relay1, ledState);
  Serial.println("App Button pressed");
  actionRelays();
}

void checkPhysicalButton()
{
  if (digitalRead(btnPin) == LOW) {
    // btnState is used to avoid sequential toggles
    if (btnState != LOW) {

      // Toggle LED state
      ledState = !ledState;
      Serial.println("Phyical Button pressed");
      actionRelays();
      

      // Update Button App
      Serial.println("Updated App Button status");
      Blynk.virtualWrite(V14, ledState);
    }
    btnState = LOW;
  } else {
    btnState = HIGH;
  }
}

BLYNK_WRITE(V0){   // add a slider on V0. 
  Countdown = param.asInt();  // set variable from Slider Widget as countdown, that can be then used in the actioRelays() setTimeout
  Serial.print("V0 Slider value is: ");
  Serial.println(Countdown);
  CountdownValue=(Countdown*60000); // Converst the value milliseconds 
  Serial.print("CountdownValue will be: ");
  Serial.println(CountdownValue);
}
void actionRelays(){
  relay1_ON(); // turn on relay1
  timer.setTimeout(2000, relay2_ON); // delay 2sec then turn on relay2
  timer.setTimeout(10000, relays_OFF); // delay 10sec (10000) from first action and turn off both relays
}

void relay1_ON(){
  Serial.println("relay1 on");
  digitalWrite(relay1,HIGH); // turn on relay1
  Blynk.virtualWrite(V18, 255); // turn on an LED widget (optional)
}

void relay2_ON(){
  Serial.println("relay2 on");
  digitalWrite(relay2,HIGH); // turn on relay2
  Blynk.virtualWrite(V20, 255); // turn on an LED widget (optional)
}

void relays_OFF(){
  Serial.println("relays off");
  digitalWrite(relay1,LOW); // turn off relay1
  digitalWrite(relay2,LOW); // turn off relay2
  Blynk.virtualWrite(V18, 0); // turn off an LED widget (optional)
  Blynk.virtualWrite(V20, 0); // turn off an LED widget (optional)
  Blynk.virtualWrite(V14, 0); // turn off relay1 Button App
  Counter++; // Increment the run counter by 1
  Blynk.virtualWrite(V16, Counter);    
}

void setup()
{
  // Debug console
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  pinMode(relay1, OUTPUT);
  digitalWrite(relay1, LOW); // ensure relay is OFF on reboot
  pinMode(btnPin, INPUT_PULLUP);
  digitalWrite(relay1, ledState);

  // Setup a function to be called every 100 ms
  timer.setInterval(100L, checkPhysicalButton);
}

void loop()
{
  Blynk.run();
  timer.run();
}