If you are a geek, a wordclock or work clock would mean a clock signal used to synchronize other devices, like digital audio tape machines and compact disc players.
A word clock can also mean a clock whose entire clock face consists of words, and the current time is presented by highlighting some of the words to form a sentence that spells out the time.
"IT IS QUARTER PAST EIGHT AM" or "IT IS FIVE MINUTES TO TWELVE O'CLOCK"
They say a picture is worth a thousand words. Here is the word clock, simply explained!
The un-highlighted words are in RED and the highlighted words are in BLACK and spell out the time "IT IS TWENTY MINUTES TO FIVE PM"!
In this project, I use the Waveshare Tri-color ePaper Display, a Raspberry Pi (I use the Model 4B here) and a ProtoStax Enclosure for Raspberry Pi B+/4B to make a table top word clock written in Python.
Step 1 - Set up Raspberry PiThe Waveshare ePaper Display uses SPI for communications. We therefore need to enable SPI on the Raspberry Pi, if you haven't already done so.
Steps to Enable SPI
Launch raspi-config. Go to "Interfacing Options". Navigate to SPI and press enter. Say yes when asked if you would like the SPI interface to be enabled. See steps below in the slideshow - the caption for each image is numbered and gives additional explanation for each step.
Install the ProtoStax Work Clock Demo code from the GitHub Repository (link below)
$ git clone https://github.com/protostax/ProtoStax_Word_Clock.git
This installs the demo code as well as the requisite Waveshare ePaper library.
Step 2 - Double-check that the SPI interface is workingSome people have encountered issues where the SPI interface doesn't get enabled properly.
Double check that SPI is actually "on" in your /boot/config.txt. Search for an entry like the following:
dtparam=spi=on
And check that you can see the SPI device connected:
$ ls /dev/spi*
/dev/spidev0.0 /dev/spidev0.1
should show something! (like /dev/spidev0.0 /dev/spidev0.1 above) If it doesn’t, try sudo rpi-update and reboot.
If SPI has been properly enabled, the /boot/config.txt entry should show up as above AND you should also see the device connected when you list the SPI devices.
Step 3 - Install other pre-requisitesThe code expects Python 3+ - if you are using an older version of python, you will need to install python3
The code also depends on other libraries. Install spidev, RPi.gpio and Pillow dependencies as follows:
$ sudo apt-get install python3-spidev
$ sudo apt-get install rpi.gpio
$ sudo apt-get install python3-pil
Step 4 - Run the Word Clockcd to the directory that was created with you cloned the git repository above.
$ cd ProtoStax_Word_Clock
Run the word_clock_paper.py python script
$ python3 word_clock_paper.py
If all the steps above have been done correctly you should see the Word Clock on your ePaper Display! It has a granularity of 5 minutes or more, so it updates every 5 minutes to show the new time.
Here is the clock in action (speeded up a bit):
I'm a firm believer in the adage "Teach a man to fish and you feed him for life"! Therefore, I'll also delve into the code and try to explain it.
The Waveshare ePaper Display library is installed under the sub-directory "lib" (so it is packaged along with the word clock code and you don't need to install it separately). It utilizes the PIL Image library to get the image buffer to show on the display.
I've tried to be object-oriented about the code. There are two distinct classes - one to encapsulate the Display related stuff (how to draw stuff on the display). This class utilizes the Image, ImageDraw libraries from PIL to render the buffer for the ePaper display to show.
The other Class is the Clock class - it encapsulates all the stuff needed to keep track of all the words of the Word Clock, including which words to highlight and which words to show un-highlighted (aka in "gray").
The Display class creates a Clock instance to keep track of all this.
The main function instantiates a Display class with the width and height of the ePaper display. It also instantiates the epd object from the ePaper library. It then goes into an endless loop where it does the following:
It gets the current time using
now = datetime.now()
It then passes the hour and minute information to the display class's drawClock() method. This method renders the word clock into two Image objects - one object containing the grayed out words and the other object containing the highlighted words.
These Image objects are then passed to the epd to display(). The epd library displays the first Image in Black, and the second Image in Red. I chose to display the gray words in Red, and the highlighted words in Black, for contrast and readability.
The script also has a "test-mode". You can provide the time in hour, minute and second as command line arguments. The script then runs exactly once, displaying the specified time on the word clock. This is useful for testing the logic. If there are no command line arguments to the script, then it runs endlessly in a loop, sleeping for 5 minutes, and then waking up and repeating the process.
The Display Class also has a method to display the gray letters as text outlines.
Going ForwardAs with all my other projects, I like to finish with "Going Forward" - with tips on how you can take the project further and experiment with more stuff and learn more!
You can try changing which letters gets displayed in black, and which get displayed in red. You can try out printing out the gray letters in outline mode. You can play around with the font and font size. Just note that it will be best to go with a Monospace font, so that all the characters occupy the same amount of space - otherwise, things may not display as expected and you'll have to play around with the spacing. The current logic assumes a monospace font and the display layout and coordinates use that logic by using multiples of a character width and height for laying things out appropriately.
You can also try changing the words and the word locations, once you get a hang of how it is done with the current array of words.
If you want even more advanced stuff, you can try optimizing the ePaper display times. Currently, I'm doing a full refresh every time. A full refresh is the best for keeping the display from developing ghost images, but it is ok to do a full refresh periodically instead of every single time. At the other times, you can do a partial refresh. This will make the display much faster.
Can you think of any more? Write a comment below to let us know! 😊 Feel free to also ask any questions you may have! 😊
Happy making! 😊
Comments