Description
Issue description
There are some major problems with the Arduino LMIC if you sleep the system for an extended period of time.
- The Arduino microsecond timer overflows in about 71 minutes.
- The conversion from microseconds to
osticks
goes crazy after about 15 minutes of idle or sleep time. ostime_t
is signed, and time stamps flip from past to future after about 9 hours of elapsed time.
These implementation limitations mean that the LMIC can get a fairly crazy ostime
value if the CPU has slept. This can (in turn) cause the LMIC to misinterpret globalDutyAvail
as being in the future rather than in the past (as it really will be).
This will lead to delayed transmit of uplink messages rather than sending at the time the user called the LMIC to send the message.
This issue can be seen because of below reasons.
- If no transmission for around 9 hours, the time calculations will overflow, because
ostime_t
is signed and the forward/past sense will flip. - If the
os_gettime()
is not called once every 17 minutes, time values will be wrong, and this may also cause timestamps to flip between "past" and "future".
Environment
- Applicable in all versions of LMIC
Quick fix
We have a quick fix by adding an API in the top-level application to fix LMIC time calculations which helps to sync the globalDutyAvail
with current LMIC ostime
. This will help to avoid the delayed transmission. Calling this API immediate after waking up from long sleep will help to do transmission on-time.
Please find the API below:
// This fix only works in the specific case where you're sure that you've been sleeping
// so long that any time delays that the LMIC is worried about are in the past.
//
void fixLmicTimeCalculationAfterWakeup(void) {
ostime_t const now = os_getTime();
// just tell the LMIC that we're available *now*.
LMIC.globalDutyAvail = now;
// no need to randomize
// for EU-like, we need to reset all the channel avail times to "now"
#if CFG_LMIC_EU_like
for (unsigned i = 0; i < MAX_BANDS; ++i) {
LMIC.bands[i].avail = now;
#endif
}
}
Updated by @terrillmoore -- splitting part of this out to a separate issue #927. The fix above doesn't help with #927, which is really independent of sleep.