Help with a 2 timer/countdown project

Hello. First of all you have to understand that i am stupid. But i am not planning to stay that way…
I am new to Blynk. I am new to ESP8266 as well. I am trying to do a project and hopefully others after this one(if i am not killing myself in the process)

Description:
I have a “device” based on wemos D1 mini board. It reads 2 push buttons and execute a relay action based on 2 timers.
First timer is a total time. It starts with 20 when button V9 is pressed on the app. Also V9 sets the Countdown timer to 10.
The second one is physical button countdown time named buttonPin.

Both timers are countdown timers. So, when i press V9 both timers are set from 0(both) to 20 and 10 seconds respectively. The relay is also set from OFF to ON. For the 20 seconds or 10 seconds (whichever comes first to 0)
the relay is ON. The countdown time is counting down only while buttonPin is kept pressed. If you stop pressing it, the countdown time stops/freezes and awaits to press buttonPin again to countdown the remaining countdown time. If you do nothing after V9 is pressed, the Total time reaches 0 after 20 seconds and the relay is set to OFF. If you press the V9 again, the counters are incremented. So, Total time from 0 to 20 and Countdown time from 10 to 20 and the relay is back to ON. I know that in the code you will find the increments set to 5 and 10, but if i try to put 10 and 20 (as it should) the incremental values are doubled. No idea why…

All that i wrote previously it happens already. So the “device” works. With one difference. The V9, Total time, is not a physical button, but a blynk(virtual) button on my phone. When i press the V9 on the phone, everything works as expected. The buttonPin is a physical pushbutton and works perfect. No matter what i’ve tried i can’t make a second physical button (to replace V9) to work for the life of me. Keep in mind that i am newer than new on this :frowning:

The builtIN LED on the board it’s used so i can see when the buttonPin (Countdown button) is pressed. Being set as a PUSH on the app, while i keep it pressed on the phone, the builtIN LED stays ON, so i know that the code is working. The builtIN LED will be replaced with a second relay. That i will do later. I have only one relay shield for now.

If someone can help me with the piece of code that will replace the blynk button(V9) with a physical one will be a big help for me. Not only that it will solve my problem but will help me understand how i should have done it.

Second question is: how can i make the timers to be displayed as minutes:seconds? So instead of 30(seconds) to actually display 0:30…0:29…0:28…etc.

Thank you for all your help. The entire sketch follows: ( P.S. Please forgive my english. It is not my native language.
Please also forgive my comments, it helps me to find my head around all that mess:frowning:

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>      // library for SimpleTimer       

SimpleTimer timer;            // define a timer for use by SimpleTimer library

char auth[] = "token";
char ssid[] = "ssid";
char pass[] = "pass";

// constants
const int buttonPin = 15;     // COUNTDOWN  TIME physical pushbutton / pin D8 on D1 Mini
const int ledPin =  2;        // Built_IN LED pin D4 on D1 Mini

// variables
int buttonState = 0;          // variable for reading the buttonPin status
int Totaltime=0;                // Global variable Total time
int Countdown=0;                // Global variable Countdown time / run EverySecond
bool ONstatus  = false;       // variable to switch the relay  ON and OFF

 BLYNK_WRITE(V9){   // Blynk Button V9 for Cycle start and/or increment Totaltime and Countdown
 Countdown = (Countdown+5);
 Totaltime = (Totaltime+10);
 digitalWrite(16, HIGH); // send ON signal to relay
 
}
void runEverySecond(){ // runs every second
    if((Totaltime > 0)&& (ONstatus == true)){
    Totaltime--;    //  reduce Totaltime by 1 second, every second
  }  
  
    if((Countdown > 0)&& (ONstatus == true)&&(buttonState == HIGH)&&(Totaltime > 0)){
    Countdown--;    //  reduce Countdown by 1 second every second

    Serial.print(F("Device will work for "));
    Serial.print(Countdown);
    Serial.println(F(" second(s)"));    
  }  
  
  if((Countdown > 0) && (ONstatus == false)&&(buttonState == LOW)){
    Serial.println(F("Device was switched ON"));
    ONstatus = true;   // to ensure device is only turned ON once
    digitalWrite(16, HIGH); // send ON signal to relay     
  }

  if((Countdown == 0) && (ONstatus == true)&&(buttonState == HIGH)){
    Serial.println(F("Device is now OFF"));
    ONstatus = false;    // to ensure device is only turned OFF once
    digitalWrite(16, LOW); // send OFF signal to relay
  }
}

void setup(){      
  // initialize the LED pin as an output
  pinMode(ledPin, OUTPUT);
  
  // initialize the pushbutton pin as an input
  pinMode(buttonPin, INPUT);
  
  pinMode(16, OUTPUT);  // relay pin
  digitalWrite(16, LOW); // relay is OFF on reboot
  
  Serial.begin(115200); 
  Blynk.begin(auth, ssid, pass);
  timer.setInterval(1000L, runEverySecond);  // start the 1s timer function 

  yield();
}

void loop()
{
  Blynk.run();
  timer.run();
  
  buttonState = digitalRead(buttonPin);
  
  Blynk.virtualWrite(4,Countdown);  //blynk widget V4 for showing the remaining working time
  Blynk.virtualWrite(10,Totaltime); //blynk widget V10 for showing the remaining total time 
  
  if((Totaltime == 0)&& (ONstatus == true)){ // disconecting on timeout
    digitalWrite(16, LOW); // ensure relay is OFF
  }
  if((Totaltime == 0)&& (ONstatus == false)&&(Countdown>10)){ // keep conected
    digitalWrite(16, HIGH); // ensure relay is ON
  }
  
  
 // check if the pushbutton is pressed. If it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
     //turn LED on:
    digitalWrite(ledPin, LOW);
  } 
  else {
     //turn LED off:
    digitalWrite(ledPin, HIGH);
  }

}

Well, first off, this is not really a code fix it forum. We primarily work on assisting with Blynk related issues… and in your case, the first one to address is that there is too much happening in your void loop() all trying to run hundreds of times a second.

This is all you should really need in there…

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

You clearly have a timer setup… so why not have all the rest of the extraneous stuff in appropriately timed loops of their own?

Since you already have one physical button working, then simply code the 2nd one a simular way, but have it process a Blynk.syncVirtual(V9) command to act as if it was the V9 Widget Button that was pressed.

Thank you!! I am not happy with the loop either.
Now i am trying to figure how/where should i put the rest of the code now.
I have left the loop just with blynk and timer now.

I will try to sync the V9 with a physical button.Hopefully…

later edit:
Can someone point me in the right direction so i can format my output time as minutes:seconds?
I have cleared the code and now my void loop section is free :slight_smile:

This topic can be closed. Everything worked as suggested. Thank you!

I wrote a Countdown program for another user on Blynk earlier this year.

Be sure to scroll down as I made some extra code for it.

Not sure if its useful at all but its a working bit of code for Blynk.

Thank you Jamin. My project works now, but i cannot make it display my 2 timers as minutes:seconds.
I have tried to adapt void CountdownShowFormatted(int seconds) from your other post but i cannot make it work. Here is my actual working code.It dows everything as it should except for the unformated time display. I am using 2 gauges to show time(total/working) but i am not bound to them. If you will find time to have a look at it, i would really appreciate it. I just need help to include your CountdownShowFormatted into this code.

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>      // library for SimpleTimer       
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
#include <SPI.h>

char auth[] = "token";
char ssid[] = "ssid";
char pass[] = "pass";
        
TFT_eSPI tft = TFT_eSPI();    // Invoke library, pins defined in User_Setup.h
SimpleTimer timer;            // define a timer for use by SimpleTimer library

// constants
const int buttonPin = 15;     // countdown pushbutton / pin D8
const int buttonPin0 = 0;     // start pushbutton / pin D3
const int ledPin =  2;        // Built_IN LED pin / D4

// variables
int buttonState = 0;          // variable for reading the buttonPin status
int buttonState0 = 0;         // variable for reading the buttonPin status
int Totaltime=0;              // Global variable Total time
int Working=0;                // Global variable used and run EverySecond()
int Coin=0;                   //global variable for counting jetons
int Twork=0;                  //global variable for counting money
bool ONstatus  = false;       // variable to switch device ON and OFF

 BLYNK_WRITE(V0){             // Button for reset
 Working = 0;
 Totaltime = 0;
 Twork = 0;
 Coin=0;
 digitalWrite(16, LOW);       // send OFF signal to relay
 }

 BLYNK_WRITE(V10){            // Button for manual overide
 Working = Working+300;
 Totaltime = Totaltime+300;
 //Coin= Coin+30;
 //Twork= (Coin*15);
 digitalWrite(16, HIGH);      // send ON signal to relay
 Blynk.virtualWrite(V7,1023); //blynk led widget V7 = relay status
 }
  
void setup(){   
  Serial.begin(115200); 
  Blynk.begin(auth, ssid, pass, "mydomain.com");
  
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(ST7735_CYAN);
  tft.fillRect (5, 5, 150, 118, TFT_BLUE);

  timer.setInterval(1000L, runEverySecond);  // start 1.0s timer function 
  timer.setInterval(500L, runFaster);        // start 0.5s timer function 
  timer.setInterval(1000L, refresh);         // start tft refresh timer 
  timer.setInterval(200L, start);            // start the widgets refresh timer 

 
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);  // initialize pushbutton pin as input: Working
  pinMode(buttonPin0, INPUT); // initialize pushbutton pin0 as input: TOTALTIME/START
  
  pinMode(16, OUTPUT);        // relay pin / D0
  digitalWrite(16, LOW);      // relay is OFF on reboot
  Blynk.virtualWrite(V7,0);   // led widget V7 for relay status
  
}

void start(){
  buttonState = digitalRead(buttonPin);
  buttonState0 = digitalRead(buttonPin0);
  if (buttonState0 == LOW) { // check if pushbutton is pressed.If yes,buttonState is LOW 
    Working = (Working+10);
    Totaltime = (Totaltime+20);
    Coin = (Coin+1);
    Twork=(Coin*15);
    digitalWrite(16, HIGH); // send ON signal to relay
    Blynk.virtualWrite(V7,1023); // led widget V7 for relay status
  } 
  else {
    Working = (Working);
    Totaltime = (Totaltime);
    Coin = (Coin);
    Twork=Twork;
  }
}
  
void refresh(){
  
  tft.fillRect (80, 19, 60, 40, TFT_CYAN);
   tft.setTextColor(TFT_BLACK);
   tft.setCursor(88,27,4);
   tft.print(Working);

  
   tft.fillRect (80, 69, 60, 40, TFT_CYAN);
   tft.setCursor(88, 77, 4);
   // Set the font colour with no background
   tft.setTextColor(TFT_BLACK);
   tft.println(Totaltime);  
 
}

void runFaster(){                            // 0.5s refresh timer for widgets

  if((Totaltime == 0)&& (ONstatus == true)){ // disconecting on timeout
    digitalWrite(16, LOW);                   // ensure relay is OFF
    Blynk.virtualWrite(V7,0);                //blynk led widget V7 for relay status
  }
  if((Totaltime == 0)&& (ONstatus == false)&&(Working>10)){     // stay conected
    digitalWrite(16, HIGH);                  // ensure relay is ON
    Blynk.virtualWrite(V7,1023);             //blynk led widget V7 for relay status
  } 
}

void runEverySecond(){ // runs every second, do noting when Button#1 is not pressed
  
    if((Totaltime > 0)&& (ONstatus == true)){
    Totaltime--;       //  reduce Totaltime by 1 second, every second

  }  

    if((Working > 0)&& (ONstatus == true)&&(buttonState == HIGH)&&(Totaltime > 0)){
    Working--;         //  reduce Countdown by 1 second every second
   
  }  
  
  if((Working > 0) && (ONstatus == false)&&(buttonState == LOW)){
    //Serial.println(F("Device was switched ON"));
    ONstatus = true;        // to ensure device is only turned ON once
    // turn device ON
    digitalWrite(16, HIGH); // send ON signal to relay   
    Blynk.virtualWrite(V7,1023);  
  }

  if((Working == 0) && (ONstatus == true)&&(buttonState == HIGH)){
    ONstatus = false;      // to ensure device is only turned OFF once
    // turn device OFF
    digitalWrite(16, LOW); // send OFF signal to relay
    Blynk.virtualWrite(V7,0); //blynk led widget V7 for relay status
  }
  Blynk.virtualWrite(V1,Totaltime); //blynk widget V1 for remaining total time 
  Blynk.virtualWrite(V2,Working);   //blynk widget V2 for remaining working time  
  Blynk.virtualWrite(V3,Coin);      //blynk widget V3 for total coins
  Blynk.virtualWrite(V4,Twork);     //blynk widget V4 for power in wats
}

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

What was the compile error?

Jamin, last night i was able to make 1 of my 2 timers showing formated correctly on blynk app. After few hours…

Let me struggle some more, maybe i can do it alone. After all i have to learn from my mistakes.
Next step will be to display the formated time on my TFT also. But if i can make it on te app i think i can do it on tft also.

If i will get stuck i will write here again.

LATER EDIT: all done. both timers formated an both show formated in blynk app and on the tft display. Now i have to clean all this mess and i will post the final code.

2 Likes

Could you post the final script?

I will post it today when i get back home.

Later edit: here it is. You should ignore the TFT_eSPI if you will not have an LCD attached. I am sure it can be done more elegant but:

  1. i am not good enough
  2. it works and it serves my purpose
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>      // library for SimpleTimer       
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
#include <SPI.h>

char auth[] = "token";
char ssid[] = "ssid";
char pass[] = "pass";
const char* server  = "yourserver";
      
TFT_eSPI tft = TFT_eSPI();    // Invoke library, pins defined in User_Setup.h
SimpleTimer timer;            // define a timer for use by SimpleTimer library

// constants
const int buttonPin = 15;                // countdown pushbutton / pin D8
const int buttonPin0 = 0;                // start pushbutton / pin D3
const int ledPin =  2;                   // Built_IN LED pin / D4
const int   checkInterval = 10000;       //10 seconds

// variables
int buttonState = 0;         // variable for reading the buttonPin status
int buttonState0 = 0;        // variable for reading the buttonPin status
int Totaltime=0;             // Global variable Total time
int Working=0;               // Global variable Working time and run EverySecond()
int Coin=0;                  //global variable for counting coins
int Twork=0;                 //global variable for counting money

bool ONstatus  = false;      // variable to switch device ON and OFF

 BLYNK_WRITE(V0){             // Button for reset
 Working = 0;
 Totaltime = 0;
 Twork = 0;
 Coin=0;
 digitalWrite(16, LOW);       // send OFF signal to relay
 }

 BLYNK_WRITE(V10){            // Button for manual overide
 Working = (Working)+50;
 Totaltime = (Totaltime)+50;
 digitalWrite(16, HIGH);      // send ON signal to relay
 Blynk.virtualWrite(V7,1023); //blynk led widget V7 = relay status
 }
 
void blynkCheck() {
  if (WiFi.status() == 3) {
    if (!Blynk.connected()) {
      Serial.println("WiFi aquired, trying to reach the server...");
      Blynk.connect();
    }
  }
  if (WiFi.status() == 1) {
    Serial.println("No WiFi connection, going offline.");
  }
}

void setup(){   
  pinMode(buttonPin, INPUT);  // initialize pushbutton pin as input: Working
  pinMode(buttonPin0, INPUT); // initialize pushbutton pin0 as input: TOTALTIME/START
  pinMode(16, OUTPUT);        // relay pin / D0

  Serial.begin(115200); 
  WiFi.begin(ssid, pass);
  Blynk.config(auth, server);
  
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(ST7735_CYAN);
  tft.fillRect (5, 5, 150, 118, TFT_BLUE);
  
  timer.setInterval(1000L, runEverySecond);  // start 1.0s timer function 
  timer.setInterval(500L, runFaster);        // start 0.5s timer function 
  timer.setInterval(checkInterval, blynkCheck);
  timer.setInterval(200L, start);            // start the led refresh timer 

  digitalWrite(16, LOW);      // relay is OFF on reboot
  Blynk.virtualWrite(V7,0);   // led widget V7 for relay status
}

void FormatedTotaltime(int seconds) {
  long mins = 0;
  long secs = 0;
  String secs_o = ":";
  secs = seconds; // set the seconds remaining
  mins = secs / 60; //convert seconds to minutes
  secs = secs - (mins * 60); //display 59 secs max
  if (secs < 10) {
    secs_o = ":0";
  }

    Blynk.virtualWrite(V1, mins + secs_o + secs);   //blynk widget V1 for total time
   tft.fillRect (80, 25, 60, 40, TFT_CYAN);
   tft.setTextColor(TFT_BLACK);
   tft.setCursor(88,27,4);
   tft.print(mins + secs_o + secs);  
}
void FormatedWorking(int seconds) {
  long mins = 0;
  long secs = 0;
  String secs_o = ":";
  secs = seconds; // set the seconds remaining
  mins = secs / 60; //convert seconds to minutes
  secs = secs - (mins * 60); //display 59 secs max
  if (secs < 10) {
    secs_o = ":0";
  }
    Blynk.virtualWrite(V2, mins + secs_o + secs);   //blynk widget V2 for remaining working time
  tft.fillRect (80, 90, 65, 25, TFT_CYAN);
  tft.setCursor(89, 92, 4);
  tft.setTextColor(TFT_BLACK);
  tft.println(mins + secs_o + secs); 
}

void start(){
  buttonState = digitalRead(buttonPin);
  buttonState0 = digitalRead(buttonPin0);
  if (buttonState0 == LOW) { // check if pushbutton is pressed.If yes,buttonState is LOW 
    Working = (Working+10);
    Totaltime = (Totaltime+20);
    Coin = (Coin+1);
    Twork=(Coin*15);
    digitalWrite(16, HIGH); // send ON signal to relay
    Blynk.virtualWrite(V7,1023); // led widget V7 for relay status
  } 
  else {
    Working = (Working);
    Totaltime = (Totaltime);
    Coin = (Coin);
    Twork=Twork;
  }
}
  
void runFaster(){                            // 0.5s refresh timer for widgets
  if((Totaltime == 0)&& (ONstatus == true)){ // disconecting on timeout
    digitalWrite(16, LOW);                   // ensure relay is OFF
    Blynk.virtualWrite(V7,0);                //blynk led widget V7 for relay status
  }
  if((Totaltime == 0)&& (ONstatus == false)&&(Working>10)){     // stay on
    digitalWrite(16, HIGH);                  // ensure relay is ON
    Blynk.virtualWrite(V7,1023);             //blynk led widget V7 for relay status
  } 
}

void runEverySecond(){ // runs every second
  FormatedTotaltime(Totaltime);
  FormatedWorking(Working);
    if((Totaltime > 0)&& (ONstatus == true)){
    Totaltime--;       //  reduce Totaltime by 1 second, every second
  }  
    if((Working > 0)&& (ONstatus == true)&&(buttonState == HIGH)&&(Totaltime > 0)){
    Working--;         //  reduce working time by 1 second, every second
  }  
  
  if((Working > 0) && (ONstatus == false)&&(buttonState == LOW)){
    ONstatus = true;        // to ensure device is only turned ON once
    digitalWrite(16, HIGH); // send ON signal to relay   
    Blynk.virtualWrite(V7,1023);  
  }

  if((Working == 0) && (ONstatus == true)&&(buttonState == HIGH)){
    ONstatus = false;      // to ensure device is only turned OFF once
    digitalWrite(16, LOW); // send OFF signal to relay
    Blynk.virtualWrite(V7,0); //blynk led widget V7 for relay status
  }
  Blynk.virtualWrite(V3,Coin);      //blynk widget V3 for total coins
  Blynk.virtualWrite(V4,Twork);     //blynk widget V4 for power in wats
}

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

BLYNK_CONNECTED()
{
  Serial.println("Reconnected, syncing with cloud.");
  Blynk.syncAll();
}
1 Like