I just recently got my first Unicorn Mini and had some fun coding on it, and want to share what I came up with. The main code is borrowed from the GitHub examples and modified by me.
The Day, Date and Time are shown in a continuously scrolling repeating message. The information is updated each time the message displays.
text = time.strftime("%A %B %-d %-I:%M %p")
https://strftime.org/
The X button is programed to do a proper shutdown when Pressed.
The Y button cycles through color options set by the following lines.
if Y == 0:
r, g, b = (0, 255, 255) # Aqua
elif Y == 1:
r, g, b = (255, 0, 0) # Red
elif Y == 2:
r, g, b = (0, 205, 0) # Green
elif Y == 3:
r, g, b = (0, 0, 255) # Blue
elif Y == 4:
r, g, b = (255, 140, 0) # Orange
Changing the numbers in brackets changes the colors assigned.
The Y= line above the while true sets the default color, Y = 0 is Aqua.
Pressing the A button will dim the display slightly each time its pressed.
Pressing the B button will brighten it slightly each time its pressed.
The B = line sets the default brightness. It goes from 0 to 1 in increments of 0.1.
I have the pHat diffuser on mine and have rotated the display 180.
rotation = 180, change it to rotation = 0 to get it back to right side up.
There is a 5x7.ttf font file that has to be in the same folder as this python script for this to work. I got that file from the examples folder. It’s the same file the text.py example file uses. If you want to run this file on bootup with crontab, you need to add the full path to this line.
font = ImageFont.truetype("5x7.ttf", 8)
for me its
font = ImageFont.truetype("/home/pi/5x7.ttf", 8)
and my crontab entry is
@reboot python3 /home/pi/scroll_clock.py
It’s not obvious unless you look for it but there is another color option after Orange that IMHO is pretty cool. Just keep pressing the Y button to get to it.
And finally my code. =)
#!/usr/bin/env python3
import sys
import os
import time, datetime
import RPi.GPIO as GPIO
from colorsys import hsv_to_rgb
from PIL import Image, ImageDraw, ImageFont
from unicornhatmini import UnicornHATMini
unicornhatmini = UnicornHATMini()
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(5, GPIO.IN, pull_up_down = GPIO.PUD_UP) # A
GPIO.setup(6, GPIO.IN, pull_up_down = GPIO.PUD_UP) # B
GPIO.setup(16, GPIO.IN, pull_up_down = GPIO.PUD_UP) # X
GPIO.setup(24, GPIO.IN, pull_up_down = GPIO.PUD_UP) # Y
X = 0
Y = 0
B = 0.3
def Dim(channel):
global B
B = B - 0.1
if B <= 0.1:
B = 0.1
unicornhatmini.set_brightness(B)
def Bright(channel):
global B
B = B + 0.1
if B >= 1.0:
B = 1.0
unicornhatmini.set_brightness(B)
def Shutdown(channel):
global X
X = 1
def color(channel):
global Y
Y = Y + 1
GPIO.add_event_detect(5, GPIO.FALLING, callback = Dim, bouncetime = 2000)
GPIO.add_event_detect(6, GPIO.FALLING, callback = Bright, bouncetime = 2000)
GPIO.add_event_detect(16, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)
GPIO.add_event_detect(24, GPIO.FALLING, callback = color, bouncetime = 2000)
rotation = 180
if len(sys.argv) > 1:
try:
rotation = int(sys.argv[1])
except ValueError:
print("Usage: {} <rotation>".format(sys.argv[0]))
sys.exit(1)
unicornhatmini.set_rotation(rotation)
display_width, display_height = unicornhatmini.get_shape()
unicornhatmini.set_brightness(B)
font = ImageFont.truetype("5x7.ttf", 8)
offset_x = 0
while True:
if Y > 5:
Y = 0
if Y == 0:
r, g, b = (0, 255, 255) # Aqua
elif Y == 1:
r, g, b = (255, 0, 0) # Red
elif Y == 2:
r, g, b = (0, 205, 0) # Green
elif Y == 3:
r, g, b = (0, 0, 255) # Blue
elif Y == 4:
r, g, b = (255, 140, 0) # Orange
if offset_x == 0:
text = time.strftime("%A %B %-d %-I:%M %p")
text_width, text_height = font.getsize(text)
image = Image.new('P', (text_width + display_width + display_width, display_height), 0)
draw = ImageDraw.Draw(image)
draw.text((display_width, -1), text, font=font, fill=255)
if Y == 5:
for y in range(display_height):
for x in range(display_width):
hue = (time.time() / 10.0) + (x / float(display_width * 2))
r, g, b = [int(c * 255) for c in hsv_to_rgb(hue, 1.0, 1.0)]
if image.getpixel((x + offset_x, y)) == 255:
unicornhatmini.set_pixel(x, y, r, g, b)
else:
unicornhatmini.set_pixel(x, y, 0, 0, 0)
if Y < 5:
for y in range(display_height):
for x in range(display_width):
if image.getpixel((x + offset_x, y)) == 255:
unicornhatmini.set_pixel(x, y, r, g, b)
else:
unicornhatmini.set_pixel(x, y, 0, 0, 0)
offset_x += 1
if offset_x + display_width > image.size[0]:
offset_x = 0
if X == 1:
unicornhatmini.set_all(0, 0, 0)
unicornhatmini.show()
os.system("sudo shutdown now -P")
time.sleep(30)
unicornhatmini.show()
time.sleep(0.05)