Do you like my hacking? If so, please consider leaving something in the
Fediverse (Mastodon etc): @Sprite_tm@social. spritesmods.com
The software would need to do a few things. The most important one would be to show the time, obviously. Depending the digit the hardware is configured at, it would need to wake up every minute, every 10 minutes, every hour, or three times a day (it's a 24-hour clock) to change what's shown on the display. It needs to do this with as low power as possible, and as mentioned before, I wanted to use the ESP32C6 low-power coprocessor for this. This coprocessor can run in deep sleep mode, using only a small amount of power when active. It's fairly capable as well: there's a RiscV core running at 20MHz with 16K of RAM and a dedicated UART and I2C master that it can use.
That 16K initially seemed a bit of an issue: the resolution of the E-ink display means that every image sent to it occupies about 12K, and given I need one for every digit, that would take up 120K of memory. Luckily, I could easily compress the graphics to fit: I created a version of RLE that records the number of pixels before the color changes from black to white or vice versa as a variable-length number. For the font I chose, that brought the storage needed down from 120K to a bit more than 11K, leaving around 4K for code. The image below attempts to explain it, but you may be better off looking at the code itself.
Aside from handling the graphics, synchronization also is really important. Given the uncompensated 32KHz crystal I'm using for timekeeping, the internal clocks of the modules could gain or lose a few seconds easily, but generally it's not that important if a clock is off by a few seconds or even a minute or so. But as the saying goes: 'A man with a watch knows what time it is. A man with two watches is never sure.'
In this case, the issue lies in changeovers. If the clocks of the four modules were to be out of sync, the clock might read the following sequence: '20:59' -> '20:50' -> '21:50' -> 21:00'. If you were to glance at the clock in one of the 'wrong' states, your idea of time might be off by ten minutes to an hour.
Given we have the full power of an ESP chip at our disposal, it's pretty easy to have them synchronize to NTP: not only will they run in sync that way, they'll also always run at the correct time. Unfortunately, doing a NTP sync can be pretty power-hungry: it requires the main CPU and the radio to work, and associating with WiFi, getting a DHCP request and contacting a NTP server can easily take ten seconds or more. Especially for the minutes digits, which already uses the most battery power of the bunch, this would drain the battery unacceptably fast.
So rather than doing that, I developed a different scheme. Synchronizing to a NTP server is still a good idea, so I had the ten-hours digit do that: as it only needs to wake up three times a day to change the number, it should have battery to spare. Then, every midnight it will wake up in a mode where it uses ESPNow to broadcast the current time. ESPNow is a very simple peer-to-peer communications mode that ESP chips have: it simply send packets to other ESP chips which are configured to receive them and doesn't require association with an access point. The other digits will also try to wake up around that time, receive the correct time, send an acknowledge and immediately go to sleep again. That way, all the other digits use as little power as possible to keep synchronized; all in all, I estimate it should take more than a year before I need to recharge the clock.