Hello,
We require real time clock capabilities for our product with an acceptable drift of several minutes per year. We are currently evaluating using solely the nRF5340 with an external 32.768kHz crystal oscillator to do this (with an nRF5340-DK). We could use an RTC chip but would prefer to avoid it if possible (more complexity, board space, cost). I know that others have found success doing this using just the external oscillator. I wrote a demo that uses UNIX time passed through BLE as the base time, then uses the uptime retrieved from k_uptime_get() to keep time relative to the base time. I didn't add anything related to the clocks in the prj.conf, or change any board files/add any overlay, the code is running with the default board files for the nRF5340-DK. The problem is that this code has a drift of about 10 seconds/day behind real time, which is unacceptably high. Here is the relevant timekeeping section, where unix_time is set through BLE:
int64_t uptime = 0; int64_t elapsed_time = 0; int64_t unix_time = 0; int64_t uptime_last = 0; int main(void) { ble_init(); while (true) { // Update times uptime_last = uptime; uptime = k_uptime_get(); elapsed_time = uptime - uptime_last; unix_time += elapsed_time / 1000; k_msleep(1000); } return 0; }
- One cause of this inaccuracy could be that k_uptime_get() is using the internal RC oscillator by default, not the external crystal oscillator, which is much less accurate. Can anyone confirm if this is the case, and if so how to tell Zephyr to use the external crystal oscillator instead?
- Is there a better way to do this that would be more accurate?