Met wat oud Pi-spul dat ligt te verstoffen in de kast, valt er altijd nog iets nuttigs / leuks te maken. Zo had ik nog een Sense HAT die met zijn 8×8 matrix en sensoren jarenlang dienst heeft gedaan voor allerlei verschillende experimenten en projectjes, zoals “A Berry-Xmas with Sense HAT“. Daarnaast was er nog een afgedankte Pi 2, die in een vorige leven trouw dienst heeft gedaan als Pi-Hole (om ongewenste reclame buiten de deur te houden), met een behuizing, waarvan de bovenkant verdwenen was.
Eendracht maakt … een “CLOCK”
Samen vormen deze drie oude spulletjes nu een prima digitale klok, die er fleurig uitziet en (na even wennen) makkelijk af te lezen is, vooral in het donker.
Het idee en de Python-code zijn afkomstig van Gus van PiMyLifeUp , met wat kleine toevoegingen. Het bijzondere aan dit project is niet de toepassing, maar de uitwerking in de software.
In de eerste plaats is er de truc om de vier cijfers (die je nodig hebt voor een digitale 24-uursklok) op de kleine 8×8 matrix te krijgen, zonder dat het een scrollende regel moet worden. Daarnaast zou je een redelijk voorspelbare Python-code verwachten, met een eeuwig durende lus ( while True: ) om minuten en uren van het display continue aan te passen. Maar niets daarvan!
Waarom moeilijk doen, als het met crontab makkelijk kan?
Toevallig heeft Gus voor zijn Python-script dezelfde oplossing bedacht die ik ook heb gebruikt in het project “Fotolijstje upcyclen“: je laat gewoon het script op vaste tijden kort draaien om een simpele verandering op het scherm uit te voeren, aangestuurd door crontab. In het geval van deze klok is dat elke minuut en in het geval van het genoemde fotolijstje één keer per 24 uur.
De matrix-truc
Een 8×8 matrix bestaat uit vier 4×4 matrices. En 4×4 pixels is voldoende voor om elk cijfer mee te maken. Door de cijfers voor de uren in de bovenste helft te plaatsen en die voor de minuten in de onderste helft, heb je al een bruikbare digitale klok. Omdat een 4×3 matrix per cijfer ook al genoeg is, houden we horizontaal tussen de cijfers nog een kolom over voor een betere optische scheiding. Helaas lukt dat in de verticale verdeling niet, want 3×3 is net te krap. Daarom is voor optische scheiding in verticale zin gekozen voor een kleurverschil. Wij kozen voor “oranje boven” en lichtblauw beneden. Het is maar net wat in jouw situatie het makkelijkste leesbaar is.
Gus heeft in zijn beschrijving duidelijk uitgelegd, hoe hij de standaard tijdsaanduiding opsplitst in losse cijfers en die verdeelt over de vier posities op de ledmatrix. Zie ook zijn volledige code hieronder (listing 1).
De kanarie in de mijn
Het ene (rode) ledje linksonder knippert in zijn eigen aparte scriptje, niet zozeer om de secondemaat aan te geven, maar vooral als visuele controle dat de Pi werkt en niet vastgelopen is. Want het nadeel van de ledmatrix is, dat deze aan blijft, ook als de Pi zelf of het Python-script “gecrashed” zijn. Zolang de stroom aanwezig is, houdt de matrix zijn laatste weergave vast. Maar zolang het ene rode ledje leeft, werkt in elk geval de Pi nog.
Joystickje
Aangezien de ledklok met het netwerk is verbonden, is hij headless te beheren via ssh, als je de lite-versie van Pi OS hebt geïnstalleerd, zijn de softwareupdates ook lekker beperkt. Het joystickje van de Sense HAT is daarbij ideaal als shutdown-knop (listing 2).
Puntjes op de i
Vanzelfsprekend moeten de scripts met een voorafgaande @reboot in crontab terecht komen, zodat ze bij het booten van de Pi automatisch opstarten.
En het laatste dat nog moet gebeuren, is een semitransparante afdekking maken die zowel de de verlichte leds beter laat uitkomen, als de rest van de Sense HAT verbergt …
Listing 1
1 #!/usr/bin/env python 2 from sense_hat import SenseHat 3 import time 4 5 sense = SenseHat() 6 7 number = [ 8 [[0,1,1,1], # Zero 9 [0,1,0,1], 10 [0,1,0,1], 11 [0,1,1,1]], 12 [[0,0,1,0], # One 13 [0,1,1,0], 14 [0,0,1,0], 15 [0,1,1,1]], 16 [[0,1,1,1], # Two 17 [0,0,1,1], 18 [0,1,1,0], 19 [0,1,1,1]], 20 [[0,1,1,1], # Three 21 [0,0,1,1], 22 [0,0,1,1], 23 [0,1,1,1]], 24 [[0,1,0,1], # Four 25 [0,1,1,1], 26 [0,0,0,1], 27 [0,0,0,1]], 28 [[0,1,1,1], # Five 29 [0,1,1,0], 30 [0,0,1,1], 31 [0,1,1,1]], 32 [[0,1,0,0], # Six 33 [0,1,1,1], 34 [0,1,0,1], 35 [0,1,1,1]], 36 [[0,1,1,1], # Seven 37 [0,0,0,1], 38 [0,0,1,0], 39 [0,1,0,0]], 40 [[0,1,1,1], # Eight 41 [0,1,1,1], 42 [0,1,1,1], 43 [0,1,1,1]], 44 [[0,1,1,1], # Nine 45 [0,1,0,1], 46 [0,1,1,1], 47 [0,0,0,1]] 48 ] 49 noNumber = [0,0,0,0] 50 51 hourColor = [180,100,0] # Orange 52 minuteColor = [0,100,200] # Blue 53 empty = [0,0,0] # Black/Off 54 55 clockImage = [] 56 57 hour = time.localtime().tm_hour 58 minute = time.localtime().tm_min 59 60 for index in range(0, 4): 61 if (hour >= 10): 62 clockImage.extend(number[int(hour/10)][index]) 63 else: 64 clockImage.extend(noNumber) 65 clockImage.extend(number[int(hour%10)][index]) 66 67 for index in range(0, 4): 68 clockImage.extend(number[int(minute/10)][index]) 69 clockImage.extend(number[int(minute%10)][index]) 70 71 for index in range(0, 64): 72 if (clockImage[index]): 73 if index < 32: 74 clockImage[index] = hourColor 75 else: 76 clockImage[index] = minuteColor 77 else: 78 clockImage[index] = empty 79 80 sense.set_rotation(90) # Optional 81 sense.low_light = True # Optional 82 sense.set_pixels(clockImage)
Listing 2
from sense_hat import SenseHat import os sense = SenseHat() event = sense.stick.wait_for_event() os.system("sudo shutdown -h now")