Open dakky opened 4 years ago
Hi, I too an experiencing reliability issues minuteChanged() and secondChanges() it seems to be linked to when an MQTT message is received and acted upon around the time the clock transitions from 59 seconds to zero seconds and minutes are incremented. It seems as though the 'timing' to increment minutes is missed. The clock does correct itself after a minute or two. The error occurs randomly and not for every transition from 59 to 0. Like you I have events() in my main loop. In the manual the description of events() refers to 'loop functions' i.e in the plural so I am wondering if events() need to be called more than once in different functions. I am using an ESP8266 BTW. To me it is fundamental that time increments with 100% reliability or otherwise this library cannot be used.
It's really only meant to be polling once, because internally there is a variable _last_read_t
used to determine if the change was already presented. Never thought of wanting to check it from two places, usually people just have a loop and need to do this themselves if they want to prevent flicker of a display. I guess you'll just have to store it yourself in the second place and see if it changed.
Fixed the documentation in commit 71a6baf to add
Note that this uses a single variable internally to store when the time was last accessed, so your code can only poll this in one place.
The library does not have a daemon running. The only thing that happens magically in the background is the ESP itself increasing the millisecond counter. ezTime is all just code that you call which then uses this counter to figure out what time it is. What that means is that if some other code is doing things at the the time second or minute changes, you will learn about it later.
@bobcroft, is that what you mean?
Hi, thank you for your responses so far, to be absolutely clear I was only using the minuteChanged() function in one place, in the main loop immediately after events(). I was only musing that maybe it had to be called multiple times, from your remarks the intent is that it is called once. Good, that's clear, however it still does not increment the display as I expected it to. Below is the code in my loop.
void loop()
{
events();
if (minuteChanged())
{
tft.setTextColor(TFT_MAGENTA, TFT_BLACK);
tft.drawString( (myTZ.dateTime("H:i:s")), 0, row2, 6 );
}
if (secondChanged())
{
tft.setTextColor(TFT_MAGENTA, TFT_BLACK);
tft.drawString( (myTZ.dateTime("s")), posnSec, row2, 6 );
}
if (millis() >= timerxs) stateloop(); // called every 100 mS
mqttClient.loop(); // process MQTT subscribed topics
ArduinoOTA.handle();
keeplive();
}
Could you clarify what 'learn about it later means' please.
In your last response you ask 'is that what I mean'? Yes, I think it is, or put another way - What happens if some other code is running at the point the minutes increment should occur? howdo I ensure the minute update is not missed?
Hmmm, I'm just wondering about something... Do things get better if you drop the minuteChanged
check and in secondChanged
do a if (now() % 60)
See too many ways my code doesn't cut it all of a sudden. I may redo this to have separate vars for presenting minutes changed and seconds changed, it seems like I wrote this too much with only one too specific use case in mind. Thank you for reporting...
Hi Rop, I'll try that later, i was wondering about doing something similar. There is so much I like about your library I want to stick with it. I'll keep you posted.
I'll try to make it work for you, within the limitations of what ezTime is. With that I mean that on modern processors such as the ESP, one could do cooler things such as running one's own process. But that doesn't translate all the way down to the original Arduino that ezTime also has to work on.
Hi Rop,
I did as you suggested and put the if (now() % 60) into the secondChanged() and the minute update has not failed in about 6 hours. I ran two separate rows of time on the TFT display one showing time using minuteChanged(), the second row showing time with the modified secondChanged(). I could see the minute change errors in row 1.
Its getting late I’ll feedback more tomorrow.
Bob
From: Rop Gonggrijp notifications@github.com Sent: 21 May 2020 10:31 To: ropg/ezTime ezTime@noreply.github.com Cc: bobcroft rdg3@lineone.net; Mention mention@noreply.github.com Subject: Re: [ropg/ezTime] secondChanged/minuteChanged triggeres not always (#91)
Hmmm, I'm just wondering about something... Do things get better if you drop the minuteChanged check and in secondChanged do a if (now() % 60)
See too many ways my code doesn't cut it all of a sudden. I may redo this to have separate vars for presenting minutes changed and seconds changed, it seems like I wrote this too much with only one too specific use case in mind. Thank you for reporting...
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ropg/ezTime/issues/91#issuecomment-631985802 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AAVDXISVBVQTTNHHFCNPILTRSTYFNANCNFSM4NF7XUCQ .
Just wanted to report, that I faced the same issue when checking secondChanged and minuteChanged in the same frame.
I used the (now() % 60 == 0)
workaround, since secondChanged always fired correctly and minuteChanged not even once.
With the workaround it runs fine now. Not a big deal :) thanks for this lib
I call secondChanged() only one place in loop(). it triggers very irregularly.
const int WX_CURRENT_SHORT_INTERVAL = 10; // WeatherBit has 500 requests per day limit ( 2 min 53 sec ) const int WX_CURRENT_LONG_INTERVAL = 60; // intervals are in minutes
void loop() { static bool shouldUpdateCurrent = true;
events();
if (secondChanged()) { DEBUG_PRINTLN(dateTime("H~:i~:s")); updateFrame(); }
// set intervals every current short interval int currentInterval = WX_CURRENT_SHORT_INTERVAL; if (minute() % WX_CURRENT_SHORT_INTERVAL == 0) { // long intervals from midnight to 7 am if (hour() < 7) { currentInterval = WX_CURRENT_LONG_INTERVAL; } // check if this interval needs current WX update if (minute() % currentInterval == 0) { if (shouldUpdateCurrent) { getWXcurrent(); shouldUpdateCurrent = false; } } else { shouldUpdateCurrent = true; } } } // loop()
Output: 17:33:51 17:33:52 17:33:55 17:33:58 17:34:00 17:34:01 17:34:02 17:34:03 17:34:06 17:34:09 17:34:14 17:34:16 17:34:17 17:34:18 17:34:25 17:34:26 17:34:29 17:34:32 17:34:34 17:34:35 17:34:36 17:34:42 17:34:43 17:34:45 17:34:46 17:34:47 17:34:49 17:34:52 17:34:53 17:34:54 17:34:58 17:34:59 17:35:00 17:35:01 17:35:02 17:35:04
I am on ezTime 0.8.3 on a ESP32-C3. I do not set any #defines for ezTime in my project.
I call secondChanged() only in one place in loop(), which runs non-blocking. Mainly TickerTwo are called from loop.
secondChanged() actually triggers any time called.
I made a simple custom function, now it works perfectly:
int8_t wasSecond = -1; bool mySecondChanged() { if (second() != wasSecond) { wasSecond = second(); return true; } else { return false; } }
Tried it, but it doesn't compile.
void loop() { int8_t wasSecond = -1; bool mySecondChanged() events(); { if (second() != wasSecond) { wasSecond = second(); return true; } else { return false; } } }
Hello
I have a problem with the secondChanged method: in one method of my class it does return true only about every 2-5 minutes, in another method of the same class it triggeres as espected every second.
code sample (stripped down to the basics)
the main loop:
As result I see:
entered method A
, which is expected and serves only a proof, that this method is really calledTesting B
which is also expectedTime X:X
, which is the problem.Any idea whats wrong here and how to fix/debug this any further?