Last week saw some exciting new features being implemented in the clock repo on GitHub. I finally added all the things I mentioned I wanted to add in a previous project log: ad hoc setup, a settings webserver, better networking, and improved NTP.
Ad hoc setup uses the WiFiManager library, which has some issues but is working well enough considering it's only at version 0.4. I'll probably contribute to the project soon.
The settings webserver seemed easy, and it was until I tried to send the full list of 417 timezones. I figured out that it was running into a segfault when trying to construct the page dynamically. I tried several things, but the best solution was to simply serve a static page from the SPIFFS filesystem. It still fails to serve the page intermittently now, but I'm still debugging that issue. I also implemented a simple observer design pattern in the settings class itself to make it easy to hook into.
Settings page screenshot:
On the networking side, I added retries and exponential backoff to make sure it doesn't inundate the receiving server with endless requests in case something goes wrong.
The improved NTP implementation took the longest and the most research. Most of the available documentation is intended to provide background for users of ntpd, not for people who want to write their own NTP implementation. Eventually, I found and fixed several errors in my previous assumptions about the timestamp and packet formats. Since the Time library I'm using doesn't support sub-second accuracy, I also made the synchronization code wait until the start of a new second before updating the time rather than simply rounding the fraction. In my basic eyeball testing, it's now synchronized perfectly to my Apple Watch with no perceptible drift over 4 hours (the time between synchronizations).
In addition to all of those features, I realized once I added the color and brightness settings that the colors were wrong when not at full brightness. Turns out that I had forgotten to apply gamma correction. Adafruit explains it very well, so all I will say is that if you use an LED in your project and you want it to display colors or relative brightness accurately, you must use some form of gamma correction. I'll definitely keep this in mind in future lighting projects.