GrumpyOldPizza / ArduinoCore-stm32l0

Arduino Core for STM32L0
125 stars 67 forks source link

GNSS Sync RTC #126

Closed hallard closed 4 years ago

hallard commented 4 years ago

Thomas, I saw that GNSS library is syncing RTC in background and I have 2 questions about that:

I mean that I need to know when I can trust the RTC. not really need precision but need to be sure I had first RTC sync.

I did not find a way to know that, did I missed something?

Thanks

GrumpyOldPizza commented 4 years ago

The right question at the right time. I am about to update all of this code (this weekend).

So no, you cannot disable the auto sync at the moment. That is mainly driven by the desire to have a global time base. Forward looking, LoRaWAN Class B and Multicast do want GPS time as a reference to sync events.

So I suppose I could add a GNSS.enableTimeSync() / GNSS.disableTimeSync() [are there better names ?] Or GNSS.setTimeSync(bool onoff) ? Or GNSS.setRtcSync(bool onoff) ?

N.b. that there are 4 components to that. One is to update the date/time. One is to align the full second to GPS time (so that all clocks flip to the next second in sync), one is to update the current leap second, and one is to compute the RTC calibration. So is one switch what is needed that turns off all of that ? Or does it only turn off the date/time update, but leaves the full second alignment and the RTC calibration in there ?

The callback to know when a sync happened ... Is a callback needed, or is somehow a simple flag off the RTC class good enough ? Say RTC.isSynced() ? But then again, what is synced ? LoRaWAN does not give me a leap second, only GNSS does. Long term calibration does not seem to be possible via LoRaWAN ... So how can you find out whether something got affected. If there is a callback, is there a way to cancel the sync in the callback ?

GNSS has early GPS time without leap second. So one of the big questions is whether it should update the data.time before the leap second is known ... One could add the "isSynced()" / "isResolved()" ... Or split into "isEpochValid()" / "isDateTimeValid()" ... (for the epoch one does not need to know the current leap second). Are those flags only set if GNSS / LoRaWAN synced something, or also if the user sets the epoch/date/time/leapSecond ?

Ok, now you had GNSS running for a while and it had a fully RTC sync. Now you reset the device (RTC still runs, so coming out of reset you still have some good time), what time components are still valid ? I mean the device could have been off for a year, and in the meantime there was a leap second ... Perhaps those flags are initially post reset "false" and only can be set to "true" if the respective event happened while active ... But then again the "epoch" will stay valid. Hence the epoch valid would survive a reset, right ?

Looks to me the important thing is more about finding out which components are valid than anything more complex ?

Mind spending some time on thinking that throu on your side ? All of this makes sense to ask for, I am just not sure what will be minimally required).

hallard commented 4 years ago

Wohh, what an interesting answer. Thanks for taking so much time.

In fact I don't really need to disable (but may be others does), I asked that because I was updating RTC thru GPS in my code until I understood it was already done. I don't know what application would have this to be removed but let's say some need, I like the name GNSS.setRtcSync(bool onoff)

Let me explain what I'm doing, my issue is not to ruin battery on bad reception or indoor location, so first shoot I'm getting First Cold Fix (with a timeout about 800s) and then subsequent fix should be warm fix once again but lower value (90s) To fire this timeout I'm using RTC.getY2kEpoch() less the same we took on start fixing (GNSS.resume())

So as you can see, second precision is enough it's just for a time out. But of course deal is that RTC sync in between does not break this difference. Of course it can happen and break mainly on start when RTC has not sync yet. Even on my side a drift of 1 or 2 seconds I don't care. But the deal is when we don't know when it was sync. For this, a simple flag in the lib is fine for me or even isEpochValid() should be fine also

Moreover, despite I just need epoch, my concern is on potential "side effect" on sync when using for example some timers (timermillis() and RTC alarms, syncing is awesome until it does not have some side effect, or at least we know them to correct in case it happens. I don't know what can be the drift on this chip for let say 1 day on RTC, is it more ms, us or seconds?

We can also resolve this (my timeout feature) on another way, perhaps better approach, could be interesting to implement fix timeout directly on the GNSS library, starting when calling GNSS.resume() or better GNSS.resume(timeout) that can fire a timeout callback.

For sure I will have more question but it's a bit off topic I will open another issue when needed

GrumpyOldPizza commented 4 years ago

I might add a GNSS.setRtcSync(onoff).

Still not sure about the naming for the other APIs. In the GNSS class I had this "fullyResvoled()", which is kind of directly from UBLOX.

RTC.isEpochSynced() RTC.isDateTimeSynced()

Anyway, what you wanna do for your problem is simply use the "TimerMillis" class. There is no side-effect from syncing the RTC from GNSS onto "TimerMillis".

hallard commented 4 years ago

Thank you, that's perfect.

To be honest sometime TimerMillis()is driving me mad, and I just confirmed that on a board but I'm opening a new ticket for that in the mean time #127

GrumpyOldPizza commented 4 years ago

There are a bunch of issues with the current code that I'd hope to fix in the next few days ...

On Fri, Apr 24, 2020 at 7:59 AM Charles notifications@github.com wrote:

Thank you, that's perfect.

To be honest sometime TimerMillis()is driving me mad, and I just confirmed that on a board but I'm opening a new ticket in the mean time

127 https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/issues/127

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/issues/126#issuecomment-619027357, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABXBA7CNCF4VN4UM3MDT42DROGLKVANCNFSM4MO3XPKQ .

hallard commented 4 years ago

A awesome feature would be a callback on USB plug, easier to flash, like that we can wake from sleep mode, making usb port visible to computer not always having reset or button on main board :-)

GrumpyOldPizza commented 4 years ago

New code dropped. Mind checking out the GNSS example to see how RTC/GNSS interaction works ?

hallard commented 4 years ago

@GrumpyOldPizza Thanks, I see lot of changes on new code. Got some boards on field for testing, if I'm not using GNSS for these boards, may I take a risk using these changes? I mean they just use LoRa, TimerMillis() and STM32L0.stop() are you confident with the changes because RTC part has changes?

GrumpyOldPizza commented 4 years ago

Those changes are part of some ongoing rework, which is not done yet (hence no 0.0.11 version for download yet).

"confident" is a good question. A lot of this has been stress tested quite a bit (way more than the code it replaced). There were some issues with stm32l0_rtc.c internally, which I'd hope this code fixes. So it would be important for me to get feedback, whether those problems are gone now. One of the interactions that were fishy originally was the GNSS / RTC interaction (which you cited was a problem for you).

On Mon, Apr 27, 2020 at 6:06 AM Charles notifications@github.com wrote:

@GrumpyOldPizza https://github.com/GrumpyOldPizza Thanks, I see lot of changes on new code. Got some boards on field for testing, if I'm not using GNSS for these boards, may I take a risk using these changes? I mean they just use LoRa, TimerMillis() and STM32L0.stop() are you confident with the changes?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/issues/126#issuecomment-619942205, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABXBA7BHKR5S623UTHG4OV3ROVYMFANCNFSM4MO3XPKQ .

hallard commented 4 years ago

Ok, I'll try that.

just saw your new code on sample, I think I can test the RTC.status() & 0x02 to see if it RTC time has sync but not sure what the RTC.status() & 0x08 is for?

    if (RTC.status() & 0x02) {
        Serial.print(", TIME-SYNCHRONIZED");
    }

    if (RTC.status() & 0x08) {
        Serial.print(", UTC_OFFSET-SYNCHRONIZED");
    }
GrumpyOldPizza commented 4 years ago

Ok, that should not have been there. Looks like I forgot to update the proper APIs into the github.

Anyway for now (at this level of the code):

Bits 0-1: 0 == default GPS TIME (or nothing written), 1 == NVRAM GPS TIME (or user written) 2 == GPS TIME from GNSS / LoRaWAN

Bits 2-3: 0 == default UTC OFFSET (or nothing written), 1 == NVRAM UTC OFFSET (or user written), 2 == UTC OFFSET from GNSS

The APIs were supposed to be RTC.getGpsEpochVilidity() and RTC.getUtcOffsetValidity() ...

A GNSS (or LoRaWAN 1.0.3) sync the GPS TIME. But to get to UTC (and UNIX EPOCH and Y2K EPOCH) you need to subtract the UTC OFFSET (or leap seconds, but leap seconds is a TAI related term). So if they decide to inject a leap second on 12/31/2020 23:59:59 then things will be off. So the GNSS code tracks also properly the UTC OFFSET.

So the examples just show you when the GNSS thinks it has which time locked (it's a tad more complex internally as the GNSS gets the "time of week" pretty quickly, but needs to resolve the week number later; this is why it might emit a seemingly correct data/time before it tells you it had synchronized it).

On Mon, Apr 27, 2020 at 7:04 AM Charles notifications@github.com wrote:

Ok, I'll try that.

just saw your new code on sample, I think I can test the RTC.status() & 0x02 to see if it RTC time has sync but not sure what the RTC.status() & 0x08 is for?

if (RTC.status() & 0x02) { Serial.print(", TIME-SYNCHRONIZED"); }

if (RTC.status() & 0x08) { Serial.print(", UTC_OFFSET-SYNCHRONIZED"); }

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/issues/126#issuecomment-619972479, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABXBA7F367JQQVH77QPZ5ZLROV7FVANCNFSM4MO3XPKQ .

UT2UH commented 4 years ago

I am ready to verify any changes to GNSS library - if you add support for Ublox I2C(DDC) interface!.. ) With STM32L0 limited pin number it can be interesting to many users of your core. Right now I have to use NeoGPS library to get NEO-M8N on I2C.

GrumpyOldPizza commented 4 years ago

GNSS via I2C is coming up.

HOWEVER it will require EXTINT to be hooked up. And using the idea to control the power to the chip via a LDO is not usable if you have other I2C slaves on the bus.

On Wed, Apr 29, 2020 at 9:38 AM UT2UH notifications@github.com wrote:

I am ready to verify any changes to GNSS library - if you add support for Ublox I2C(DDC) interface!.. ) With STM32L0 limited pin number it can be interesting to many users of your core. Right now I have to use NeoGPS https://github.com/nseidle/NeoGPS library to get NEO-M8N on I2C.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/GrumpyOldPizza/ArduinoCore-stm32l0/issues/126#issuecomment-621292083, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABXBA7ERHGPVYWACWE7WDX3RPBCV5ANCNFSM4MO3XPKQ .

UT2UH commented 4 years ago

Of course my board has an option to connect both EXTINT to control the power and PPS pin of Ublox. ) Ready for any experiments! Regarding the way of informing what component is valid please look at the way it is done in this library ezTime - it would be great to have look-a-like functionality but with GNSS instead of NTP.

GrumpyOldPizza commented 4 years ago

Can I go ahead and close this issue ?