LED-klok

      Geen reacties op LED-klok

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.

klok

Sense HAT + Pi 2 = digitale ledklok. In de praktijk zijn de verlichte leds veel beter te zien dan  het op de foto lijkt. Een netwerkkabeltje (boven) zorgt voor de synchronisatie.

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")