Doing something at a certain time

Hallo,
I’m wanting to execute a line of code on the hour every hour apart from at night. Can I do it like this:

if(Time.hour() > 7 && Time.minute() > 9)
{
  // gotoSleep for 10mins
}

or is it best to use a library? I’m sort of struggling to see the advantage to a library for my use case.

Thanks (another question to follow about using the DFPlayer Mini!)

1 Like

This would do it “on the hour” every hour past 7:

if(Time.hour() > 7 && Time.minute() == 0)
{
  // gotoSleep for 10mins
}

Does the Arduino TimeAlarms library work on Particle? It’s not without fault, but it is pretty straightforward to do some common but error-prone alarm tasks.

There are several timer libraries available in the web IDE, including one called TimeAlarms, so you could use one of them if you want. However, if all you want to do is similar to what you posted in your question, a library is a bit of an overkill in my opinion.

or

Whenever I see time checks made like this it makes me shudder :wink: - sorry :blush:
For numerous reasons.

  • none oft these solutions (nore does the original request state the exact bounds) do any explicit checks for "at night" (unless only times past midnight are considered night)
  • > 7 in both of these solutions means that the condition will only be true for 8:00:00 and later
  • the condition in the OP would render the condition to be true from 8:10 till midnight every minute except the first few minutes from the full hour to 10 minutes past
  • the Time.minute() == 0 condition relies on actually sleeping for at least one minute after the check, so any change inside the conditional block that does away with the sleep may break the logic of the condition potentially causing confusion.
  • in case the sleep wasn't there the equality check for mintues would cause the condition to be true one minute long

If you want to make a range check for timestamps, I'd always go with Time.local() % 86400 which gives you one number for the full time part of the UNIX epoch date/time (hh:mm:ss).
With that number you won't be confronted with exponental complexity for your range checks for extra fields.
e.g.

  // simple check for only hours (do stuff 7am till just before 8pm)
  if (Time.hour() >= 7 && Time.hour() < 20)
  // quickly gets messy with minutes added (do stuff from 7:10am till just before 8:10pm)
  if ((Time.hour() >= 7 && Time.minute() >= 10 || Time.hour() > 7) && (Time.hour() < 8 || Time.hour() <= 8 && Time.minute() < 10))

And then you haven't had the "execute only once per minute" guard in place.

With one and only one number for the full timestamp things look a bit easier

const int startTime =  7*3600 + 10*60 + 0*1; // 7:10:00 - 3600 seconds to the hour 60 to the minute
const int stopTime = 20*3600 + 10*60 + 0*1;
int oneShotGuard = -1;
...
int currentSecond = Time.local() % 86400; // 86400 seconds to the day
if (startTime < currentSecond && currentSecond < stopTime && currentSecond != oneShotGuard) {
  oneShotGuard = currentSecond;
  // do whatever without breaking the condition
}

To change the timeframe you just alter the two constants and are done and the condition is (almost) independent of the active block - only the first line has to be considered in connection, but since it follows immediately and works on a variable that's and intrinsic part of the condition the connection is obvious (which isn't the case with the implicit impact of a System.sleep() call).

Granted, the check to repeat things once an hour isn't implemented there, but can be added much easier to the latter solution than to the former - in a similar fashion as the oneShotGuard (e.g. oneShotGuard = Time.hour() to only act once per hour - usually on the full hour since that's the earilest time the number changes :wink: ).

4 Likes