This clock gets the time from the Internet using the ESP32's built-in WIFI and sets the built-in real time clock. It displays the time on a big 8 x 32 RGB LED matrix.
Two years ago I built this clock using the Adafruit HUZZAH32 - ESP32 Feather. I programmed it in Arduino C. I used an external DS3231 real time clock and a small DC-DC converter to power the ESP32 at 3.3 volts and the display at 5 volts.
This new version uses Arduino's new Nano ESP32 and is programmed in Python. But that's not the only change. I'm using the built in RTC on the Nano ESP32, and I am running the display directly off the Nano's 3.3 volt supply. That's possible because 1) to my surprise, the 5 volt display seems very happy running on 3.3 volts. and 2) only a few of the panel's LEDs are on at any one time, and I am powering them at less that 10% of their full brightness, so the display only draws a few milliamps.
This new clock is programmed in Micro-Python! I used the new Arduino Lab for Micro-Python, which is still in Beta version. I am not proficient with Python, so I thought it would be fun to try something new. It also gave me an opportunity to make several minor improvements to the original design.
One comment I should make about the Lab of Micro-Python is that it does not save program changes when you run the program. I am so use the Arduino's regular IDE saving my work automatically that I lost changes several times by forgetting to SAVE.
HardwareThe hardware in this project is amazingly simple! A 9 volt brick power supply provides power to the Nano ESP32. The Neopixel display has three pins: power, data, and ground. Power is supplied from the Nano 3.3 volt pin and data comes from ESP pin 9 (Arduino D6). That's it!!
If you build this clock, you will need to enter a few items of your own into the software. It needs your WiFi credentials and also your time zone offset from GMT. Also, there are a couple of lines of code that convert the 24 hour clock to a 12 hour clock. If you want the 24 hour clock, simply comment out those 2 lines.
This project is really about the software. There's a lot going on. I was pleasantly surprised, as a novice Python programmer, that it was fairly easy to convert my previous C software into appropriate Python code. The Python libraries for network, time, ntptime and neopixel made a huge difference. They made all the difficult tasks relatively easy - like connecting to the Internet, setting the RTC, and controlling the LED display.
One of the nice features of this clock is that is sets itself and stays very accurate. The network library facilitates establishing an Internet connection. The ntptime library gets NTP time from an NTP server and uses it to set the built-in Real Time Clock. The time library reads the RTC and provides hours, minutes, seconds.
With our Python code running through Arduino's Lab for Micro-Python, the program will confirm its connection to the Internet, as well as print out the time once per second. This output is useful for debugging and can demonstrate most of the functionality without even needing the LED display.
I don't know much about the quality or accuracy of this RTC. It seems to keep perfect time for several hours, but I didn't test it long term. Instead, I built in a re-set to NTP time every 24 hours. So at 02:02:02 every night, my clock gets NTP time again. That should keep it always accurate to within a few milliseconds!
To put the time on our LED display, we need an appropriate font. Our 5x8 pixel font, digits 0-9 are contained in an array called num. In my original design two years ago, I set up the content of the display in a buffer in RAM and then transferred the content of the buffer periodically to the display. But a Neopixel display itself is fully capable of storing its own content, so this time I am writing the digits (and the blinking colon) directly into the display. The software to do this is a little tricky, because the display is a linear strip of LEDs that winds up and down across the face of the display. The neopixel library doesn't itself support addressing the LEDs by their x, y coordinates. We need to do that in software to get our font onto the display.
Our display only has enough room for hours and minutes, but I wanted to do something with seconds, so there is a blinking colon that shows seconds. Also the display changes color over the course of a minute, starting out green, transitioning to blue and then to red, before returning to green when the minute changes. The color changes every 5 seconds.
Other InformationA couple of things specific to Python are worth noting here. Even though the Nano ESP32 is an Arduino and pins are assigned and labelled like all Arduinos, i.e., D2, A0, etc., Python refers to pins by their ESP32 GPIO number. So pin D6 is called pin 9, as shown on the Pinout table.
Also, we need our clock program to run at startup. In Python, that is accomplished by naming the program main.py and storing it on the ESP32 next to the boot.py file. Arduino Lab for Micro-Python has two file directories - one for programs on the user's computer and a second in the Nano's Flash memory, so setting it up to run at startup is very straight forward. Simply copy the program and store it on the Nano as main.py
I hope my Python code is clear and understandable. An experienced Python programmer can probably point out a better way of doing some things. I'd be happy to hear from them.
Comments