Hi there,
I want to schedule an event ( put high a pin ) every day at 6:00 PM
To do this I made this code:
void loop()
{
/* Send sensors data */
if( (Time.minute() % 5 == 0) && (Time.second() == 0) )
{
readSensorBMP180();
}
/* Start Irrigation System */
if( (Time.hour() == 18) && (Time.minute() == 14) && (Time.second() == 0) )
{
Particle.publish( "IrrigationSystemStatus", "started", 60, PRIVATE );
}
/* Request time synchronization from the Particle Cloud */
if( (Time.hour() == 0) && (Time.minute() == 0) && (Time.second() == 0) )
{
Particle.syncTime();
}
delay(200);
}
Every thing works, but thus is the problem each evet is sent 4 times because when 18:00:00 comes, the second if is true for an entire second and with the delay of 200 ms the code inside this loop is executed 4 times.
I set 1 seconds as delay, but there is the risk that the code won’t executed.
I think to use a flag variable but I need to this a mechanism to reset this variable.
The mills function should be fine for the first IF, but to schedule an event at 6:00:00 is not a precise.
Any advice?
Thanks!
First I’d not test for multiple fields when checking for a time but for the combined time - easiest would be seconds as this is what Time.local()
gives you back already.
Next I would not check for equality but always for greater or equal in conjunction with a “once per day” flag, otherwise you may miss a whole day when you miss the particular second.
So I’d go with something like this
const int timeAction = 18*3600 + 14*60 + 00; // hh+mm+ss
int previousDay = 0;
void setup() {
Time.zone(yourUTCOffset);
...
}
void loop() {
if (previousDay != Time.day() && Time.local() % 86400 >= timeAction) {
previousDay = Time.day();
doWhatever();
}
}
3 Likes
Hi ScruffR,
thnaks for the example! Very usefull!
I have another two questions:
-
How to trigger an event every 5 minutes? Time.local() % 300 may be invalid is the loop delay is 200 ms. In this case I need a flag variable.
‘if( (Time.local() % 300) == 0 )
{
readSensorBMP180();
}’
-
Is it necessary to update the system time with Particle.syncTime once a day?
if( (Time.hour() == 0) && (Time.minute() == 0) && (Time.second() == 0) )
{
Particle.syncTime();
}
Thanks for your time!
Depending on your needs for precission you may want to resync once a day or once a week or month.
But whenever a new cloud connection is established an implicit resync will happen anyway.
If you decide to stick with once a day I’d just stuff it into the 18:14:00 block - that’s done once a day too.
For the 5 minute task, it’s just the same: Don’t check for equality.
And in this case you don’t just want to store the day you last performed this, but the actual time.
int previousTime = 0;
...
if (Time.local() - previousTime >= 300) {
previousTime = Time.local();
previousTime -= (previousTime % 300); // optional to act on 5min boundary
doWhatever();
}
If you don’t care about the 5min bounds but just round about every five minutes, I’d go with the commonly used millis()
timing or use a Software Timer.
1 Like
Thanks.
I prefer to use the unix time because I want to send data every 5 min.
And in this way I can set a loop delay equal to 1000.
Have a nice day!
The best practice would be to not use any delay but have your loop()
run completely free.
And the two alternatives I mentioned will allow 5 minute intervals just the same, so I don't quite understand your argument
2 Likes