Word Clock with a Unicorn

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)

1 thought on “Word Clock with a Unicorn

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.