I’ve been messing about with the Pi Zero W and one of my RasPiO InsPiRing boards to make a colourful clock that keeps accurate time using NTP (Network Time Protocol). Because the Zero W has WiFi onboard, it’s perfect for things like this. It’s quite a visual thing, so I made a video about it…
Here’s the Code
If you want a walk-through of the code, I made a little walk-through video of it, but decided to keep that separate because not everybody would want that level of detail. You can find that after the code.
import time
from time import strftime, sleep
from datetime import datetime
import apa # RasPiO InsPiRing driver class
numleds = 24 # number of LEDs in our display
brightness = 0xE5 # 224-255 or 0xE0-0xFF
ledstrip = apa.Apa(numleds) # initiate an LED strip
ledstrip.flush_leds() # initiate LEDs
ledstrip.zero_leds()
ledstrip.write_leds()
print ('Press Ctrl-C to quit.')
try:
while True:
timenow = datetime.now().strftime('%H%M%S.%f').rstrip('0')
hour = int(timenow[0:2])
if hour >= 12:
hour = hour - 12
minute = int(timenow[2:4])
second = float(timenow[4:])
print(hour, minute, second)
ledstrip.led_set(hour*2, brightness, 0, 0, 255) # 3 Red LEDs for the hour
ledstrip.led_set(hour*2+1, brightness, 0, 0, 255)
if hour == 0:
ledstrip.led_set(23, brightness, 0, 0, 255)
else:
ledstrip.led_set(hour*2-1, brightness, 0, 0, 255)
precise_minute = float(minute + second/60.0)
ledstrip.led_set(int(precise_minute / 2.5) , brightness, 0, 255, 0) # green minute
ledstrip.led_set(int(second / 2.5) , brightness, 255, 0, 0) # blue second
ledstrip.write_leds()
# Now blank the LED values for all LEDs in use, so that if any values
# change in the next loop iteration, we've cleaned up behind us
ledstrip.led_set(int(second / 2.5) , brightness, 0, 0, 0)
ledstrip.led_set(int(precise_minute / 2.5) , brightness, 0, 0, 0)
ledstrip.led_set(hour*2+1, brightness, 0, 0, 0)
ledstrip.led_set(hour*2 , brightness, 0, 0, 0)
ledstrip.led_set(hour*2-1, brightness, 0, 0, 0)
time.sleep(0.03) # limit the number of cycles to ~33 fps
if minute == 59 and int(second) == 59: # Red wipe hourly
for i in range(numleds):
ledstrip.led_set(i , brightness, 0, 0, 255)
ledstrip.write_leds()
sleep(0.03)
sleep(0.25)
for i in range(numleds):
ledstrip.led_set(i , brightness, 0, 0, 0)
ledstrip.write_leds()
elif minute == 29 and int(second) == 59: # Green wipe half-hourly
for i in range(numleds):
ledstrip.led_set(i , brightness, 0, 255, 0)
ledstrip.write_leds()
sleep(0.03)
sleep(0.25)
for i in range(numleds):
ledstrip.led_set(i , brightness, 0, 0, 0)
ledstrip.write_leds()
# Blue wipe quarter-hourly
elif (minute == 14 or minute == 44) and int(second) == 59:
for i in range(numleds):
ledstrip.led_set(i , brightness, 255, 0, 0)
ledstrip.write_leds()
sleep(0.03)
sleep(0.25)
for i in range(numleds):
ledstrip.led_set(i , brightness, 0, 0, 0)
ledstrip.write_leds()
finally:
print("/nAll LEDs OFF - BYE!/n")
ledstrip.zero_leds()
ledstrip.write_leds()
I’ll pre-empt those who are going to tell me that the animations (53-81) could be made into a single function. I know that. I just haven’t got ‘a round tuit’ yet. Here’s the code walk-through video…
If you find this interesting, you’ll probably like the RasPiO InsPiRing KickStarter. Please pop over and have a look.
Looks lovely, that. Practical, blinky and colourful. :-D
Ta. Yep. Ticks all my boxes.
LEDS
BRIGHT
BLINKY
COLOURFUL
PROGRAMMABLE
What more could anybody ever want?
why not using the object returned by datetime.now() ? it already provides .hour, .minute and .second as numeric. No need for string manipulations.
You’re right. Thanks for pointing that out. I dug a bit deeper into datetime() I didn’t know those were hiding there :)
I’ll make some tweaks to the code.
What is the licence for your code?
Did you share your library already?
Line 41-49: Why don’t you clear all pixel?
Line 49 is wrong compared to Line 30.
There is so much to say or fix in this code… of only you open source it. :-)
I’m not ready to publish the class yet. When I do it will be on a CC-BY-NA-4 I think (not fully decided).
I don’t think you watched the second video where I explained how the code works and how the “blanking” works. Although I didn’t mention that these are not WS2812 so do not have to be pulsed regularly. They are APA102 and stay set at last setting until they get the next setting. 41-49 resets the led values in the list to zero, but that is not sent to the LEDs until the next iteration of line 39. It’s only done so we can clean up after ourselves if in the next frame we’re writing to the next LED in the sequence.
The code works.