7 Segment Anzeigen eignen sich perfekt zur einfachen Anzeige von numerischen Werten wie der zeit oder Zahlen. Eine Raspberry Pi 7 Segment Anzeige kann also z.B. als Timer, Stoppuhr oder Betragsanzeige in Automaten etc. (Stichwort Tankstelle) verwendet werden. Neben Zahlen können auch die einzelnen Segmente einzeln angesteuert werden, womit manche Buchstaben darstellbar sind.
Die LEDs unterscheiden sich in ihrer Bauweise, da es sog. Anoden und Kathoden gibt. Wie man eine 7 Segment Anzeige (Anode) anschließt, habe ich bereits in einem anderen Tutorial gezeigt. Da die Verwendung und vor allem die Ansteuerung unterschiedlich ist, möchte ich in diesem Tutorial auch die Verwendung von einer 7 Segment Kathode zeigen.
Zubehör
Wie der Name schon sagt sind pro Zahl sieben Segmente vorhanden. Viele der Module haben aber einen zusätzlichen Dezimalpunkt, weshalb es eigentlich „8 Segment Anzeigen“ sind. Außerdem sind oftmals bereits fertige Module vorhanden, welche auch den nötigen MAX7219 Treiber IC mitbringen. Ich kann diese Module empfehlen:
- 7 Segment Anzeige Modul mit 4-8 Zahlen (Farbe egal)
- zusätzlich: Jumper Kabel (female-female)
- u.U. sind Lötutensilien nötig, um die Pins anzubringen. Bei manchen Modulen ist der Pin Header schon angelötet.
Kauft man die Anzeigen einzeln, ist ein Verbinden der Pins mit dem MAX7219 laut Datenblatt nötig. Da die LEDs jedoch oft eine unterschiedliche Anzahl an Pins haben und auch die Pin Belegung nicht immer überein stimmt, müssen diese dann ebenfalls individuell verbunden werden. Bei einem Modul entfällt dies. Beachte, dass pro MAX7219 bis zu 8 Zahlen (inkl. Dezimalpunkt) gesteuert werden können. Zwar wäre es theroretisch auch möglich diese über die GPIOs zu steuern, wobei man bei 8 Zahlen inkl. Punkt aber 64 Segmente separat ansprechen würde. Wer so etwas vor hat, muss in jedem Fall eine GPIO Erweiterung wie den I2C GPIO Expander nutzen.
Anschluss der 7 Segment Anzeige am Raspberry Pi
Sofern der Pin Header noch nicht angebracht ist, muss dieser erst angebracht werden. Da auf beiden Seiten Löcher zum Löten sind, nimmt man jene, wo der Pin „DIN“ (Data In) vorhanden ist, da wir von dieser Seite das Modul mit Daten versorgen.
Nun schließen wir die Pins des 7 Segmente Modul mit den Jumper Kabeln an die GPIOs des Raspberry Pi’s an:
Board Pin | Name | Anmerkung | Raspberry Pi Pin |
1 | VCC | +5V | Pin 2 (5V) |
2 | GND | Masse | Pin 6 (GND) |
3 | DIN | Daten Pin (in) | Pin 19 (GPIO10 / MOSI) |
4 | CS | Chip Select | Pin 24 (GPIO8 / CE0) |
5 | CLK | Clock | Pin 23 (GPIO11 / SCLK) |
6 | DOUT | Daten Pin (out) | nicht angeschlossen |
Eine Belegung der GPIO’s gibt es noch einmal hier:
Software Vorbereitung
Weiter geht es mit der benötigten Software. Wir öffnen dazu das Terminal (per SSH oder direkt mit Tastatur und Maus) und befolgen diese Schritte:
- SPI aktivieren:
sudo raspi-config
Unter „Advanced Options“ findet sich aktivieren wir SPI. Anschließend wird neu gestartet:
sudo reboot
- Mit
ls -l /dev/spi*
können wir überprüfen, ob SPI aktiviert ist. Es sollten zwei Einträge angezeigt werden.
- Mit
- Die Packetquellen werden aktualisiert:
sudo apt-get update
- Wir vergeben dem User Berechtigungen.
sudo usermod -a -G spi,gpio pi
- Wir laden die benötigten Tools und Bibliotheken über den Linux Paketmanager (mit Y bestätigen).
sudo apt-get install python-dev python-pip libfreetype6-dev libjpeg-dev
- Nun bringen wir noch den Python Paketmanager (pip) auf den aktuellen Stand, da meist eine veraltete Version auf Raspbian Betriebssystemen vorinstalliert ist:
sudo -i pip install --upgrade pip
- Anschließend können wir bereits die Bibliothek zum Steuern der 7 Segment Anzeigen über Pip installieren:
sudo -H pip install --upgrade luma.led_matrix
Dieser Schritt kann etwas dauern, aber sollte ohne Probleme durchlaufen. Falls hier ein Fehler auftritt, poste diesen im Entwicklerforum.
Testen der Raspberry Pi 7 Segment Anzeige
Sofern alles vorherige ohne Probleme durchgelaufen ist, können wir nun bereits einen ersten Test starten. Dazu laden wir uns der Einfachheit halber ein Skript, welches bereits ein paar Funktionen vordefiniert hat und wir im Anschluss verändern und individualisieren können:
wget https://raw.githubusercontent.com/rm-hull/luma.led_matrix/master/examples/sevensegment_demo.py
Diese Python Datei kann nun ausgeführt werden, woraufhin die am Raspberry Pi angeschlossene 7 Segmente Anzeigen anfangen sollten zu leuchten:
sudo python sevensegment_demo.py
Das Ergebnis ist ebenfalls im Video zu sehen:
Die Funktionen sehen folgendermaßen aus:
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 |
#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (c) 2017 Richard Hull and contributors # See LICENSE.rst for details. """ Example for seven segment displays. """ import time from datetime import datetime from luma.led_matrix.device import max7219 from luma.led_matrix.virtual import sevensegment from luma.core.serial import spi, noop from luma.core.virtual import viewport def date(seg): """ Display current date on device. """ now = datetime.now() seg.text = now.strftime("%y-%m-%d") def clock(seg, seconds): """ Display current time on device. """ interval = 0.5 for i in range(int(seconds / interval)): now = datetime.now() seg.text = now.strftime("%H-%M-%S") # calculate blinking dot if i % 2 == 0: seg.text = now.strftime("%H-%M-%S") else: seg.text = now.strftime("%H %M %S") time.sleep(interval) def show_message_vp(device, msg, delay=0.1): # Implemented with virtual viewport width = device.width padding = " " * width msg = padding + msg + padding n = len(msg) virtual = viewport(device, width=n, height=8) sevensegment(virtual).text = msg for i in reversed(list(range(n - width))): virtual.set_position((i, 0)) time.sleep(delay) def show_message_alt(seg, msg, delay=0.1): # Does same as above but does string slicing itself width = seg.device.width padding = " " * width msg = padding + msg + padding for i in range(len(msg)): seg.text = msg[i:i + width] time.sleep(delay) def main(): # create seven segment device serial = spi(port=0, device=0, gpio=noop()) device = max7219(serial, cascaded=1) seg = sevensegment(device) print('Simple text...') for _ in range(8): seg.text = "HELLO" time.sleep(0.6) seg.text = " GOODBYE" time.sleep(0.6) # Digit slicing print("Digit slicing") seg.text = "_" * seg.device.width time.sleep(1.0) for i, ch in enumerate([9, 8, 7, 6, 5, 4, 3, 2]): seg.text[i] = str(ch) time.sleep(0.6) for i in range(len(seg.text)): del seg.text[0] time.sleep(0.6) # Scrolling Alphabet Text print('Scrolling alphabet text...') show_message_vp(device, "HELLO EVERYONE!") show_message_vp(device, "PI is 3.14159 ... ") show_message_vp(device, "IP is 127.0.0.1 ... ") show_message_alt(seg, "0123456789 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ") # Digit futzing date(seg) time.sleep(5) clock(seg, seconds=10) # Brightness print('Brightness...') for x in range(5): for intensity in range(16): seg.device.contrast(intensity * 16) time.sleep(0.1) device.contrast(0x7F) if __name__ == '__main__': main() |
Wir können aber zusätzlich auch eigene Funktionen schreiben, wie ich es beispielsweise gemacht habe. Mein kleiner Timer sieht nun folgendermaßen aus:
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 |
import time from datetime import datetime, timedelta from luma.led_matrix.device import max7219 from luma.led_matrix.virtual import sevensegment from luma.core.serial import spi, noop def countdown(seg, seconds): end = datetime.now() + timedelta(0, seconds) current = datetime.now() while current < end: sec = (end - current).seconds dezsec = (end - current).microseconds / 10000 seg.text = (" %d.%d" % (sec, dezsec) )[-9:] time.sleep(0.05) current = datetime.now() if __name__ == '__main__': serial = spi(port=0, device=0, gpio=noop()) device = max7219(serial, cascaded=1) seg = sevensegment(device) countdown(seg, 15) |
Weitere Infos zu dieser Bibliothek können auch auf der Dokumentationsseite gefunden werden.
4 Kommentare
Super Tutorial
Danke
Hi,
ich wäre sehr dankbar, wenn mir jemand sagen könnte, was ich nicht sehe. Ich bin die Anleitung durchgegangen, habe in der Original-Beschreibung „luma-led-matrix“ nachgelesen und kenne die Pin-Belegung des max7219 nun annähernd auswendig. Ich habe die Verkabelung doppelt und dreifach gecheckt, habe jedes Kabel geprüft und die Anzeige (einzelne 7-Segmentanzeige in gelb, fängt bei etwa 1,8V zu leuchten an) durchgeklingelt. Ich habe zwei verschiedene RPis und drei verschiedene MAX7219CNGs probiert. Mein Code startet folgendermaßen:
from luma.led_matrix.device import max7219
from luma.core.interface.serial import spi, noop
from luma.core.render import canvas
from luma.core.virtual import sevensegment
serial = spi(port=0, device=0, gpio=noop())
device = max7219(serial, cascaded=2)
seg = sevensegment(device)
Problem: Sobald das Programm startet messe ich zwischen ALLEN DIG- und ALLEN SEG-Pins etwas um – (sic!) 5V.
Irgendjemand? Danke!
Pardon, es muss heißen
device = max7219(serial, cascaded=1)
Ich hatte immer folgende Fehlermeldung beim Ausführen des Skriptes:
Traceback (most recent call last):
File „7segment.py“, line 4, in
from luma.led_matrix.virtual import sevensegment
ImportError: No module named virtual
Laut diesem Beitrag hat sich der Namespace geändert, sodass „from …“ nun folgendermaßen aussehen muss:
from datetime import datetime, timedelta
from luma.led_matrix.device import max7219
from luma.core.virtual import sevensegment
from luma.core.interface.serial import spi, noop
Quelle: https://github.com/rm-hull/luma.led_matrix/issues/104