CountDown not counting down

Dear Blynkers,
I wracked my head around this issue but cant seem to get it to work. I have a CountDown function which takes 2 parameters, CountLimit which is defined in the variables statements in the initial part of the sketch and CountRemain which gets its value from the CountLimit minus millis().
The function has a timer interval set 50L in the setup. The correct value shows up on the diplay widget but it does not count down.
Any ideas anyone?

Simply paste your code between ``` If you don’t format your code, your topic can be deleted by moderators.

//COUNTDOWN TIMER VARIABLES//

char count[9];
#define totalSec(_time_) (_time_ % SECS_PER_MIN)  
#define totalMin(_time_) ((_time_ / SECS_PER_MIN) % SECS_PER_MIN) 
#define totalHr(_time_) (( _time_% SECS_PER_DAY) / SECS_PER_HOUR)

unsigned long CountLimit1 = DeGasOn1 / 1000;     //Millis > Seconds 
unsigned long CountLimit2 = DeGasOn2 / 1000;     //Millis > Seconds 
unsigned long CountLimit3 = DeGasOn3 / 1000;     //Millis > Seconds 
unsigned long CountLimit4 = DeGasOn4 / 1000;     //Millis > Seconds 
unsigned long CountLimit5 = DeGasOn5 / 1000;     //Millis > Seconds 
unsigned long CountLimit6 = DeGasOn6 / 1000;     //Millis > Seconds
unsigned long CountRemain; 
void setup()
{
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  // You can also specify server:
  //Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
  //Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);
  pinMode(CircPin, OUTPUT);
  pinMode(FeedPin, OUTPUT);
  pinMode(CO2Pin, OUTPUT);
  pinMode(SensorPin, INPUT);
  pinMode(LedCO2, OUTPUT);
  pinMode(LedFeed, OUTPUT);
  pinMode(LedCirc, OUTPUT);
  setSyncInterval(50);
  timer.setInterval(1000L, ClockDisplay);
  timer.setInterval(50L, RunStateMachine);
  timer.setInterval(50L, CountDown);

}
BLYNK_WRITE(V2)   
{
  DegasPd = param.asInt();
  Blynk.virtualWrite(V3, DegasPd);    //Send value to gauge display
}

BLYNK_WRITE(V4)   //Numeric Input Widget
{
  CalcSt = (param.asFloat()*100);
  CycleTime = map(CalcSt, 0, 10, 0, 30000);
  Blynk.virtualWrite(V5, (CalcSt/100));           //Send value to gauge display
  Serial.print(CalcSt/100);
  Serial.print(" : " );
  Serial.println();
}
void CountDown()
{
  unsigned long ts;
  ts = millis() / 1000;
  
  if ((CountRemain >= 0)&&(DegasPd == 1))
  {
    CountRemain = CountLimit1 - ts;
    int Sec = totalSec(CountRemain);
    int Min = totalMin(CountRemain);
    int Hr = totalHr(CountRemain);
    CountRemain = CountLimit1 - ts;
    sprintf(count, "Next DeGas In %02d:%02d:%02d", Hr, Min, Sec);
    Blynk.virtualWrite(V6, count);
    Serial.println(" Degas " );
    Serial.print(DegasPd);
  }
  else if ((CountRemain >= 0)&&(DegasPd == 2))
  {
    CountRemain = CountLimit2 - ts;
    int Sec = totalSec(CountRemain);
    int Min = totalMin(CountRemain);
    int Hr = totalHr(CountRemain);
    CountRemain = CountLimit2 - ts;
    sprintf(count, "Next DeGas In %02d:%02d:%02d", Hr, Min, Sec);
    Blynk.virtualWrite(V6, count);
    Serial.println(" Degas " );
    Serial.print(DegasPd);
  }
  else if ((CountRemain >= 0)&&(DegasPd == 3))
  {
    CountRemain = CountLimit3 - ts;
    int Sec = totalSec(CountRemain);
    int Min = totalMin(CountRemain);
    int Hr = totalHr(CountRemain);
    CountRemain = CountLimit3 - ts;
    sprintf(count, "Next DeGas In %02d:%02d:%02d", Hr, Min, Sec);
    Blynk.virtualWrite(V6, count);
    Serial.println(" Degas " );
    Serial.print(DegasPd);
  }
  else if ((CountRemain >= 0)&&(DegasPd == 4))
  {
    CountRemain = CountLimit4 - ts;
    int Sec = totalSec(CountRemain);
    int Min = totalMin(CountRemain);
    int Hr = totalHr(CountRemain);
    CountRemain = CountLimit4 - ts;
    sprintf(count, "Next DeGas In %02d:%02d:%02d", Hr, Min, Sec);
    Blynk.virtualWrite(V6, count);
    Serial.println(" Degas " );
    Serial.print(DegasPd);
  }
  else if ((CountRemain >= 0)&&(DegasPd == 5))
  {
    CountRemain = CountLimit5 - ts;
    int Sec = totalSec(CountRemain);
    int Min = totalMin(CountRemain);
    int Hr = totalHr(CountRemain);
    CountRemain = CountLimit5 - ts;
    sprintf(count, "Next DeGas In %02d:%02d:%02d", Hr, Min, Sec);
    Blynk.virtualWrite(V6, count);
    Serial.println(" Degas " );
    Serial.print(DegasPd);
  }
  else if ((CountRemain >= 0)&&(DegasPd == 6))
  {
    CountRemain = CountLimit6 - ts;
    int Sec = totalSec(CountRemain);
    int Min = totalMin(CountRemain);
    int Hr = totalHr(CountRemain);
    CountRemain = CountLimit6 - ts;
    sprintf(count, "Next DeGas In %02d:%02d:%02d", Hr, Min, Sec);
    Blynk.virtualWrite(V6, count);
    Serial.println(" Degas " );
    Serial.print(DegasPd);
  }
}

These are both starting, and thus trying to run their functions, at the exact same time every 50 ms.

Try staggering them apart a bit and see if that helps.

timer.setInterval(50L, RunStateMachine); 
delay(25);
timer.setInterval(50L, CountDown);

No it does not. It was set at 1000 before i was just trying to experiment there if it would help and forgot to change back to 1000

Regardless then… stagger all the timers so they don’t try to run multiple functions concurrently.

Ok. But looking at my extracted code now above it has just dawned on me the math to do the CountRemain is after the if condition, so how does the CountRemain in the if condition know its value? I think this could be the issue. I will try tomorrow. What do you think?

I am trying to make a set of countdown timers which will run depending on the input of a numeric input widget. The code is based on code written by Jamin but i just cannot seem to get it to work. can somebody please look over the code and point me where i am going wrong.

#define BLYNK_PRINT Serial


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

unsigned long Sec = 1000UL;
unsigned long Min = Sec*60;
unsigned long Hr = Min*60;
unsigned long Dy = Hr*24;
unsigned long LastDeGas = 0;
unsigned long DeGasOff = Min*3;
unsigned long DeGasOn1 = Dy;
unsigned long DeGasOn2 = Dy/2;
unsigned long timeRemain;
unsigned long CountdownMillis;
unsigned long ts;

int CountdownRemainReset;
unsigned long CountdownRemain;
//unsigned long CountdownRemain2;

int CDT;
int Ts;

char auth[] = "";

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

BlynkTimer timer;

//CONNECT TO BLYNK SERVER//
BLYNK_CONNECTED()
{
  Blynk.syncAll();
}

void setup()
{
  // Debug console
  Serial.begin(9600);

  Blynk.begin(auth, ssid, pass);
  CDT = timer.setInterval(500, CountDown);

}

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

BLYNK_WRITE(V1) 
{
  Ts = param.asInt();   //Numeric input widget to determine which timer to run (2 timers)
  Blynk.syncVirtual(V1);
}

void CountDown()
  {
    if (Ts == 1)
        {
          CountdownMillis == DeGasOn1;     //Day in millis
          CountdownRemain == CountdownMillis/1000;    //convert millis to seconds
        if (CountdownRemain > 0)
        {
          CountdownRemain--;
          CountdownShowFormatted(CountdownRemain);    //Format seconds into Hr:Min:Sec
          Serial.print("DeGasOn1   ");
          Serial.println(DeGasOn1);
          Serial.print("Countdown   ");
          Serial.println(CountdownRemain);
          Serial.print("Period   ");
          Serial.println(Ts);
        }
        else if (CountdownRemain == 0);
        {
          ts=millis();
          if (millis() - ts <= 30000)
          {
            //DO NOTHING FOR NOW UNTIL MORE CODE IS PUT HERE
          }
        }
        }
        else if (Ts == 2)
        {
          CountdownMillis == DeGasOn2;
          CountdownRemain == CountdownMillis/1000;
          if (CountdownRemain > 0)
          {
          CountdownRemain--;
          CountdownShowFormatted(CountdownRemain);
          Serial.print("DeGasOn2   ");
          Serial.println(DeGasOn2);
          Serial.print("Countdown   ");
          Serial.println(CountdownRemain);
          Serial.print("Period   ");
          Serial.println(Ts);
          }
          else if (CountdownRemain == 0);
          {
          ts=millis();
          if (millis() - ts <= 30000)
          {
            //DO NOTHING FOR NOW.....
          }
          }
        }
  }
          

void CountdownShowFormatted(int seconds) 
{
  long days = 0;
  long hours = 0;
  long mins = 0;
  long secs = 0;
  String secs_o = ":";
  String mins_o = ":";
  String hours_o = "";
  secs = seconds; // set the seconds remaining
  mins = secs / 60; //convert seconds to minutes
  hours = mins / 60; //convert minutes to hours
  days = hours / 24; //convert hours to days
  secs = secs - (mins * 60); //subtract the coverted seconds to minutes in order to display 59 secs max
  mins = mins - (hours * 60); //subtract the coverted minutes to hours in order to display 59 minutes max
  hours = hours - (days * 24); //subtract the coverted hours to days in order to display 23 hours max
  if (secs < 10) {
    secs_o = ":0";
  }
  if (mins < 10) {
    mins_o = ":0";
  }
  if (hours < 10) {
    hours_o = "0";
  }
  Blynk.virtualWrite(V0, hours_o + hours + mins_o + mins + secs_o + secs);

}

What exactly does that mean?

Pete.

It does not register the time it should countdown from nor does it count down. What should happen is

  1. if I input from the widget the number 1 I should get to the if statement (Ts == 1)

  2. The time which is given in the declared variables by DeGas1 is converted to seconds.

  3. This is then converted to hrs : Mins : Secs by void CountdownShowFormatted()

  4. Count down timer should start to countdown.

I think this may be your problem.

== is for comparisons.
= is for setting values.

And because CountdownRemain initialises as 0, it will never get into this if statement because the value is never updated.

if (CountdownRemain > 0) {
1 Like

Please don’t create a 2nd topic for your same issue. I have merged both together.

@JustBertC I changed the items you suggested and I now get the correct value for the initial countdown, but it does not count down!!

Depending on what you have done/changed it won’t. I guess you have just changed == to =. In which case every time TS==1 and you code goes into the if statement the counter will get reset to the initial value every time.

You need to move the initial setting of the variables outside of your if statement. Maybe put them into the BLYNK_WRITE function?

you are right , this is the problem !
also in

else if (Ts == 2)
CountdownMillis == DeGasOn2;
CountdownRemain == CountdownMillis/1000;
BLYNK_WRITE(V1) 
{
  Ts = param.asInt();   //Numeric input widget to determine which timer to run (2 timers)
 
 Blynk.syncVirtual(V1);// <<<<<<<<<<<<<<<<<<<<<<<
}

and that’s not a good idea, I think it creates an infinite loop

1 Like

Just to clarify how the single and double quotes work…

x=1 This assigns the value of 1 to the variable x

if(x==1) This tests if the value of the variable x is equal to 1

Pete.

2 Likes

Thanks I will try all the above recommendations and let you know

2 Likes

just a question :
why do you use numeric input widget instead of button ? :thinking:

because eventually if I get it working there will be 6 countdown timers, so the numeric input widget will be the switch will be the method of choosing which timer is active

2 Likes

You could use a segmented switch instead.

Pete.

segmented switch is so ugly :rofl:
better use 2 styled buttons

1 Like

Anyway I have tried all the options and just cant get it to work. I found a library called countimer which works perfectly, which is kinda sad as I think libraries tend to evade the problems and you don’t learn.
but hey…at least it is working

1 Like