-
-
Notifications
You must be signed in to change notification settings - Fork 130
Rename RealtimeClock to ArduinoTime #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
In about a week, I should be able to work on this time stuff. At the moment I'm wrapping up a new shield product release with an IMU and other stuff, so it's demanding most of attention right now. Hopefully this time API isn't highly urgent? However, here's a lengthy message about the Time library, originally by Michael Margolis, which I somehow ended up sort-of maintaining. Michael's design does exactly what you're suggesting, keeping time with millis() and allowing occasional sync to external sources. NTP over the internet and GPS are the 2 common cases. A recurring problem with the Time library is confusion when syncing to a RTC. Michael and I have talked about this in person at Maker Faire at least twice. I've been tentatively planning to expand the Time library to distinguish between 2 different types of time sources. I've been called them "online" and "external", but perhaps other names would be better. When an "online" device like a RTC is present, keeping time separately with millis and syncing them is terribly confusing. But people do easily understand and expect this when they know the source is "external", like NTP over the internet. My main point is there's 2 different types of time sources and people do seem to intuitively understand the difference. Atomic access is a real issue with the current Time library. The simple functions year(), month(), day(), hour(), minute(), second() are convenient, but when called in sequence, especially when mixed with code that does I2C or SPI communication to update a display, it's possible to get the minute when seconds is 59, and then later get the second after it's rolled over to zero... for a 1 minute display error! Theoretically this error could happen between any of the functions, but a 1 hour error is 60X less likely, 1 day 24X less common, etc. Often I've considered adding buffer and millisecond timestamp inside the Time library, to remember the most recent 32 bit time returned by these functions and intentionally return the "old" time under certain circumstances, like detecting if all 6 or either group of 3 have or haven't been read, and not "too many" milliseconds have elapsed to make the buffer "too old". I know the simplicity of these functions is very compelling, but for a permanent Arduino API, perhaps we should think about ways to solve the atomic access problem, yet still end up with something simple and easy to learn & use? Maybe a C++ object of some sort? Another issue Michael raised when we've talked about "online" versus "external" time sources the inefficient nature of I2C communication to many RTC chips. Solving the atomic access issue would also go a long way towards solving the excessive communication issue if each call to year(), month(), day(), hour(), minute(), second() accessed a single atomically acquired time, rather than causing 6 separate I2C communications. Previously I was concerned about the use of short, common words as functions in the global namespace. But I just did a few quick tests. It doesn't seem to be such a big problem. One final thought. On Teensy, I've been using this in my platform.txt file in the linker step:
This embeds the build time into the hex file in a way that's always updated right before upload, even if none of the files needed to be recompiled. Then startup code can detect if a RTC isn't initialized and use this number to automatically set it to the timestamp when the code was compiled. In the common case where someone casually uploads an Arduino sketch, it allows their RTC or software-based timekeeping to automatically have the correct time, at least within the seconds for upload and startup. When they power cycle (without a battery-backed RTC), of course the time gets reset to when they built the code, but at least in those initial experiences while uploading, things "just work" with the time set fairly close to accurate. Might be worthwhile to add this to Arduino's platform.txt files. Like other linker symbols, it only gets allocated to bytes in the HEX file if actual code uses it. Whew, long message. Hopefully some of this helps? In a week or so, I can actually work with the code... |
this brings a more wider question: are we going to provide the time API (and also the other API listed in this repository) as separate libraries? or are we going to include them in the Arduino Core? If we go with the library path, then I agree, it should be renamed ArduinoTime. |
Paul, thanks for taking the time to write this message that contains really valuable information.
If I undestand correctly in your proposal the current time is kept by the CPU via software, using millis() or other techniques, and it's synced (more or less often) with a time-service that can be an RTC or a NTP server or any other precise time-reference. The time functions ( At the moment the Time API in this repository is structured in a slightly different way: the class RealTimeClock {
virtual unsigned long getTime() = 0;
virtual bool setTime(unsigned long t) = 0;
}; and the time functions will performs all the calculations after reading the current timestamp from the SystemRTC: extern RealTimeClock *arduinoSystemRTC; The synchronization with a time-service is, IMHO, another different thing: what you call "external" source is actually a time-service that provides the real current time. This is deeply different from an RTC because the time-service will always provide you the real current time by means of other sources that are usually slow (GPS/Network/DFC77/a human being that enters the current time...). |
Caching the last timestamp for a fixed amount of time looks like a reasonable solution to me and the implementation seems also straightforward. |
Some random thoughts... Paul and Cristian, I like what you said about the On Tue, Mar 29, 2016 at 8:32 AM, Cristian Maglie [email protected]
|
As I mentioned elsewhere I see ArduinoTime as the high level arduino time API then you can subclass it for the different implementations.. by default on UNO it’s a software only implementation (which can be synched as you mention) on other platform it’s implemented using the on board RTC if the platform has one (ZERO, CURIE, DUE and Linux on libArduino) what is important it that when the code starts the user has a time object that gives access to time and date. m
|
Ok I've had some time to tinker on this one, hope that the latest changes reflect better how I would like to see this API evolve and that those changes matches your expectations too! :-)
we now have two classes:
The use case I have in mind is to use
This is an untested draft, it's just to see how well it fits. The idea is that boards or CPU that doesn't have an hardware RTC may create a SoftwareRTC instance in their variant file to make it available to users. We should also figure out a way to let the compiler optimize the build and remove the SoftwareRTC instance when not used. |
The RealtimeClock class is actually managing time so it should be called ArduinoTime
we could also provide a software only implementation which can be useful even if only based on millis() (there are a number of use cases where one needs to manage time, maybe syncronising via NTP every etc)
The text was updated successfully, but these errors were encountered: