Time Input Sync after drop in connection

This is how I do it

void SetLed(int pin,
            unsigned long time,       //Current time in millis
            unsigned long start,      //Start time of LED channel
            unsigned long fadeup,     //Fadeup period in millis
            unsigned long period,     //Total photo period
            unsigned long fadedown,   //Fadedown period in millis
            unsigned long stop,       //Stop time of LED channel
            float pwm,                //Max value of brightness
            int Vpin)                 //ProgressBar
{
  //ON PERIOD//
  if (time > start + fadeup && time <= start + period - fadedown)
  {
    analogWrite(pin, pwm);
    int progress = round((pwm*100)/1023);
    Blynk.virtualWrite (Vpin, progress);   
  }
  //FADEUP PERIOD//
  else if (time > start && time <= start + fadeup)
  {
    float brightness;
    brightness = map(time - start, 0, fadeup, 0, pwm);
    analogWrite(pin, brightness);
    int progress = round((brightness*100)/1023);
    Blynk.virtualWrite (Vpin, progress);   
  }
  //FADEDOWN PERIOD//
  else if (time > start + period - fadedown && time <= start + period)
  {
    float brightness;
    brightness = map(time - start - period + fadedown, 0, fadedown, pwm, 0);
    analogWrite(pin, brightness);
    int progress = round((brightness*100)/1023);
    Blynk.virtualWrite (Vpin, progress);   
  }
  //OFF PERIOD//
  else if (time > stop || time < start)
  {
    analogWrite(pin, 0);
    Blynk.virtualWrite(Vpin, 0);
  }
}
2 Likes

I am using my phone for the above so I cant find the triple back ticks

I guessed it !!

" ``` "
:point_up_2: if you want to copy the back ticks

I didn’t suggest that a timer should be used to trigger the Blynk.syncVirtual call(s).
The way to do it is to use the BLYNK_CONNECTED callback function to trigger the synchronisation whenever the device reconnects to Blynk.

Pete.

1 Like

:point_up_2: Was your suggestion, sorry for the confusion.

Hello !!
I firstly dont know whether to ask this doubt\problem here or create a new topic, but as this related to Time input widget i feel i can post this here… if not please tell me i will create a new topic …

The problem is i am trying to read the t.isWeekdaySelected out side the BLYNK_WRITE function. TimeInputParam t(param); as this can only be called inside BLYNK_WRITE… As i am not a coder i think i have failed to explain properly, But i want to see the days selected in a void function…

But i found a post where @Gunner told to do so :point_down:

bool Mon;
bool Tue;
bool Wed;
bool Thu;
bool Fri;
bool Sat;
bool Sun;

And later check the if the days has been selected

BLYNK_WRITE(V1) {  // Called whenever setting Time Input Widget
  TimeInputParam t(param);

  Mon = t.isWeekdaySelected(weekday(1)); // Check if Monday is selected or not (1 = Yes, 0 = No)
  Tues = t.isWeekdaySelected(weekday(2));
  Wed = t.isWeekdaySelected(weekday(3));
  Thu = t.isWeekdaySelected(weekday(4));
  Fri = t.isWeekdaySelected(weekday(5));
  Sat = t.isWeekdaySelected(weekday(6));
  Sun = t.isWeekdaySelected(weekday(7));
}

Later checking if the days are selected

void checkdays1() {
  if (Mon == 1) {
    TimeCheck1();
  } else if (Tues == 1) {
    TimeCheck1();
  } if (Wed == 1) {
    TimeCheck1();
  } else if (Thu == 1) {
    TimeCheck1();
  } if (Fri == 1) {
    TimeCheck1();
  } else if (Sat == 1) {
    TimeCheck1();
  } if (Sun == 1) {
    TimeCheck1();
  }
}

Every things seems to work properly !! But when i select only a single day ex: Sat… I does not trigger the event… But if a select Fri , Sat, Sun then it will trigger…

Can someone tell me where am i going wrong ?? @proietti @PeteKnight

How to assign the 'time input' param to a global var

I’d start by putting some serial print statements in your code, so that you can see the value of your variables and monitor the program flow through the if/else statements.

Pete.

Okay i did what you said and yes even though i select a single day or all days, it is selecting all days
Serial monitor output

Mon selected
Tue selected
Wed selected
Thu selected
Fri selected
Sat selected
Sun selected

I am not understanding how to read the days selected from Blynk App !!

I think we’d need to see your full code to be able to provide more specific feedback.

Pete.

Here is the code

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#define BLYNK_PRINT Serial
#include <TimeLib.h>
#include <WidgetRTC.h>
WidgetRTC rtc;
BlynkTimer timer;

bool MonWeekDay;
bool TuesWeekDay;
bool WedWeekDay;
bool ThuWeekDay;
bool FriWeekDay;
bool SatWeekend;
bool SunWeekend;

char ssid[] = "xxxxxxxxx";
char auth[] = "xxxxxxx";
char pass[] = "xxxxxxxx" ; 


void setup(){
  Serial.begin(115200);  // Debug console
  Blynk.begin(auth, ssid, pass);
  setSyncInterval(100);
  rtc.begin();
  timer.setInterval(10000L, checkdays);
}

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

BLYNK_WRITE(V1) {  // Called whenever setting Time Input Widget
  TimeInputParam t(param);

  MonWeekDay = t.isWeekdaySelected(weekday(1));// Check if Monday is selected or not (1 = Yes, 0 = No)
  TuesWeekDay = t.isWeekdaySelected(weekday(2));
  WedWeekDay = t.isWeekdaySelected(weekday(3));
  ThuWeekDay = t.isWeekdaySelected(weekday(4));
  FriWeekDay = t.isWeekdaySelected(weekday(5));
  SatWeekend = t.isWeekdaySelected(weekday(6));
  SunWeekend = t.isWeekdaySelected(weekday(7));
}

void checkdays() {
  if (MonWeekDay == 1) {
    Serial.println("Mon Selected");
  } else if (TuesWeekDay == 1) {
    Serial.println("Tue Selected");
  } if (WedWeekDay == 1) {
    Serial.println("Wed Selected");
  } else if (ThuWeekDay == 1) {
    Serial.println("Thu Selected");
  } if (FriWeekDay == 1) {
    Serial.println("Fri Selected");
  } else if (SatWeekend == 1) {
    Serial.println("Sat Selected");
  } if (SunWeekend == 1) {
    Serial.println("Sun Selected");
  }
}

first i would like to read the input from the app side… later i will call the function on what to do if the condition is met…

Are you sure this syntax is correct?
I would have expected this:
MonWeekDay = t.isWeekdaySelected(1);

Pete.

:thinking::thinking: now you are putting me in more confusion :joy:
Can you please tell if that is wrong ??

for (int i = 1; i <= 7; i++) {
    if (t.isWeekdaySelected(i)) {
      Serial.println(String("Day ") + i + " is selected");

t.isWeekdaySelected(x) is an array with seven members, numbered 1-7.

For each member of he array you are trying to find the value (true or false) but you’re trying to use an array called weekday(x) to select each of the members of the t.isWeekdaySelected() array.

t.isWeekdaySelected(weekday(1))
versus
t.isWeekdaySelected(1)

Can you see the difference?

Pete.

:man_facepalming:
I always feel dumb in this forum !!
ok Now changed to

  MonWeekDay = t.isWeekdaySelected(1);// Check if Monday is selected or not (1 = Yes, 0 = No)
  TuesWeekDay = t.isWeekdaySelected(2);
  WedWeekDay = t.isWeekdaySelected(3);
  ThuWeekDay = t.isWeekdaySelected(4);
  FriWeekDay = t.isWeekdaySelected(5);
  SatWeekend = t.isWeekdaySelected(6);
  SunWeekend = t.isWeekdaySelected(7);

I have serial print out put as selected in the app

[760515] Time sync: OK
Wed V1

if i select multiple days it will reflect on the serial monitor…
But the problem is if i set the time and select monday it will trigger the function even though today is saturday :roll_eyes:

EDIT
Because as soon as i select Mon in the app it will send 1 and the condition is met. So the function will be triggered !! :man_facepalming:

Is there a way to trigger only on selected days ?

Your void checkdays function contains a three if/else pairs, and a stand-alone if statement.

Take a look at this if/else pair…

  if (MonWeekDay == 1) {
    Serial.println("Mon Selected");
  } else if (TuesWeekDay == 1) {
    Serial.println("Tue Selected");

If just Monday or just Tuesday we’re selected then the correct result would be printed to the serial monitor.
However, if both Monday and Tuesday were selected then only Monday would print to the serial monitor.

If you had 7 single if statements then the correct results would be printed in the serial monitor.

However, you don’t currently have any functionality to use these Boolean values in any sensible way (other than printing something to the serial monitor).

Also, you don’t have to use the “==1” bit of the if statement. Simply saying if (logical test) is enough.

I’d write the statement like this…

void checkdays() 
{
  if (MonWeekDay) 
  {
     Serial.println("Mon Selected");
  }

  if (TuesWeekDay) 
  {
     Serial.println("Tue Selected");
  }

  if (WedWeekDay) 
  {
     Serial.println("Wed Selected");
  }

  if (ThuWeekDay) 
  {
     Serial.println("Thu Selected");
  }

  if (FriWeekDay) 
  {
     Serial.println("Fri Selected");
  }

  if (SatWeekend)
  {
     Serial.println("Sat Selected");
  }

  if (SunWeekend)
  {
     Serial.println("Sun Selected");
  }
}

Pete.

Yes this did not work… so i changed to

if (MonWeekDay == 1) {
     Serial.println("Mon V1");
  } else {
  Serial.println("Nothing to do mon");

But the problem is as soon as we select the day required on the app it sends 1 and the condition will be met… if the app had sent 1 only at ex: 12:00AM of monday then it would have worked as i am thinking !! But now it sends 1 as soon i select the day !!

I don’t have time to stay here for longer to read and understand this thread, but I’ve experienced long time ago some thing similar to this.
This is a snippet of code, can you look at it to see if there anything similar to what you’re looking for.


int isTimeInputActivated(const unsigned int scheduleNo, int &lastAction, const TimeInputParam t)
{
  int startseconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60) + t.getStartSecond();  
  int stopseconds  = (t.getStopHour() * 3600) + (t.getStopMinute() * 60) + t.getStopSecond();

  //In case of inactive timer 
  if (startseconds == stopseconds)
    return DO_NOTHING;
    
  int retVal = DO_NOTHING;
  int nowseconds   = ((hour() * 3600) + (minute() * 60) + second());

  int blynkWeekDay = weekday();
  
  if(blynkWeekDay == 1)
    blynkWeekDay = 7; // needed for Sunday Time library is day 1 and Blynk is day 7
  else
    blynkWeekDay--;
    
  if (t.isWeekdaySelected(blynkWeekDay))  
  { 
    //Time library starts week on Sunday, Blynk on Monday  
    //Schedule is ACTIVE today 
    if ((lastAction != TURN_ON) && (nowseconds >= (startseconds - (BLYNK_SCHEDULE_ACCURACY + 1)) && nowseconds <= (startseconds + BLYNK_SCHEDULE_ACCURACY)))
    { 
      #if (DEBUG_BLYNK_RTC > 0)  
        sprintf(activatedTime, "%s %02d/%02d/%04d", dayOfWeek[weekday()-1], day(), month(), year());              
        Serial.printf("Schedule %d started at %s on %s\n", scheduleNo, currentTimeAM_PM(currentTime), activatedTime);
      #endif
      retVal = TURN_ON;
      
      #if (DEBUG_BLYNK_RTC > 1)
        Serial.printf("Last Action = %s, Action = %s, Now = %d, startsec = %d, stopsec = %d\n", 
                      lastActionStr[lastAction], lastActionStr[retVal], nowseconds, startseconds, stopseconds);
      #endif        
    }
                      
    if ((lastAction != TURN_OFF) && (nowseconds >= (stopseconds - (BLYNK_SCHEDULE_ACCURACY + 1)) && nowseconds <= (stopseconds + BLYNK_SCHEDULE_ACCURACY)))
    {   
      #if (DEBUG_BLYNK_RTC > 0)
        sprintf(activatedTime, "%s %02d/%02d/%04d", dayOfWeek[weekday()-1], day(), month(), year());     
        Serial.printf("Schedule %d stopped at %s on %s\n", scheduleNo, currentTimeAM_PM(currentTime), activatedTime);
      #endif
      //If both startSeconds and stopSeconds falls in the same 2 * (BLYNK_SCHEDULE_ACCURACY) range, DO_NOTHING
      if (retVal == TURN_ON)
        retVal = DO_NOTHING;
      else
        retVal = TURN_OFF;
      #if (DEBUG_BLYNK_RTC > 1)
        Serial.printf("Last Action = %s, Action = %s, Now = %d, startsec = %d, stopsec = %d\n", 
                      lastActionStr[lastAction], lastActionStr[retVal], nowseconds, startseconds, stopseconds);        
      #endif        
    }
    
    if (retVal != DO_NOTHING)
      lastAction = retVal;                   
  }
    
  return retVal;  
}

If necessary, I’ll put the full code on GitHub later.

@khoih
Actually i need to trigger a function only on say mon, wed and sun… but it will trigger the function as soon the time has arrived… Because the app has already sent 1 and the if condition is met… This is the problem…

You seem to be saying that the app sends data, triggering the BLYNK_WRITE(V1) callback, as soon as a day is selected in the app.
I can’t reproduce this in either the iOS or Android versions of the app. For me, the data is only sent when the OK button in the Set the time toolbar is pressed.

Your current code is simply printing-out which days have been selected. No test of whether the start or optional end time has been met, or whether the current day is an active day is being done within your code. This is what I was saying earlier.
You need to add to the logic that you’re using and compare the current time and day number values from the RTC widget with the start and end time values and active day values that you’ve received from the time input widget.
The Time Input widget doesn’t do this for you, it’s simply a method to allow the user to select active days and start/stop times. You need to do the rest in your code, but you don’t currently have any code to do that. Your existing code simply prints out which active days have been selected.

Pete.

Yes as i mentioned earlier, if i get this day selecting business done then later i will add an digital write function after the condition is met…

I mean the same… Once the day and time as been set we press ok… So the app will send 1 for selecting monday… But today will be sunday, and our condition is only to proceed if if (MonWeekDay == 1) but as the app has already sent 1 after pressing “ok” the condition is met. If the app had sent 1 on monday itself then this problem wouldn’t have arrived…

Is there a way to track what day is today from RTC widget ? just like we do with the time !!

:point_down:

once i get this right!! then a function can be called