Missing something with attempt to understand Advanced Time Input

In an attempt to understand how to use Advanced Time Input I searched and found @Costas Scheduler.ino-Thank you.
I attempted to modify it for a Wemos D1 Mini with the relay shield attached. Keep in mind that I am not an experienced programmer. I am using the latest Blynk app on iOS.

The issue is that no matter what time I set the Time Input to in the future, I never get a respons from the relay when the Start time begins. I have selected a Start Time, Finish Time and Day of the Week. I added a button widget to the dashboard which is also programmed to D1 and I can operate the relay. My Time Input is assigned to V0 as in the example.

I have attached the code I am using below. Any suggestions would be appreciated.

// Scheduler.ino by Costas 22 March 2017
// Include library hack so scheduler is off when no days selected
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
#define BLYNK_DEBUG 
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
const int relayPin = D1;

unsigned int clockHour;
unsigned int clockMinute;
unsigned int clockSecond;
unsigned long daySeconds;
unsigned int dayNumber;  // 1 Monday through to 7 Sunday, like Blynk day numbers
bool activeToday = false;
long start1seconds, stop1seconds;
bool scheduler = true;          // default is scheduler on but it will be checked every 10s
bool schedulerStatusChanged = false; // check if status has changed

char auth[] =   "xxxxxx";
char ssid[] =   "xxxxxx";
char pass[] =   "xxxxxx";
//char server[] = "xxxxxxxx";

SimpleTimer timer;

BLYNK_WRITE(V0) {   // Weekday timer
  activeToday = false;
  TimeInputParam t(param);
  unsigned int countondays = 0;
  for (int i = 1; i <= 7; i++) {          // Process weekdays (1. Mon, 2. Tue, 3. Wed, ... 7. Sun)
    if (t.isWeekdaySelected(i)) {
      countondays++;
      if(i == dayNumber){
        activeToday = true;  // set false at start of function
      }
      Serial.println(String("Day ") + i + " is selected");
    }
  }
  if (countondays == 0) {
    scheduler = false;  
  }
  else{
    scheduler = true;    
  }
  if (scheduler != schedulerStatusChanged){
    schedulerStatusChanged = scheduler;
    if(scheduler == false){
      Serial.println(F("Scheduler1 currently disabled"));
      Blynk.virtualWrite(V1,"Scheduler1 currently disabled\n");        
    }
    if((scheduler == true) && (activeToday == true)){
      Serial.println(F("Scheduler1 active today"));
      Blynk.virtualWrite(V1,"Scheduler1 active today\n");      
    }
    if((scheduler == true) && (activeToday != true)){
      Serial.println(F("Scheduler1 not active today"));
      Blynk.virtualWrite(V1,"Scheduler1 not active today\n");      
    }
  }
  if(scheduler == true){    
    if (t.hasStartTime())                                             // Process start time
    {
      start1seconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
    }
    else if (t.isStartSunrise())
    {
      Serial.println(F("Start at sunrise"));
    }
    else if (t.isStartSunset())
    {
      Serial.println(F("Start at sunset"));
    } 
    if (t.hasStopTime())                                              // Process stop time
    {
      stop1seconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);    
    }
    else if (t.isStopSunrise())
    {
      Serial.println(F("Stop at sunrise"));
    }
    else if (t.isStopSunset())
    {
      Serial.println(F("Stop at sunset"));
    }
  }
}

void timeChecker()
{
  if(activeToday == true){
    if((daySeconds >= start1seconds)&&(daySeconds <= start1seconds + 10)){
      digitalWrite(relayPin, LOW);          // LED ON or relay active LOW ON
      Serial.println(F("Device ON"));
    }
    if((daySeconds >= stop1seconds)&&(daySeconds <= stop1seconds + 10)) {
      digitalWrite(relayPin, HIGH);         // LED or relay active LOW OFF
      Serial.println(F("Device OFF"));
    }  
  }
}

void setup(){
  Serial.begin(115200);
  
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW); 
  Blynk.begin(auth, ssid, pass); 
  timer.setInterval(10000L, timeChecker);   // check every 10s if any weekday scheduled events
}

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

You forgot rtc widget, both in your code and app. Time input will not work without it.

2 Likes

Thanks for your reply

@zodiac I added TimeLib.h, WidgetRTC.h to my includes as well as the RTC widget to my app. Also added WidgetRTC rtc; rtc.begin(); to my code, copied from the sketch builder RTC example. My updated code is pasted below but the Time Inuput still does not energize the relay when the time condition is met.

Thanks

// Scheduler.ino by Costas 22 March 2017
// Include library hack so scheduler is off when no days selected
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space
#define BLYNK_DEBUG 
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <TimeLib.h>               //added
#include <WidgetRTC.h>         //added 

const int relayPin = D1;

unsigned int clockHour;
unsigned int clockMinute;
unsigned int clockSecond;
unsigned long daySeconds;
unsigned int dayNumber;  // 1 Monday through to 7 Sunday, like Blynk day numbers
bool activeToday = false;
long start1seconds, stop1seconds;
bool scheduler = true;          // default is scheduler on but it will be checked every 10s
bool schedulerStatusChanged = false; // check if status has changed

char auth[] =   "xxxxxx";
char ssid[] =   "xxxxxx";
char pass[] =   "xxxxxx";
//char server[] = "xxxxxxxx";

SimpleTimer timer;
WidgetRTC rtc;   //addded

BLYNK_WRITE(V0) {   // Weekday timer
  activeToday = false;
  TimeInputParam t(param);
  unsigned int countondays = 0;
  for (int i = 1; i <= 7; i++) {          // Process weekdays (1. Mon, 2. Tue, 3. Wed, ... 7. Sun)
    if (t.isWeekdaySelected(i)) {
      countondays++;
      if(i == dayNumber){
        activeToday = true;  // set false at start of function
      }
      Serial.println(String("Day ") + i + " is selected");
    }
  }
  if (countondays == 0) {
    scheduler = false;  
  }
  else{
    scheduler = true;    
  }
  if (scheduler != schedulerStatusChanged){
    schedulerStatusChanged = scheduler;
    if(scheduler == false){
      Serial.println(F("Scheduler1 currently disabled"));
      Blynk.virtualWrite(V1,"Scheduler1 currently disabled\n");        
    }
    if((scheduler == true) && (activeToday == true)){
      Serial.println(F("Scheduler1 active today"));
      Blynk.virtualWrite(V1,"Scheduler1 active today\n");      
    }
    if((scheduler == true) && (activeToday != true)){
      Serial.println(F("Scheduler1 not active today"));
      Blynk.virtualWrite(V1,"Scheduler1 not active today\n");      
    }
  }
  if(scheduler == true){    
    if (t.hasStartTime())                                             // Process start time
    {
      start1seconds = (t.getStartHour() * 3600) + (t.getStartMinute() * 60);
    }
    else if (t.isStartSunrise())
    {
      Serial.println(F("Start at sunrise"));
    }
    else if (t.isStartSunset())
    {
      Serial.println(F("Start at sunset"));
    } 
    if (t.hasStopTime())                                              // Process stop time
    {
      stop1seconds = (t.getStopHour() * 3600) + (t.getStopMinute() * 60);    
    }
    else if (t.isStopSunrise())
    {
      Serial.println(F("Stop at sunrise"));
    }
    else if (t.isStopSunset())
    {
      Serial.println(F("Stop at sunset"));
    }
  }
}

void timeChecker()
{
  if(activeToday == true){
    if((daySeconds >= start1seconds)&&(daySeconds <= start1seconds + 10)){
      digitalWrite(relayPin, LOW);          // LED ON or relay active LOW ON
      Serial.println(F("Device ON"));
    }
    if((daySeconds >= stop1seconds)&&(daySeconds <= stop1seconds + 10)) {
      digitalWrite(relayPin, HIGH);         // LED or relay active LOW OFF
      Serial.println(F("Device OFF"));
    }  
  }
}

void setup(){
  Serial.begin(115200);
  
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, LOW); 
  Blynk.begin(auth, ssid, pass); 
 // Begin synchronizing time
  rtc.begin();  //added
  
  timer.setInterval(10000L, timeChecker);   // check every 10s if any weekday scheduled events
}

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

Did you allocate a pin for the RTC?

Did you set timezones correctly in RTC and TimeInput?

?? Did that become a thing again?

No, just my bad memory.

1st thing to go… forgot what the 2nd was :stuck_out_tongue_winking_eye:

@mpo881 I managed to figure this much out…

First off, I used the sprintf() method for nicer looking monitor prints, but is not required for the code logic

Secondly, I am ignoring the seconds, comparing hours first, then minutes… so as long as a calling timer is running every 30 seconds or so this should work

Finally, the only real important if() check is the initial one for “Doing something now”… which would be replaced with a function call or command to do something. The rest is mostly for troubleshooting my comparison logic.

I think this will all work… you can expand upon it for both start and stop times and put it to the test

if (t.hasStartTime())
  {
    // Get RTC time
    sprintf(currentTime, "%02d:%02d:%02d", hour(), minute(), second());
    Serial.print("Current Time: ");
    Serial.println(currentTime);

    // Get Time Input Widget time
    sprintf(startTime, "%02d:%02d:%02d", t.getStartHour(), t.getStartMinute(), t.getStartSecond());
    Serial.print("Start Time: ");
    Serial.println(startTime);

    if (hour() == t.getStartHour()) {
      if (minute() == t.getStartMinute()) {
        Serial.println("Doing somthing now");
      } else if (minute() < t.getStartMinute()) {
        Serial.println("Will do something");
      } else if (minute() > t.getStartMinute()) {
        Serial.println("Did something");
      } else {
        Serial.println("Clueless");
      }
    }
  }
Current Time: 11:17:55
Start Time: 11:18:00
Will do something

Current Time: 11:18:15
Start Time: 11:18:00
Doing somthing now

Current Time: 11:19:04
Start Time: 11:18:00
Did something
1 Like

Thank you. I initially started with @Costas Scheduler.ino and I did not modify any of the code related to time. I simply wanted to attempt writing HIGH and LOW to a GPIO. Based on @zodiac reply, I added the RTC widget, associated libraries and code (hopefully correctly!). As was suggested, I did confirm both time zones are set to the same time zone. But I am confused by the comment about allocation of a pin to the RTC widget. There is no provision for this and I have googled for the information as suggested as well as searched the forum. Funny enough, I found a post where @costas replies to someone else that a pin is not needed anymore. So, now I am really confused.

Thanks for your help. Still digging around!

We all get that way in our old age :stuck_out_tongue:

Of course you DO need the RTC to compare the start/stop times with. But you DON’t need a pin for the RTC Widget anymore (was required at one time) :wink:

LOL imagine how I feel pushing 60 and have only managed cut and paste coding!

So, I understand I need the RTC widget. I believe that it is added correctly to my code. I now understand I do not need a pin assignment for the RTC widget.

Still do not understand why the code does not write the GPIO HIGH or LOW when the START/STOP time is triggered?

My serial print shows being connected to the cloud, V0.5.0, the correct auth token, and rtc sync.

Wish they had an emoji for tapping my foot! Thats what I am doing since yesterday with this one :thinking:

I just realised that this ^ command, as well as the stop time one, needs to be in a BLYNK_WRITE() Function tied to the Time Input Widget… so you should transfer/store all the if t.hasStartTime()… etc… into separate variables to be ran in my if() code.

e.g.

BLYNK_WRITE(V1) {  // Time Input Widget
  TimeInputParam t(param);
  SThour = t.getStartHour();
  STmin = t.getStartMinute();
  SPhour = t.getStopHour();
  SPmin = t.getStopMinute();
}

void TimeCheck() {  // call with timer every 30 seconds or so
  if (hour() == SThour) {
    if (minute() == STmin) {
      Serial.println("Doing something now");
    } else if (minute() < STmin) {
      Serial.println("Will do something");
    } else if (minute() > STmin) {
      Serial.println("Did something");
    } else {
      Serial.println("Clueless");
    }
  }

  if (hour() == SPhour) {
    if (minute() == SPmin) {
      Serial.println("Stopping something now");
    } else if (minute() < SPmin) {
      Serial.println("Will stop something");
    } else if (minute() > SPmin) {
      Serial.println("Stopped something");
    } else {
      Serial.println("Clueless");
    }
  }
}

LOL you did read this part of my reply?:sweat_smile:

Ok, thank you. I will see what I can figure out

I understand… it has taken me the last 3+ hours to get this far… :stuck_out_tongue: But I wanted to finally figure out this Time Input Widget for myself… so your welcome :slight_smile:

And I am working on a more fleshed out example… eventually :timer_clock: :wink:

I may still be sitting here when you come up with your example, albeit without any hair left on my head.

Thanks again. Ill keep plugging away. Seems as though I am not the only one to struggle with this one.

Here is something else that confuses me though. I look at the sketch builder and find an example for Advanced Time Input. If I load this sketch and add a Time Input widget, it would seem to me it will do nothing. But, shouldn’t I be able to just add a digitalWrite somewhere in the code based on the time trigger? Otherwise, what is the point of this example? Plus there is no mention of needing the RTC widget in the docs or example sketch when using the Time Input widget. I dont understand why I need RTC at all when there is already a provision to set the time zone in the Time Input widget and I cannot find an explanation anywhere?

That is a template that contains this extract of code:

Serial.println(String("Start: ") +
               t.getStartHour() + ":" +
               t.getStartMinute() + ":" +
               t.getStartSecond());

This give you the trigger time but you need all the extra code like RTC to check if the time now is < == > than trigger time etc.

I need to digest that a bit. In the serial monitor when I change time zones, I see it update correctly to the time zone i choose in the widget. Same for the day of the week, if I change it in the widget, I see it updated in serial monitor. One issue though, in terminal widget assigned to V1 as in the code I am using, the only message I ever see is 'Scheduler1 not active today".Still trying to figure that out

Could be the library hack that you are missing but that should only be required to switch no days selected to actually meaning no days, rather than the Blynk default of no days means everyday.

Do you have all days selected in the widget as that’s best for testing?