Das Display

Bevor wir anfangen müssen wir noch die Bibliothek für das Display installieren. Das können wir einfach mit den folgenden Terminal Befehlen machen:

$ sudo apt install python3-dev
$ git clone https://github.com/coding-world/SSD1306-python
$ cd SSD1306-python
$ sudo python3 setup.py install
Anschlüsse am Raspberry PiAnschlüsse am Display
GPIO 2 / I2C SDA1 – SDA
GPIO 3 / I2C SCL2 – SCL
3,3V3 – VCC
GND4 – GND

Wenn du das Display anschließt, ist es wichtig, dass du darauf achtest, ob das Display auch in dieser Reihenfolge beschriftet ist. Deswegen steht die Benennung der meisten Pins entweder auf der Vorder- oder Rückseite.

Um zu überprüfen, ob du alles richtig angeschlossen hast, kannst du dir alle engeschlossenen I2C-Geräte enzeigen lassen:

$ sudo i2cdetect -y 1

Die Ausgabe sollte dann in etwa so aussehen:

Wie du in dem Screenshot sehen kannst, wurde von dem Pi ein I2C Gerät mit der Adresse 3C erkannt.

Um zu testen, ob alles geklappt hat, kannst du eines der Beispielscripte ausführen. Er setze dazu zunächst die I2C Adresse im Code mit deiner.
Bei der Datei ipanzeige.py findest du die Adresse in Zeile 7 nach dem 0x (Das bedeutet übrigens, dass dies eine Hexadecimalzahl ist. Mehr dazu findest du hier: https://de.wikipedia.org/wiki/Hexadezimalsystem).

Jetzt kannst du die Datei ausführen:

$ python3 ipanzeige.py

Auf dem Display sollte nun „Hello World :D“ und die IP-Adresse deines Raspberrys zu sehen sein.

import socket, fcntl, struct, board, digitalio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306

RESET_PIN = digitalio.DigitalInOut(board.D4)
i2c = board.I2C()
oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c,
    addr=0x3C, reset=RESET_PIN)

def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(
        fcntl.ioctl(
            s.fileno(),
            0x8915,
            struct.pack("256s", str.encode(ifname[:15])),
        )[20:24]
    )

TEXT=""
try:
    TEXT = get_ip_address("eth0")
except IOError:
    try:
        TEXT = get_ip_address("wlan0")
    except IOError:
        TEXT = "kein Netzwerk!"

oled.fill(0)
oled.show()

image = Image.new("1", (oled.width, oled.height))
draw = ImageDraw.Draw(image)

font = ImageFont.truetype(
    "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 16)

draw.text((0, 0), "Hello World :D", font=font, fill=255)
draw.text((0, 30), "Deine IP ist:", font=font, fill=255)
draw.text((0, 46), TEXT, font=font, fill=255)

oled.image(image)
oled.show()

In den Zeilen 7 und 35 sind aus drucktechnischen Gründen Zeilenumbrüche.

Kommen wir zur Erklärung:

Zu Beginn importieren wir wie gewohnt alle beötigten Bibliotheken.
In Zeile 5 bis 8 initialiesieren wir dann die Anbindung zum Display. In Zeile 7 wird z.B. auch die SPI-Adresse gesetzt.

In Zeile 10 bis 18 definieren wir eine Funktion, mit der wir die IP-Adresse abfragen können. Über den Parameter ifname wird der name des Netzwerkgerätes übergeben, von dem die IP-Adresse abgeragt werden soll. Was genau in der Funktion passiert, ist für uns erstmal nicht so wichtig. Wir möchten zunächst erstmal lernen, wie wir das Display mit Daten befüllen können.

In Zeile 20 deklarieren wir die Variable TEXT und initialisieren sie mit einem leeren String. Als nächstes fragen wir nun mit der Funktion get_ip_address() ab, ob der Raspberry über WLAN oder LAN verbunden ist. (Zeile 20 bis 27) Zunächst versuchen wir (try/except) in Zeile 22 die IP-Adresse des LAN-Interfaces (eth0) abzufragen. Sollte das nicht klappen, weil du den Pi z.B. nicht über ein Netzwerkkabel sonder über WLAN verbunden hast, wird der Teil nach except ausgeführt. Nun versuchen wir die IP-Adresse vom WLAN-Interface zu beziehen, sollte das auch nicht klappen, schreiben wir in die Variable TEXT „kein Netzwerk!“.

In Zeile 29, 20 überschreiben wir das Display zunächst mit leerem Inhalt.

Daruaf erstellen wir in den Zeilen 32, 33 ein leeres Bild auf das wir unseren Text schrieben können, um das später auf dem Display anzeigen zu lassen.

Jetzt laden wir in Zeile 36 die Schriftart DejaVuSans.ttf mit der Schriftgröße 16px. Wenn du eine andere Schriftart nutzen möchstest, kannst du einige Weitere auf deinem Raspberry unter /usr/share/fonts/ finden.

In Zeile 38 bis 40 füllen wir jetzt das leere Bild mit Inhalt. Dazu rufen wir die Funktion draw.text()auf. Hier können wir die x/y-Position, wo der Text auf dem Display dagestellt werden soll, den eigentlichen Textinhalt und die zuvor importierte Schriftart übergeben.

Zuletzt müssen wir nur noch das Erstellte Bild auf dem Display erscheinen lassen. Das machen wir in den Zeilen 42 und 43.