Timers using the time input widget

I will try

1 Like

Ok i have my 2 types of timers working. There is only 1 issue. When power is disconnected the timers sit in the Set state which is displayed via a LED widget with green colour. When in On state it should turn blue. When i go to the Time Input Widget and hit OK it reverts back into the correct mode ie if it should be on LED is blue and if it should be off LED is green. This is telling me I need force a syncvirtual of the Time Input Widget to somewhere. Any ideas anybody?

STANDARD TIMER on 1/day
/STIMER1////////////////////////////////////////////////////
BLYNK_WRITE(V87) //SWITCH WIDGET
{
  ST1Button = param.asInt();
  if (ST1Button == 1)
  {
    STimer1Active = true;
    timer.enable(S1);
    STimer1();
    ST1LED.setColor(Green);
    ST1LED.on();
  }
  else
  {
    STimer1Active = false;
    timer.disable(S1);
    ST1LED.off();
  }
}
   
BLYNK_WRITE(V47)  //TIME INPUT WIDGET
{
  TimeInputParam t(param);
  int Shour = t.getStartHour();
  int Smin = t.getStartMinute();
  int Ssec = t.getStartSecond();
  int Ehour = t.getStopHour();
  int Emin = t.getStopMinute();
  int Esec = t.getStopSecond();
  int dayadjust = -1;
  if (weekday() == 1)
  {
    dayadjust = 6;
  }
  if (t.isWeekdaySelected((weekday() + dayadjust)))
  {
    if (t.hasStartTime())
    {
      ST1 = (Shour*3600) + (Smin*60) + Ssec;   //Start time seconds
    }
    if (t.hasStopTime())
    {
      ET1 = (Ehour*3600) + (Emin*60) + Esec;    //End time seconds
    }
    for (int i = 1; i <=7; i++)
    {
      if (t.isWeekdaySelected(i))
      {
        //terminal.println(String("Day ") + i + " is selected");
      }
    }
  }
}

void STimer1()
{
  unsigned long TotalSec = ((hour()*3600) + (minute()*60) + second());
  if (STimer1Active)
  {
    if(STime1Update)
    {
      if (ST1 > ET1)          //Check for midnight correction if needed
      {
        ET1 = ET1 + 86400;    //Midnight correction
      }
      if (TotalSec >= ST1 && TotalSec <= ET1)
      {
        if (STime1Update)
        {
          STime1Update = false;
          master_slave4.digitalWrite(D1, HIGH);
          ST1LED.setColor(Blue);
          ST1LED.on();
          Serial.println("ON");
        }
        else
        {
          if (STime1Update == false)
          STime1Update = true;
          master_slave4.digitalWrite(D1, LOW);
          ST1LED.setColor(Green);
          ST1LED.on();
          Serial.println("OFF");
        }
      }
    }
  }
}

Add it after you’ve connected to Blynk, or add a BLYNK_CONNECTED() callback function and put your syncVirtual in there.

Pete.

Thanks

A thought just occured I think I will add Blynk Not Connected situation in case of a disconnection…if 1 of the timers is dosing a chemical during the disconnection it should stop until reconnected…avoid overdosing something and doing damage to the aquarium

1 Like

@PeteKnight just to clarify, I read through the blynk documents you linked to…so
Blynk.syncAll syncs all the settings stored on the Blynk server and Blynk.syncVirtual syncs from my app back to the server. With that said should we not be Blynk.syncVirtual on all the widgets which handle data? Otherwise when does Blynk.syncAll gets its data?

Blynk.syncAll is a bit of a sledgehammer approach, and can cause issues, so it’s best avoided if you can.

What Blynk.syncVirtual(VPin) does is to force the server to push its current saved value back to the device.
So, if you used the app to set V10 to 27 then this is the value stored on the server. It doesn’t matter if the app isn’t connected, the value of “27” is still stored on the server.
Blynk.syncVirtual(V10) will force the server to push that value to the device, triggering the BLYNK_WRITE(V10) callback.

You only need to do this for values that are stored on the server and that need to be pulled-back to the device after a reboot.

Pete.

1 Like

Thanks for that. It is now clear.

1 Like

@PeteKnight sorry to bother you again… is there a maximum limit as how many virtual pins you can syncVirtual? I have removed the Blynk.syncAll and adopted the Blynk.syncVirtual and i have noticed that it takes very much longer to connect to the Blynk server, sometimes up to 5mins!

Post your code and details of what widgets are attached to each of the virtual pins, and why each of them is being synched.

Pete.

Wow…that is going to be feat…the code is 2210 lines long divided into tabs!

I will see how I can compress as there are a lot of reps

Well, we at least need to see the bit where you’re doing the Blynk.syncVirtual, the Blynk connection and understand what BLYNK_WRITEs you have and what’s happening in each of them.

Pete.

Ok…here it is. I have removed all the reps and all the WiFi Manager stuff ect to make it shorter. Just to be clear I am not saying it does NOT CONNECT it does but takes up to 5 minutes before it does

//MASTER TAB//
/*BLYNK APP
 * V0-TIME
 * V1-DATE
 * V2-TANK TEMP
 * V3-HEATING ON
 * V4-CHILLER ON
 * V5-UV LED % BAR
 * V6-RBLUE/BLUE LED % BAR
 * V7-BLUE LED % BAR
 * V8-OCW LED % BAR
 * V9-LIME/AMBER LED % BAR
 * V10-MODE SWITCH (Manual/Auto)
 * V11-CH1 UV TIME SET
 * V12-CH1 UV FADEIN TIME
 * V13-CH1 UV FADEOUT TIME
 * V14-CH1 UV INTENSITY SETTING
 * V15-CH2 RBLUE/BLUE TIME SET
 * V16-CH2 RBLUE/BLUE FADEIN TIME
 * V17-CH2 RBLUE/BLUE FADEOUT TIME
 * V18-CH2 RBLUE/BLUE INTENSITY SETTING
 * V19-CH3 BLUE TIME SET
 * V20-CH3 BLUE FADEIN TIME
 * V21-CH3 BLUE FADEOUT TIME
 * V22-CH3 BLUE INTENSITY SETTING
 * V23-CH4 OCW TIME SET
 * V24-CH4 OCW FADEIN TIME
 * V25-CH4 OCW FADEOUT TIME
 * V26-CH4 OCW INTENSITY SETTING
 * V27-CH5 AMBER TIME SET
 * V28-CH5 AMBER FADEIN TIME
 * V29-CH5 AMBER FADEOUT TIME
 * V30-CH5 AMBER INTENSITY SETTING
 * V31-PH DATA FOR GRAPH
 * V32-CH1 UV LED WIDGET
 * V33-CH2 RBLUE/BLUE LED WIDGET
 * V34-CH3 BLUE LED WIDGET
 * V35-CH4 OCW LED WIDGET
 * V36-CH5 AMBER LED WIDGET
 * V37-TANK TEMP SET
 * V38-TANK TEMP DATA FOR GRAPH
 * V39-TERMINAL WIDGET
 * V40-SAFELED LED WIDGET
 * V41-CH5 LIME TIME SET
 * V42-CH5 LIME FADEIN TIME
 * V43-CH5 LIME FADEOUT TIME
 * V44-CH5 LIME INTENSITY SETTING
 * V45-LIME LED % BAR
 * V46-CH5 AMBER LED WIDGET
 * V47-STIMER1
 * V48-STIMER2
 * V49-STIMER3
 * V50-STIMER4
 * V51-MTIMER1 TIME INPUT WIDGET
 * V52-MTIMER1 DOSES/DAY WIDGET
 * V53-MTIMER1 DOSE DURATION WIDGET
 * V54-MTIMER1 SWITCH
 * V55-MTIMER2 TIME INPUT WIDGET
 * V56-MTIMER2 DOSES/DAY WIDGET
 * V56-MTIMER2 DOSE DURATION WIDGET
 * V58-MTIMER2 SWITCH
 * V60-DATA EXCHANGE S1
 * V61-DATA EXCHANGE S2
 * V62-BRIDGE WIDGET 1
 * V63-BRIDGE WIDGET 2   
 * V64-BRIDGE WIDGET 3
 * V65-BRIDGE WIDGET 4
 * V66-BRIDGE WIDGET 5
 * V71-MTIMER3 TIME INPUT WIDGET
 * V72-MTIMER3 DOSES/DAY WIDGET
 * V73-MTIMER3 DOSE DURATION WIDGET
 * V74-MTIMER3 SWITCH
 * V75-MTIMER4 TIME INPUT WIDGET
 * V76-MTIMER4 DOSES/DAY WIDGET
 * V77-MTIMER4 DOSE DURATION WIDGET
 * V78-MTIMER4 SWITCH
 * V79-STIMER1 LED
 * V80-STIMER2 LED
 * V81-STIMER3 LED
 * V82-STIMER4 LED
 * V83-MTIMER1 LED
 * V84-MTIMER2 LED
 * V85-MTIMER3 LED
 * V86-MTIMER4 LED
 */

//Blynk Master device Authorisation code : " 9b67012003144e4b874fa61a5e57e935 " //

//LIBRARIES//
       
//#include <FS.h>                   

#include <ESP8266WiFi.h>  
//#include <DNSServer.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
#include <OneWire.h>
#include <DallasTemperature.h>
//#include "DFRobot_PH.h"   //version2
//#include <EEPROM.h>       //version2
WidgetRTC rtc;
BlynkTimer timer;

WidgetLED ch1(V32); //LED WIDGET TO SHOW LED LIGHTING CHANNEL 1 IS SET

WidgetLED ST1LED(V79);  //LED WIDGET TO SHOW STANDARD TIMER IS ON/OFF

WidgetLED MT1LED(V83);  //LED WIDGET TO SHOW MULTIPLE TIMER IS ON/OFF

#define Green "#23C48E"  //LED WIDGET COLOUR GREEN SET NOT ON
#define Blue  "#04C0F8"   //LED WIDGET COLOUR BLUE ON

//PIN ASSIGNMENTS//
#define ONE_WIRE_BUS D1
#define PH_PIN A0           

//WIFI Variables
char auth[] =
char ssid[] = 
char pass[] =

//BRIDGE WIDGET//
WidgetBridge master_slave1(V62);   //Master/slave1 bridge - LED unit 1
WidgetBridge master_slave2(V63);   //Master/slave2 bridge - LED unit 2
WidgetBridge master_slave3(V64);   //Master/slave3 bridge - Chiller & Heater plugbar
WidgetBridge master_slave4(V65);   //Master/slave4 - Supplimentary plugbar1 4xSTimers
WidgetBridge master_slave5(V66);   //Master/slave5 - Supplimentary plugbar2 4xMTimers

//GLOBAL ATTRIBUTES & VARIABLES//
int BTNval;  //BUTTON WIDGET AUTO AND MANUAL MODES USED TO SET LEDS INITIALLY.

//PH CONTROL GLOBALS//
#define Offset -4.00            
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40 
int pHArray[ArrayLenth];
int pHArrayIndex=0;
static float pHValue,voltage;

//RTC & TIME IMPUT ATTRIBUTES & VARIABLES
char currentTime[9];    //RTC time
char currentDate[11];   //RTC date

//LED CHANNEL 1 TIME GLOBALS//
int SThour1;            //Time input widget
int STmin1;             //Time input widget
int STsec1;             //Time input widget
int SPhour1;            //Time input widget
int SPmin1;             //Time input widget
int SPsec1;             //Time input widget
int dayNumber1;         //Time input widget

//LED FADE ATTRIBUTES & VARIABLES//
//CHANNEL 1//
unsigned long CH1S;  //START TIME
unsigned long CH1E;  //END TIME
unsigned long FadeINmin1;
unsigned long FadeOUTmin1;
int maxPWM1;
int PWMinput1;

//NB!!!! THERE ARE 6 CHANNELS FOR LEDS//

//TEMPERATURE ATTRIBUTES & VARIABLES//
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float TankTempSet = 0;
float TankTemp = 0;

//MULTIPLE TIMER GLOBALS// THESE WORK: YOU SET TIME & DAY. THEY ACTIVATE ON AND OFF MULTIPLE TIMES DURING THE DAY IN ACCORDANCE WITH YOUR INPUT SETTINGS
enum MTimer1 {RESET1, ON, RESET2, OFF};  //STATE MACHINE STATES
MTimer1 state = RESET1;
int Doses1;  //NUMBER OF DOSES/DAY SET BY A NUMERIC INPUT WIDGET
unsigned long DoseTime1; //DOSE TIME SET BY A NUMERIC INPUT WIDGET
int MT1Button;  //BUTTON WIDGET TO ACTIVATE THE MULTIPLE TIMER FUNCTION. NEEDS TO BE 1 TO ACTIVATE

unsigned long MT1S;  //START TIME FOR MULTIPLE TIME SET BY TIME INPUT WIDGET
bool MT1active = false;
int M1;  //BLYNK TIMER VARIABLE FOR MULTIPLE TIMER1

long M1CountRemain; // COUNTDOWN TIMER FOR MULTIPLE TIMER

//STANDARD TIMER GLOBALS// THESE WORK: SET START/STOP/DAY REQUIRED. THEY WILL TURN OF 1/DAY AT SETTINGS INPUTTED.
bool STimer1Active = true;
unsigned long ST1;  //STANDARD TIME START TIME
unsigned long ET1;  //STANDARD STOP TIME
int S1; //VARIABLE FOR BLYNK TIMER
int ST1Button; //BUTTON WIDGET TO SET/ACTIVATE STANDARD TIMER

//CONNECT TO BLYNK SERVER//
BLYNK_CONNECTED()
{
  Blynk.syncVirtual(V10, V11, V12, V13, V14, V15, V16, V17, V18, 
  V19, V20, V21, V22, V23, V24, V25, V26, V27, V28, V29, V30, V41, 
  V42, V43, V44, V47, V48, V49, V50, V51, V52, V53, V54, V55, V56, 
  V57, V58, V71, V72, V73, V74, V75, V76, V77, V78, V87, V88, V89, V90);
  rtc.begin();
  master_slave1.setAuthToken("0d10d17a44c94f3795fd5d7c36206bf1");   //SLAVE 1 LED UNIT 1
  master_slave2.setAuthToken("b62b199dc066429e833baa753ea70dad");   //SLAVE 2 LED UNIT 2
  //master_slave3.setAuthToken("XXXXXXXXXXXXXX");   //SLAVE 3         //SLAVE 3 HEATER/CHILLER PLUGBAR
  //master_slave4.setAuthToken("XXXXXXXXXXXXXX");   //SLAVE 4         //SLAVE 4 STIMER PLUGBAR
  //master_slave5.setAuthToken("XXXXXXXXXXXXXX");   //SLAVE 5         //SLAVE 5 MTIMER PLUGBAR
}


void setup()
{
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  pinMode(ONE_WIRE_BUS, INPUT);
  pinMode(PH_PIN, INPUT);
  sensors.begin();
  setSyncInterval(30);
  timer.setInterval(1000L, ClockDisplay);
  timer.setInterval(2000L, TankTempControl);
  timer.setInterval(3000L, PHFunction);
  S1 = timer.setInterval(950L, STimer1);
  M1 = timer.setInterval(1000L, MTimer1);
  timer.disable(S1);  //DISABLE TIMER ON START UP
  timer.disable(M1);
}

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

}
//LED LIGHTING TAB//
BLYNK_WRITE(V10)   //BUTTON WIDGET USED TO SET THE LEDS. OFF POSITION IS MANUAL ON POSITION IS AUTO
{
  BTNval = param.asInt();
  master_slave1.virtualWrite(V25, BTNval); //SEND DATA TO BRIDGE
}

//CHANEL 1 UV///////////////////////////////////////////////////////////////////////////
BLYNK_WRITE(V11)  //CH1 TIME IMPUT WIDGET
{
  TimeInputParam t(param);
  SThour1 = t.getStartHour();
  STmin1 = t.getStartMinute();
  STsec1 = t.getStartSecond();
  SPhour1 = t.getStopHour();
  SPmin1 = t.getStopMinute();
  SPsec1 = t.getStopSecond();
  dayNumber1 = weekday();
  unsigned int OnDays1 = 0;
  for (int i = 1; i <= 7; i++)    //Process weekdays (1-Mon, 2-Tues, 3-Wed, 4-Thurs, 5-Fri, 6-Sat, 7-Sun)
  {
    if (t.isWeekdaySelected(i))
    {
      OnDays1++;
      if(i==dayNumber1)
      {
        master_slave1.virtualWrite(V1, 1);
      }
      if(t.hasStartTime())
      {
        CH1S = (SThour1*60) + STmin1;   //Start time min
        master_slave1.virtualWrite(V2, CH1S);  //SEND DATA TO BRIDGE
      }
      if(t.hasStopTime())
      {
        CH1E = (SPhour1*60) + SPmin1;    //End time min
        master_slave1.virtualWrite(V3, CH1E);  //SEND DATA TO BRIDGE
      }
    }
    if (OnDays1 == 0)
    {
      master_slave1.virtualWrite(V1, 0);  //SEND DATA TO BRIDGE
    }
  }
}

BLYNK_WRITE(V12)   //CH1 FADEIN TIME NUMERIC INPUT WIDGET
{
  FadeINmin1 = param.asInt();
  master_slave1.virtualWrite(V4, FadeINmin1); 
}

BLYNK_WRITE(V13)   //CH1 FADEOUT TIME NUMERIC INPUT WIDGET
{
  FadeOUTmin1 = param.asInt();
  master_slave1.virtualWrite(V5, FadeOUTmin1);
}

BLYNK_WRITE(V14)   //CH1 UV INTENSITY NUMERIC INPUT WIDGET
{
  PWMinput1 = param.asInt();
  maxPWM1 = map(PWMinput1, 0, 100, 0, 1023);
  master_slave1.virtualWrite(V6, FadeOUTmin1);   
}
//NB!!!6 OF THESE AS WELL//
//TIMERS TAB//
//STIMER1////////////////////////////////////////////////////
BLYNK_WRITE(V87) //BUTTON WIDGET
{
  ST1Button = param.asInt();
  if (ST1Button == 1)
  {
    STimer1Active = true;
    timer.enable(S1);
    STimer1();
    ST1LED.setColor(Green);
    ST1LED.on();
  }
  else
  {
    STimer1Active = false;
    timer.disable(S1);
    ST1LED.off();
  }
}
   
BLYNK_WRITE(V47)  //TIME INPUT WIDGET
{
  TimeInputParam t(param);
  int Shour = t.getStartHour();
  int Smin = t.getStartMinute();
  int Ssec = t.getStartSecond();
  int Ehour = t.getStopHour();
  int Emin = t.getStopMinute();
  int Esec = t.getStopSecond();
  int dayadjust = -1;
  if (weekday() == 1)
  {
    dayadjust = 6;
  }
  if (t.isWeekdaySelected((weekday() + dayadjust)))
  {
    if (t.hasStartTime())
    {
      ST1 = (Shour*3600) + (Smin*60) + Ssec;   //Start time seconds
    }
    if (t.hasStopTime())
    {
      ET1 = (Ehour*3600) + (Emin*60) + Esec;    //End time seconds
    }
    for (int i = 1; i <=7; i++)
    {
      if (t.isWeekdaySelected(i))
      {
        //terminal.println(String("Day ") + i + " is selected");
      }
    }
  }
}

void STimer1()
{
  unsigned long TotalSec = ((hour()*3600) + (minute()*60) + second());  //NOW TIME
  if (STimer1Active)
  {
    if(STime1Update)
    {
      if (ST1 > ET1)          //Check for midnight correction if needed
      {
        ET1 = ET1 + 86400;    //Midnight correction
      }
      if (TotalSec >= ST1 && TotalSec <= ET1)
      {
        if (STime1Update)
        {
          STime1Update = false;
          master_slave4.virtualWrite(D1, 1);
          ST1LED.setColor(Blue);
          ST1LED.on();
          Serial.println("ON");
        }
        else
        {
          if (STime1Update == false)
          STime1Update = true;
          master_slave4.virtualWrite(D1, 0);
          ST1LED.setColor(Green);
          ST1LED.on();
          Serial.println("OFF");
        }
      }
    }
  }
}
//MTIMER1////////////////////////////////////////////////////
BLYNK_WRITE(V51)            //Time input    
{
  TimeInputParam t(param);
  int Shour = t.getStartHour();
  int Smin = t.getStartMinute();
  int Ssec = t.getStartSecond();
  int Ehour = t.getStopHour();
  int Emin = t.getStopMinute();
  int Esec = t.getStopSecond();
  int dayadjust = -1;
  if (weekday() == 1)
  {
    dayadjust = 6;
  }
  if (t.isWeekdaySelected((weekday() + dayadjust)))
  {
    if (t.hasStartTime())
    {
      MT1S = (Shour*3600) + (Smin*60) + Ssec;   //Start time seconds
    }
    for (int i = 1; i <=7; i++)
    {
      if (t.isWeekdaySelected(i))
      {
        //terminal.println(String("Day ") + i + " is selected");
      }
    }
  }
}

BLYNK_WRITE(V52)          //Doses/Day
{
  Doses1 = param.asInt();
}

BLYNK_WRITE(V53)        //Dose duration in seconds 3-240
{
  DoseTime1 = param.asInt();
}

BLYNK_WRITE(V54)        //Activate MTimer
{
  MT1Button = param.asInt();
  {
    if (MT1Button == 1)
    {
      MTimer1();
      timer.enable(M1);
      MT1LED.setColor(Green);
      MT1LED.on();
    }
    else
    {
      timer.disable(M1);
      MT1LED.off();
    }
  }
}

void MTimer1()
{
  unsigned long TotalSec = ((hour()*3600) + (minute()*60) + second());
  unsigned long doseInt = ((86400 - (Doses1 * DoseTime1)) / Doses1);
  Serial.println(doseInt);
  if ((TotalSec >= MT1S) && (TotalSec <= (MT1S - MT1S) + 86400))   //Time to start timer & add a day if start up is before Start time
  switch (state)
  {
    case RESET1:
    {
      if (M1CountRemain != DoseTime1)
        {
          M1CountRemain = DoseTime1;
          M1FormattedON(M1CountRemain);
          timer.enable(M1);
          state = ON;
          Serial.println("RESET1");
        }
        break;
       }
            
    case ON:
    {
      if (M1CountRemain)
      {
        M1CountRemain--;
        M1FormattedON(M1CountRemain);
        master_slave5.virtualWrite(D1, 1);
        MT1LED.setColor(Blue);
        MT1LED.on();    //On period
        Serial.println("ON");
      }
      if (M1CountRemain == 0)
      {
        state = RESET2;
      }
      break;
    }
      
    case RESET2:
    {
      if (M1CountRemain != doseInt)
      {
        M1CountRemain = doseInt;
        Serial.println(doseInt);
        M1FormattedOFF(M1CountRemain);
        timer.enable(M1);
        state = OFF;
         Serial.println("RESET2");
      }
      break;
    }

    case OFF:
    {
      if (M1CountRemain)
      {
        M1CountRemain--;
        M1FormattedOFF(M1CountRemain);
        master_slave5.virtualWrite(D1, 0);
        MT1LED.setColor(Green);
        MT1LED.on();    //Off period
        Serial.println("OFF");
      }
      if (M1CountRemain == 0)
      {
        state = RESET1;
      }
    break;
    }
  }
}
//RTC TAB//
void ClockDisplay()
{
  sprintf(currentTime, "%02d:%02d:%02d", hour(), minute(), second());
  sprintf(currentDate, "%02d/%02d/%04d", day(), month(), year());

  Blynk.virtualWrite(V0, currentTime);    //Send time to TIME widget
  Blynk.virtualWrite(V1, currentDate);    //Send date to DATE widget
  Blynk.virtualWrite(V47, day());
}

void M1FormattedON(long seconds) //On period
{
  long days = 0;
  long hours = 0;
  long mins = 0;
  long secs = 0;
  String secs_o = ":";
  String mins_o = ":";
  String hours_o = "";
  secs = seconds;
  mins = secs / 60;
  hours = mins / 60;
  days = hours / 24;
  secs = secs - (mins * 60);
  mins = mins - (hours * 60); 

  if (secs < 10)
  {
    secs_o = ":0";
  }
  if (mins < 10) {
    mins_o = ":0";
  }
  if (hours < 10) {
    hours_o = "0";
  }
  Blynk.virtualWrite(V91, "DOSING " + hours_o + hours + mins_o + mins + secs_o + secs);
}

void M1FormattedOFF(long seconds)   //Off period
{
  long days = 0;
  long hours = 0;
  long mins = 0;
  long secs = 0;
  String secs_o = ":";
  String mins_o = ":";
  String hours_o = "";
  secs = seconds;
  mins = secs / 60;
  hours = mins / 60;
  days = hours / 24;
  secs = secs - (mins * 60);
  mins = mins - (hours * 60); 

  if (secs < 10)
  {
    secs_o = ":0";
  }
  if (mins < 10) {
    mins_o = ":0";
  }
  if (hours < 10) {
    hours_o = "0";
  }
  Blynk.virtualWrite(V91, "NEXT DOSE " + hours_o + hours + mins_o + mins + secs_o + secs);
}

Sorry forgot to mention the reason behind syncing the pins is to avoid the issue of a power failure or reboot and the programme not starting of from where it should be. I noticed this with the Time Input Widget which needs to be re-OKed.

And does this actually work, are all of the variables synched correctly when the device does connect?

You’re trying to get 50 items to sync at the same time, which could mean that you run into some issues.

Personally, I think you’ve added far to many controls to your app for it to be really useable. Once you’ve established the basic operating parameters then all you should really need to do is tweak a couple of controls and your timers.

Looking at the complexity of the project, with multi devices and the wide arange of parameters to be controlled, I would have used Node-Red and MQTT as the basis for the project, as it simplifies all of the bridging and allows you to tweak parameter values without the need to re-load code. It also overcomes the issues of needing to sync so much data with Blynk if you use retained MQTT messages.

Pete.

Yes it does work when it gets connected. I do not know Node-Red I will have to look into that

Take a look here:

Pete.

I don’t know if this made the difference or not but I split the Blynk.sync like this
Blynk.sincvirtual(1, 2, 3, 4, 5, 6,);
Blynk.sincvirtual(7, 8, 9, 10, 11);
ect…
ect…
And connection is much faster now

I hope you are using the correct syntax and spelling in your code :stuck_out_tongue:

Yes, just the fact that you are splitting up into multiple group commands will allow the syncing to happen in stages… still fast, yes, but at least not all simultaneously.