[SOLVED] Virtual button pressed for X seconds

You’re all correct in some way or another.

If you want ot use timer.disable() or timer.enable()… at all… then you must declare it global. Else it just wont work. In my example I chose not to include it… but I should have to help with understanding the compile error.

Costas is also correct. You can declare it global with a value, but the timer will replace it once you declare the same int a timer function.

If you take the PushData example, where it does not declare the timer to a var, then you will have no way to control it, and it will run forever (depending on setTimeout or setInterval)

1 Like

I see what you mean, you have to declare it obviously, but what I meant was, you don’t have to declare them globally to use in functions. They can be scoped to the local function. They do need to exist before messing with them, in that way your example will not work, but if you declare it right before the if, it works fine (provided you do the “int timerNew = timer.set Etc”.

1 Like

Notice that the functions that set timers return an int, which the function descriptions refer to as a “Timer ID”. This is a value that is unique to the individual timer and is meaningful to the SimpleTimer code, but not necessarily to the calling code or to the programmer. In fact, by reading the code, you can find out that a timer ID is just the array index of the timer that was allocated for you, BUT since that isn’t documented, good practice dictates that we do nothing with it other than store it to use for cancelling that same timer later on, if necessary. If you know you won’t be needing to do that, there isn’t even a reason to store it. A timer ID is the equivalent, but better! - of saying, “Hey, you know that timer I set three calls ago? The one that had an interval of 3000ms? Yeah, that one. I’m done with it. Please shut it off and return it to the pool of available timers.” Instead, you save the ID use it to explicitly specify which timer you meant.

You can store a timer ID anywhere, at any scope, that you can store an int, as long as it will still be in scope and undamaged, when & if you need to retrieve it.

I used with your code but after afew times, it not working a void, can explain it, thanks, about 7 or 8 times it went wrong

@Trieu_Le please post the formatted code that doesn’t work reliably for you.

BLYNK_WRITE(V5){
  if(param.asInt()){
    // button pressed
    newTimer = timer.setTimeout(2000,unlockbutton);
    led1.on();
  } 
  else {
    timer.disable(newTimer);
    led1.off();
  }
}

void unlockbutton() {
 if (rs==0){ 
   rs=1;}
 else if (rs==1){
   rs=0;}
}

it working perfectly in about 10 times. but after a few times control, unlockbutton not working, rs not change anymore.
(led display when i press button, after 2 secons led off and unlockbutton working)
Im also used timer.setinterval(1000L,senddata) in setup to get temperature data every second

Are you using 0.4.8 or an earlier version?

Sounds like the 10 timers per instance issue. Increased to 16 with BlynkTimer instead of SimpleTimer but you will still have problems if the Timers are not being deleted correctly.

Will advise further when I know what library version you are using.

Thanks. Maybe u right, because 10 times is not exactly , i guess that, maybe 16 as u said. im using newest 0.4.8 but maybe the old library not delete correctly. So i will find and deleted old simpletimer.h and add the new ones right?

Yes ensure you have the correct libraries. You can remove the header file from your sketch now as it’s included in the main Blynk libraries. Conventionally we use BlynkTimer now but the Blynk guys have left SimpleTimer available for Blynkers that don’t update their libraries and code.

Just check and use blynktimer. The issue still have, not exactly how many times i used and it not working, it depend on real time, it about 30 minutes when turn it on.

Setup
I used timer.setinterval(1000L,sentdate)
Void sentdata()
To update data every second

Can help me this issue?!!
Sorry I will upload my code later…

@Trieu_Le if your sketch is not too complicated can you paste the formatted version here.

#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> 
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
//#include <SimpleTimer.h>
#include <BlynkTimer.h>
#include <LiquidCrystal_I2C.h>
#include "EmonLib.h"
#include <EEPROM.h>
EnergyMonitor emon1;
BlynkTimer timer;
int newTimer = 1;


void setup()
{
  Serial.begin(115200);
    WiFiManager wifiManager;
timer.setInterval(1000L, LoadPower);
    
}

void loop()
{
  Blynk.run();
  timer.run(); // Initiates SimpleTimer
 }

void LoadPower()
{
  
    double Irms = emon1.calcIrms(1480);  // Calculate Irms only
    if (Irms < 0.3) Irms = 0;
    long watt = Irms*230.0; // default was 230 
    wattsume = wattsume+watt;
    energy=wattsume/(3600*1000);
    Blynk.virtualWrite(V8, Irms);Blynk.run();
    Blynk.virtualWrite(V9, watt);Blynk.run();
    Blynk.virtualWrite(V10, energy);Blynk.run();
    EEPROM.put(50,energy); 
    delay(100);
    EEPROM.commit();
}


BLYNK_CONNECTED() {
  // Request the latest state from the server
  Blynk.syncVirtual(V1,V2,V3,V4,V5,V6);}



BLYNK_WRITE(V5)
{
 if(param.asInt()){
    // button pressed
    newTimer = timer.setTimeout(2000,unlock);
    led6.on();
  } 
  else {
    timer.disable(newTimer);
    led6.off();
    
  }
  }
void unlock()
{
      if (sb==1){
      sb=0;
      led5.off(); }
      else if (sb==0){
      sb=1;
      led5.on(); }
      led6.off();
       
}

My project formatted as that. Thanks Costas …

Edit the formatting with 3 backticks line before and line after your sketch.

@Trieu_Le now I have fixed your gruesome formatting, see how it was done with the 3 backticks by viewing your last post in edit mode (but then abandon without editing).

Ohh Thanks alot :heart_eyes::heart_eyes::heart_eyes:

@Trieu_Le I am looking at your sketch now. Stripped it down to this (note there is no header required for the timer, whatever name it has).

// Press4Xseconds.ino per https://community.blynk.cc/t/solved-virtual-button-pressed-for-x-seconds/11379/58
#define BLYNK_PRINT Serial
//#include <DNSServer.h>
//#include <ESP8266WebServer.h>
//#include <WiFiManager.h> 
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
//#include <SimpleTimer.h>
//#include <BlynkTimer.h>
//#include <LiquidCrystal_I2C.h>
//#include "EmonLib.h"
//#include <EEPROM.h>
//EnergyMonitor emon1;

BlynkTimer timer;
int newTimer = 1;
int sb = 1;

WidgetLED led5(V1);
WidgetLED led6(V2);

char auth[] = "xxx";
char ssid[] = "GargoyleTest";
char pass[] = "xxx";
char server[] = "xxx";

void setup()
{
  Serial.begin(115200);
  Serial.println();
  //WiFiManager wifiManager;
  Blynk.begin(auth, ssid, pass, server);
  timer.setInterval(1000L, LoadPower);
    
}

void loop()
{
  Blynk.run();
  timer.run(); // Initiates SimpleTimer
 }

void LoadPower()
{ 
    /*
    double Irms = emon1.calcIrms(1480);  // Calculate Irms only
    if (Irms < 0.3) Irms = 0;
    long watt = Irms*230.0; // default was 230 
    wattsume = wattsume+watt;
    energy=wattsume/(3600*1000);
    Blynk.virtualWrite(V8, Irms);Blynk.run();
    Blynk.virtualWrite(V9, watt);Blynk.run();
    Blynk.virtualWrite(V10, energy);Blynk.run();
    EEPROM.put(50,energy); 
    delay(100);
    EEPROM.commit();
    */
}

BLYNK_CONNECTED() {
  // Request the latest state from the server
  //Blynk.syncVirtual(V1,V2,V3,V4,V5,V6);
  Blynk.syncVirtual(V5);
}

BLYNK_WRITE(V5)
{
 if(param.asInt()){
    // button pressed
    newTimer = timer.setTimeout(2000,unlock);
    led6.on();
  } 
  else {
    timer.disable(newTimer);
    led6.off();   
  }
}

void unlock()
{
      if (sb==1){
        sb=0;
        led5.off(); 
        Serial.println("LED5 OFF");
      }
      else if (sb==0){
        sb=1;
        led5.on();
        Serial.println("LED5 ON"); 
      }
      led6.off(); 
      Serial.println("LED6 OFF");     
}

I still need to add some more simulation but I’ll get back to you when I have worked something out.

@Trieu_Le if you run the following sketch with the timer count being displayed in V0 value display you will see it toggles between 1 and 2. All is fine, the bugs are in the rest of your sketch :slight_smile:

// Press4Xsecs.ino per https://community.blynk.cc/t/solved-virtual-button-pressed-for-x-seconds/11379/58

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

BlynkTimer timer;
int newTimer = 1;
int sb = 1;

WidgetLED led5(V1);
WidgetLED led6(V2);

char auth[] = "xxx";
char ssid[] = "GargoyleTest";
char pass[] = "xxx";
char server[] = "xxx";

void setup()
{
  Serial.begin(115200);
  Serial.println();
  Blynk.begin(auth, ssid, pass, server);
  timer.setInterval(1000L, LoadPower);    
}

void loop()
{
  Blynk.run();
  timer.run(); // Initiates SimpleTimer
 }

void LoadPower()
{ 
  // do some Emon stuff here
  Blynk.virtualWrite(V0, timer.getNumTimers()); // display # of running timers in Blynk
}

// V0 value display
// V1 Green LED
// V2 Red   LED

BLYNK_WRITE(V5)
{
 if(param.asInt()){  
    newTimer = timer.setTimeout(2000,unlock); // button pressed
    led6.on();
  } 
  else {
    timer.disable(newTimer);
    led6.off();   
  }
}

void unlock()
{
  if (sb==1){
    sb=0;
    led5.off(); 
    Serial.println("LED5 OFF");
  }
  else if (sb==0){
    sb=1;
    led5.on();
    Serial.println("LED5 ON"); 
  }
  led6.off(); 
  Serial.println("LED6 OFF");     
}

The simulation is only using V5 in the ON position but you can have ON / OFF with minor mods.
Edit: I have just used the button in PUSH mode and I notice the timer count is forever increasing.
It stops at the maximum 16. Mod the code above to delete the running timer in PUSH mode.

Were you working in PUSH or SWITCH mode?

If you are working in PUSH mode comment out this line:

timer.disable(newTimer); // for switch mode only

and after:

Serial.println("LED6 OFF");

add the following:

timer.deleteTimer(newTimer);     // for button in PUSH mode
1 Like

Thank you !!! Already upload and testing !!! It over an hour and still perfect.
I’m running in Push mode

It working perfectly, :heart_eyes::heart_eyes::heart_eyes::heart_eyes:. Thank you Costas !!

1 Like

A post was split to a new topic: Looking for coding advice for multiple, long-press buttons.widgets