Picture Frame LED Clock Using ESPHome
804 Views, 6 Favorites, 0 Comments
Picture Frame LED Clock Using ESPHome

What can you build from a 60 LED ring? A clock obviously, and there are quite a few designs available from instructables, but I felt a strong urge to design my own.
First the design should aesthetically fit my home, and not be too hard to construct without 3d printer and a full blown workshop. A square picture frame would serve well. My wife found me one at a vintage shop for 1 euro. If you are not that lucky, they are quite affordable new.
Second, I'd like the to use ESPHome for this clock. ESPHome allows for integration with Home Assistant to control the clock. For standalone usage, ESPHome offers an easy to use access point to setup wifi parameters, and a simple web server to control the clock.
Third, I didn't like the simple analogue clock design too much. I started experimenting on different ways to show time and quickly discovered that adding an inner ring would open up a lot of possibilities.
So I added a 48 LED ring which tightly fits inside the 60 LED ring. This is where things got really interesting:
- a 48 LED ring is perfect for showing the hour hand as it naturally shows quarter to, quarter past and half past the hour (12*4=48).
- given the hour hand on a real analogue clock is shorter, the inner ring is the obvious place for the hour hand.
- it is easier to read the time with seperate rings for hour and minute hands
In the code for my clock I added watchfaces without ticks that are still easy to read (and more beautiful IMHO).
Features:
- Using RTC, no loading time
- Supports a second (inner) ring for the hour hand
- Automatic brightness with light sensor
- Three watch face animation types:
- Classic Analog: the analog clock with ticks and a wide hour hand
- 5min Arc at Hand: shows a dim arc for the 5min interval for each hand
- Arc from Top to Hand: shows a dim arc from top to the hour/minute hands
- Settings in web_server or Home Assistant
- Select colors and effects
- Enable/Disable fade out and second hand
The code for this clock works equally well with 60+48 LED rings as well as a single 60 LED ring.
Adding an RTC helps to boot fast, without it you need wifi connected and a NTP server reachable. An light sensor to automatically control brightness is a really nice to have. Both connect via I2C and are optional.
Supplies
Clock Frame:
- Square picture frame minimal sized 20x20cm. Allow at least a cm space at the back to host the electronics. Eg IKEA sannahed 25x25cm (about 7 euro).
- a sheet of acrylic glas that fits the picture frame. This might come with the picture frame. I used a piece of Acrylcolor Gray (eg. Gutta, available at diy stores like Hornbach, about 7 euro for 50x25 cm) to fit the black color of the frame.
- a diffuser sheet that fits the picture frame. I used plain 80gr/m2 paper (almost free).
- additional mounting material, depends on how the picture frame is constructed. For IKEA sannahed:
- a mounting board 25 by 25 cm of 3-4mm (MDF, hard board) Hornbach
- four suspenders lenght 24.5cm 1 by 4 cm (wood, MDF, ...)
- tape, double-sided tape, double side foam tape
Electronics:
- 60 LED ring tinytronics.nl / aliexpress
- 48 LED ring (optional) tinytronics.nl / aliexpress
Note it is important to use the same addressable LED chip for both rings
- Wemos D1 mini v4 (anything ESPHome supports) tinytronics.nl / aliexpress
- USB power supply 10 Watt tinytronics.nl / aliexpress
- 3 pin female header (pre-wired if you like) tinytronics.nl / aliexpress
- 3 pin angled header tinytronics.nl / aliexpress
Optional electronics:
- preassembled qwiic cable, a.k.a. STEMMA QT or 4 pin jst-sh female (optional) tinytronics.nl / aliexpress
- ds1307 attached with qwiic connector (optional) tinytronics.nl / aliexpress
- bh1750 light sensor chained to rtc (optional) tinytronics.nl / aliexpress
- simple small enclosure for electronics, e.g. 65x38x22mm (optional) tinytronics.nl / aliexpress
Tools:
- saw to cut thin board and acryl. Low accuracy is ok, because picture frame overlaps
- something to make one 20 mm hole: wood drill size 20. Punching/cutting would work, low accuracy here as well.
- soldering iron, a bit of thin soldering tin
Code:
- github project ESPHome-Ring-Clock
- if you're not using Home Assistant, follow guide to Install ESPHome Manually
- a Linux/Windows/Mac computer. Home Assistant install requires Chrome or Edge.
Note: product links are provided for reference, I am not affiliated with tinytronics.nl nor aliexpress.
Set Up Microcontroller
If you use ESPHome for the first time on your microcontroller device, connect it to your computer with a USB cable. Later uploads can use OTA. Please never connect the LED ring while uploading firmware with USB, it potentially light all LEDs at maximum brightness, which will overload your computers' USB port and potentially cause damage to it.
In Home Assistant, go to ESPHome compiler, click 'Add Device' and follow on-screen instructions. Note: at some point this requires USB serial access from your browser, you might need to change permissions and/or use a specific browser (Chrome or Edge), google is your friend. As soon as the device is adopted you can start creating a configuration YAML file as per below.
In ESPHome standalone, create a directory for your project. Retrieve files or clone from https://github.com/umask007/ESPHome-Ring-Clock
Create a secrets file using secrets.yaml as a template.
Create a new ESPHome configuration YAML file using one of the examples esphome_ring_clock.yaml as a template. Customize the basic device configuration (Leds, Board, WiFi, pins, time zone, RTC, light sensor etc.) to your liking.
Copy ring_clock.h to Home Assistant in the esphome folder, or to your project directory if using ESPHome standalone.
Finally compile and install your configuration via USB. Using ESPHome:
It should upload the code, don't worry about errors now. Subsequent installs can be done over the air (OTA).
Now it is time to heat up your soldering iron.
Connect Electronics








Before installing everything into the picture frame, we connect and test electronics. First prepare the LED rings:
- solder the angled header to the DI, 5V and GND pads of the 60 LED ring.
- position the second ring, keep it in place with pieces of tape and use small wires to connect as per above picture. Make sure to use a small loop to allow repositioning the rings.
- 5V to 5V (red wire on picture)
- GND to GND (blue wire on picture)
- DO (of 60 LED ring) to DI (of inner ring) (white wire on picture)
Connect 10cm wires to the 3 pin header connector and solder them to the microcontroller:
- pin 1 corresponds to DI on the outer LED ring and RX on ESP866.
- pin 2 corresponds to 5V on the outer LED ring and Vbus on ESP866.
- pin 3 corresponds to GND on the outer LED ring and Gnd on ESP866.
A pin header connector usually has a mark for pin one, mark the LED ring as well to avoid reversing it.
Use pieces of tape to hold the rings together for now.
If you use a RTC and/or a Light Sensor, connect them via I2C. If using qwiic, cut wires to desired length (ca 6 cm) and solder to the RTC. Daisy chain the light sensor.
Note: some cheap RTC boards need a modification to prevent charging the lithium cell. Mine required removing a diode. Google to be sure.
Note on power: either use 10W USB power supply, or a 5V 2A power supply. On USB, leds are fed from the Vbus pin, but likely it will suffer when two rings have all LEDs at full white, full brightness. A more robust setup is to add two wires to 5V and GND connections and attach a 5V 2A power supply to it. Then make sure to never connect both the USB and the 5V power supply at the same time (it is much cheaper to light essence sticks if you like the smell).
Prepare an enclosure for the electronics: try the fit, create a hole for the USB connector if needed, and apply tape to protect against short-circuit.
After double checking power connections, it is time for the truth: power it up. The microcontroller on-board led should light. If not, disconnect immediately and double check better, or try without LEDs.
If the clock doesn't show at "http://<device-name>.local", you might want to connect the USB cable to a computer to check logs. Remember to disconnect the LED rings while uploading the firmware.
Using RTC, the clock should immediately show some time (the actual time if it managed to reach ntp servers). Otherwise wait up to a minute. The hard part is done, congratulations!
Assemble Picture Frame








Now it is time to prepare the picture frame to host the clock. The major effort goes to making the LEDs and PCBs barely visible when not emitting light.
I got good results using 4 mm 20% transparent gray acryl and a sheet of printer paper (80 grams/m2). The paper doubles as a diffusing foil. Note this reduces outgoing light with a factor 25 (!). This is actually not an issue because the minimum brightness is still quite bright. Experiment a bit if you can get hold of better diffusing foils etc.. Experiment before cutting sheets and boards to the right size.
You will end up with a stack of the following items:
- (semi)transparent front sheet
- diffusing sheet (paper)
- leds
- mounting board
- suspenders
- back panel
The suspenders make sure that everything is tightly kept in place after securing the back panel.
For very thin frames, you might not need a mounting board and suspenders. In that case the LED rings and electronics will be mounted on the back panel.
Cut the boards and sheets to size. Check if they fit the frame.
The mounting board needs to be prepared for the LEDs:
- draw alignment lines for the 12/3/6/9 hour LEDs
- mark where the pin header sticks through
- create a hole for the pin header and the wires (drill, punch, cut) of about 20 mm
- Optional, not on pictures: a hole for the light sensor.
Then mount the LED rings to the mounting board:
- apply double-sided tape to the back of the led rings. Don't remove the protective paper for the inner ring yet (or remove and stick back on so it can be removed easily later).
- position the outer ring on the mounting board, make sure the connector and wires fit the hole, and firmly press to permanently stick it to the board.
- then carefully align the inner ring at the 12/3/6/9 hour positions. Use a ruler, your carpenter's eye, anything. The picture shows ill aligned LED rings
- remove the remaining protective paper and firmly press to bond well.
Empty the frame, remove dust, and assemble all layers. Finally mount the suspenders with a few bits of double-sided tape and mount the back panel. Create a recess for the usb cable if needed. Add a cable strain relief if needed.
Install and Configure
Power the clock. You can reach it using any browser at "http://<device-name>.local" (or as a device from Home Assistant). Tweak its settings to your liking, be aware that not all settings are persistent. If you want other defaults, update the yaml file and re-deploy.
If 12 o'clock is not at the top, you can rotate/offset each ring individually in the yaml file and re-deploy:
Eg, to rotate 90 degrees CW, use {15,12}. Use positive values (e.g. {59,47} to rotate 1 led CCW).
If you start using the clock somewhere else, your wifi credentials won't be valid. ESPHome provides improv, it will start an access-point which you can connect to to enter new wifi credentials. Note: my code doesn't include improv-serial to do the same via a USB cable.
License and Credits
This is not really a step.
The ESPHome-Ring-Clock code is licensed CC0, which is almost no licence. Do what you like to do, but do no harm.
The esphome-ring-clock code is based on Markus Ressel's ESPHome-Analog-Clock. I changed too many things, commiting back to his code would be a coup d'etat.
ESPHome is a wonderful framework that helped me a lot to implement sophisticated features while it is still easy to use.