A few days back I saw this article about a Word Clock that had been built using at ATmega328P and an 8×8 LED matrix. “Cool” I thought, I have bi-colour one of those in the “toy” box, I might have a go at that.
Around the same time, those pesky pirates Pimoroni were having their #yarrbooty twitter competition. I was fortunate enough to win a few rounds and decided to spend some of my booty on a Unicorn HAT and an A+. The Unicorn HAT is an 8×8 matrix of very bright RGB LEDs.
And low, the Unicorn Word Clock was born
The template for the words is just printed on a piece of white paper, cut to size. It’s slightly off but it’s not far out. The more adept amongst you may want to cut out a larger shape so it encompasses the entire case like a lid.
The code is fairly straight forward. I have defined lists of pixel co-ordinates for the minute phrases, which can then be combined (half + past, ten + to, etc). There is a function to determine the correct minute phrase, and one for the hour. Other than that, hopefully the comments will fill in any gaps.
The source and template can be found on GitHub
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | #!/usr/bin/env python # wordclock.py by Carl Monk (@ForToffee) # code is provided with no warranty, feel free to use. # no unicorns were harmed in the making of this code import unicornhat as UH import time #global variables hourPattern = [] minPattern = [] #pre-defined patterns - groups of x,y co-ords - 0,0 is bottom right with GPIO at bottom fivePattern = [[7,6],[6,6],[4,6],[2,6]] tenPattern = [[1,7],[1,6],[0,6]] fiftPattern = [[7,6],[6,6],[5,6],[3,6],[2,6],[1,6],[0,6]] twenPattern = [[5,7],[4,7],[3,7],[2,7],[1,7],[0,7]] halfPattern = [[7,7],[6,7],[7,5],[6,5]] pastPattern = [[4,5],[3,5],[2,5],[1,5]] toPattern = [[1,5],[0,5]] #function to light the pixels we need to display the time #pixels is a list of pixels def showTime(pixels): UH.clear() for coords in pixels: UH.set_pixel(coords[0],coords[1],255,0,255) #magenta UH.show() #once pixels set, call .show() to enable them #function to light the '*' character to show seconds and minutes elapsing def showTick(m): colour = [] minPart = m % 5 # % is modulo which gives us the remainder of m divided by 5 # this tells us the value 0 - 4 or the part of 5 minutes the time is if m == -1: # for setting the '*' off or black colour = [0,0,0] elif minPart == 0: #:m0 or :m5 colour = [255,0,0] #red elif minPart == 1 : #:m1 or :m6 colour = [0,255,0] #green elif minPart == 2 : #:m2 or :m7 colour = [0,0,255] #blue elif minPart == 3 : #:m3 or :m8 colour = [255,255,0] #yellow elif minPart == 4 : #:m4 or :m9 colour = [0,255,255] #cyan UH.set_pixel(5,5,colour[0],colour[1],colour[2]) #5,5 is the position of '*' UH.show() #takes the current hour and provides the required pattern of letters def getHourPattern(h,m): global hourPattern hourPattern = [] #convert 24hr into 12hr if h >= 12: h -= 12 #if minutes > 35 then display will be 'to' the next hour if m >= 35: h = h + 1 #special case for 11:35 - 12:00. Hour is 0 to 11 so need to reset to 0 if h == 12: h = 0 if h == 0: #aka Twelve hourPattern = [[7,2],[6,2],[5,2],[4,2],[2,2],[1,2]] elif h == 1: hourPattern = [[7,3],[6,3],[5,3]] elif h == 2: hourPattern = [[7,2],[6,2],[6,1]] elif h == 3: hourPattern = [[4,3],[3,3],[2,3],[1,3],[0,3]] elif h == 4: hourPattern = [[7,1],[6,1],[5,1],[4,1]] elif h == 5: hourPattern = [[3,1],[2,1],[1,1],[0,1]] elif h == 6: hourPattern = [[7,0],[6,0],[5,0]] elif h == 7: hourPattern = [[4,0],[3,0],[2,0],[1,0],[0,0]] elif h == 8: hourPattern = [[4,4],[3,4],[2,4],[1,4],[0,4]] elif h == 9: hourPattern = [[7,4],[6,4],[5,4],[4,4]] elif h == 10: hourPattern = [[0,4],[0,3],[0,2]] elif h == 11: hourPattern = [[5,2],[4,2],[3,2],[2,2],[1,2],[0,2]] #takes the current minute and provides the required pattern of letters def getMinutePattern(m): global minPattern minPattern = [] if 10 > m >= 5 or m >= 55: minPattern = fivePattern elif 15 > m >= 10 or 55 > m >= 50: minPattern = tenPattern elif 20 > m >= 15 or 50 > m >= 45: minPattern = fiftPattern elif 25 > m >= 20 or 45 > m >= 40: minPattern = twenPattern elif 30 > m >= 25 or 40 > m >= 35: minPattern = twenPattern + fivePattern elif 35 > m >= 30: minPattern = halfPattern #if time between 5 and 34 we need to show 'past' the hour if 35 > m >= 5: minPattern = minPattern + pastPattern elif m >= 35: #otherwise 'to' the hour minPattern = minPattern + toPattern #cycle through a full 12hrs minute by minute def fullTest(): for n in range(12*60): getHourPattern(n / 60, n % 60) getMinutePattern(n % 60) showTime(minPattern + hourPattern) showTick(n) time.sleep(.25) #cycle through hours, then minutes def quickTest(): for n in range(12): getHourPattern(n, 0) showTime(hourPattern) time.sleep(.5) for n in range(60): getMinutePattern(n) showTime(minPattern ) showTick(n) time.sleep(.25) #main function quickTest() while True: #get time parts h = time.localtime().tm_hour m = time.localtime().tm_min s = time.localtime().tm_sec #get patterns getHourPattern(h, m) getMinutePattern(m) #show patterns showTime(minPattern + hourPattern) #flash '*' to show time passing, lit every 2 seconds if s % 2: showTick(m) else: showTick(-1) time.sleep(1) |
So simple – gives me hope!