Why an external RTC is needed with the Newt

A project log for Newt: Always On, Low Power Digital Assistant

An always-on digital assistant that fits on a desk/nightstand/mirror/wall/fridge. Weather, alarm, timer, calendar, habit tracker, to-do list

Darian JohnsonDarian Johnson 10/02/2021 at 14:360 Comments

As I mentioned in an earlier post, the Newt uses an external Real Time Clock (RTC), specifically, the Mirco Crystal RV-3028. Some people may wonder why an external RTC is needed for an ESP32s2, since those microcontrollers come with an internal RTC. Well, there are a few reasons:

Need to add a crystal for accuracy

The internal RTC looses seconds when a crystal is not used. I could have added a crystal to the PCB, but that would have (a) reduced the number of available pins and (b) made use with Arduino or Circuit Python slightly more complex (I wanted to create a device that was "accessible" to a novice developer).

The internal RTC can operate without a crystal, but it looses seconds. This loss is exacerbated when the device goes into deep sleep. I ran a test with my ESP32s2, comparing the internal RTC with the external RTC. The device sleeps for 60 seconds, prints the time from the internal and external RTC, then returns to sleep.

Comparison at start: 22:46:31.453 -> Sunday, March 14 2021 22:46:31

Comparison 23 hours later: 21:18:00.583 -> Monday, March 15 2021 21:47:18

As you can see, we lose 13 seconds in a day... that's a minute in week, and a 4-5 minutes over a month.

Of course, you can always sync the time - but that takes a wifi call. The Newt is built for low power, so we want to minimize any unnecessary wifi calls.

Timezone craziness

The other reason an external RTC - and specifically the RV-3028 - is useful in this build is around timezone management - especially when it comes to daylight saving time changes. The RV-3028 is able to store the UNIX time separate from Local time. For example:

The Unix time at this moment is 1633184251 (this represents the number of seconds since Jan 1, 1970 in UTC). The local time equivalent (for Dallas, TX) is Saturday Oct, 02 2021 09:17:31 GMT-0500 (Central Daylight Time).

Unfortunately, in 2 weeks, Dallas will be in Central Standard Time, and the offset from UTC will be 6 hours, not 5 hours. So if I hardcode an offset in my code, then my time will be off.

However, using the UNIX time with the ESP32 "setenv" command allows me to adjust the time based on the specific month/day/time. ESP32 use the POSIX format to define the timezone. Here is the format for Dallas, TX (America/Chicago): CST6CDT,M3.2.0,M11.1.0.

Here's the breakdown of the format (from IBM developer website):

So, in short, I can use the UNIX time from the RV-3028, calculate the local time with the ESP32 "setenv" command, then save that local time in the Local Time register of the RV-3028 - all without making a series of wifi calls!