If (time) = midnight do

I would think this would be right up there with turning on an LED in the often asked list.

I can't find an elegant way to reset variables at midnight, or a given time. I don't want to loop through "if hours ==23 and minutes==" on every loop for an event that happens once a day.

is there a timeOfDayEventTrigger() hidden somewhere?

What Arduino, RTC, and library are you using?

First of all, how would your Arduino know when it is midnight? I think most of them don't even have a real-time clock. This requires external hardware, and from that point on, this is no longer a trivial matter (as it would be on PC).

If what you need is run a piece of code every 24 hours, that can be done fairly easily with things like Metro, at least if you're on a platform where 24 * 60 * 60 * 1000 is smaller than the maximum value of whatever millis() returns, but running it daily at a specific time is a lot more difficult.

And since this is something that is entirely reliant to external hardware, I'd be surprised if the Arduino API would have any integrations for something like that.

(This may also be slightly related to my recent rants in What would be a good synonym for "delay"?. Event-driven programming just isn't something that's very common in the Arduino ecosystem.)

I inferred from the OP's question that perhaps OP was using an integrated RTC or external RTC hardware. Either way OP will have to use the requisite library.

I read it mostly as a theoretical question. OP has been here long enough to know what an RTC is and where they can buy them.

Assuming you have an RTC, you don't have to check continuously. You can use millis() to determine when you check. It all depends on how "close" to midnight you variables need to be reset. You could check once per loop, once per 10ms, once per 100ms, once per second, etc.

Why ever not? How else is it going to know when it's midnight.

1 Like

Well, for one thing, the loop() may be long enough to just skip 23:59 entirely. (Which would, admittedly, point at problems with the code.)

For another thing, it just doesn't make for very elegant code. The loop() function just tends to end up as a big ball of stuff which has to poll a whole bunch of completely unrelated stuff - which is not exactly what modern design guidelines (like the "separation of concern" principle) call for.

Having a dedicated object which you just set up during, well, setup(), and which then executes a given callback exactly once every time midnight has happened, makes for a clean separation between the timing and the application logic, and a clean separation between this part of the application logic and the rest of the application.

In Spring Boot, I can just do something like this:

@Scheduled(cron = "0 0 24 * * *")
public void midnightTask() {
    log.warn("It's midnight and you should go to bed instead of starting philosophical"
    + "discussions on the Arduino forums!!!");
}

And while this probably still relies on some form of polling in the background, that polling is hidden from me. That makes my life a lot less complicated.

Buuuuuuuut this is, of course, reliant on technologies like AOP and reflection, which are just not viable on most Arduinos. Still, I sympathize with OP's request.

Why not use the alarm output of a RTC.
Leo..

very good idea.

another approach would be to calculate minutesOfDay
hour * 60 + minutes
and if this results in zero it is midnight
IMHO not a very complex thing

if (hour * 60 + minutes == 0) {
  doTheMidNightReset()
}

best regards Stefan

Will still fail if the loop() function is slow enough to take more than 60 seconds.

ESP32 TTGO OLED Lora SD. This thing:

unfortunately, the I2C pin scanner shows only the OLED, no other I2C devices connect. this makes using the RTC3231 timer impossible. Library is RTCLib.h

I am trying to record total LoRa on air time per day. Legal max is 30 seconds per user, eventual plans are 5 - 15 stations. I am trying to remain kosher. I want to reset the on air timers at each station at the same time every day.

Project is an LPPM: Large Property Perimeter Monitor - and a weather station. If all goes well, certain gates will never be entered, so the FSB - Field Sensor Box - could fail and you would not know. So, spread the weather sensors around the property and get a reading every 5 minutes from each, like a heartbeat. You see the rainfall sensor, #5 is alive.

switch from the Arduino API to bare FreeRTOS.

get back to me about learning yet another programming language and IDE when you are 67. enough is enough.

2 Likes

I'd guess the RTC3231 (i assume you mean DS3231?) just isn't connected to the default I2C bus. There may be a specific library to access the on-board RTC. If there isn't, you'll at least get access to it if you switch from the Arduino API to bare FreeRTOS.

Also, if you just want to reset the counts "at the same time every day", simply running your logic once every 24 hours, rather than running it every day at 24:00, is completely sufficient as long as your device doesn't regularly get reset.

If the OP's loop( ) runs this slow, time to take up fishing :fish: .

1 Like

Yes, I said that this would indicate some problem back in post #8.

if (currentHour == 00 && previousHour == 23)
{
  // midnight happened
}

previousHour = currentHour;

2 Likes

HI,
if(( hours + minutes + seconds) == 0)
{
// do something....
}

This is even worse than previous suggestions because it will fail if loop() happens to take more than 1 second, or if it is fast enough to run more than once between 00:00:00 and 00:00:01.

(Admittedly, that's also a problem with the code proposed in #10.)

Sir @taschi ,

If you are able, you can use smart way of blocking so that it does not run more than once every time 00:00:00.

If your loop takes longer than a second, smartly, you don't use the seconds variable in the if.

Yes, I am able to do that.

However, the code you posted doesn't do that and I wanted to point it out.