TigerJython4Kids
HomeTurtlegrafikRobotikDatenbanken
oled

3. I2C UND OLED

 

 

DU LERNST HIER...

 

ein wichtigstes Protokoll zwischen Sensoren und Mikrocontrollern zu verwenden und einen alphanumerischen Display anzusteuern.

 

 

DAS I2C PROTOKOLL

 

In der Sensorik ist es von fundamentaler Wichtigkeit, digitale Daten zwischen einem Microcontroller und daran angeschlossenen Geräten (Aktoren, Sensoren, Displays, usw.) auszutauschen. In einer typischen Anordnung sendet der Mikrocontroller eine Aufforderung an den Sensor, eine Messung durchzuführen und den Messwert zurück zu senden. Um den Verdrahtungsaufwand klein zu halten, sollten dabei nur wenige Verbindungsleitungen nötig sein, auch wenn mehrere Sensoren miteinander am Mikrocontroller angeschlossen werden. Das I2C-Protokoll (ausgesprochen "i-quadrat-c") benötigt nur 4 Leitungen: GND, VDD, SDA(Serial DAta), SCL (Serial CLock), wobei VDD nur dazu verwendet wird, den Sensor zu speisen, also eigentlich nicht zum Protokoll gehört.

Alle Geräte sind gleichartig an den 4 Leitungen angeschlossen. Man spricht daher von einer Bus-Struktur. Um die Geräte zu identifizieren, wird eine eindeutige 8bit-lange Adresse verwendet, die bei den Geräten fest eingestellt ist. Die Adresse ist also im dezimalen Bereich 0..255 oder hexadezimal zwischen 0x00 und 0xFF.


 

MUSTERBEISPIELE

 

Auf der Oxocard ist bereits ein Beschleunigungssensor (Accelerometer) am I2C-Bus angeschlossen. MicroPython unterstützt das I2C-Protokoll mit der Klasse I2C, wobei auf der Oxocard Pinnummer 21 für SDA und Pinnummer 22 für SCL verwendet wird. Eine der wichtigsten Tests bei der Verwendung von I2C-Devices besteht darin, einen Bus-Scan auszuführen, d.h. die Adressen aller richtig angeschlossenen und betriebsbereiten Geräte aufzulisten. Du machst dies mit folgendem Programm:

Programm:

from oxocard import *
from machine import Pin, I2C

i2c = I2C(scl = Pin(22), sda = Pin(21))
devices = i2c.scan()
for dev in devices:
    print("%X" % dev)
► In Zwischenablage kopieren

Hast du keine externen Geräte angeschlossen, so wird lediglich die Adresse 0x28 des internen Accelerometers angezeigt.

Für viele Anwendungen ist ein fehlender Display ein schweres Handicap. Auf der Basis des SSD1306 Controllers gibt es aber einen kostengünstigen OLED-Display mit einer Auflösung von immerhin 128x64 Pixels und einem I2C-Interface. Man lötet am Display ein Kabel mit einem Grove-Stecker  an und steckt diesen in den I2C-Hub der Oxocard. Der Scan zeigt nun neben der Adresse 0x28 auch die Adresse 0x3C des OLED-Displays.  

Um ein I2C-Gerät zu verwenden, ist es nötig, das Datenblatt zu studieren und die entsprechenden I2C-Befehle in Programmcode umzusetzen. Dies ist meist mit grösserem Aufwand verbunden. Darum wird dieser Code für alle in diesem Tutorial verwendeten Geräte in Zusatzmodulen gekapselt, die beim Flashen des Betriebssystems auf die Oxocard kopiert werden. (Ein solches Modul nennt man auch einen Gerätetreiber.) Alle aktuellen Treiber kann man auch von hier  herunterladen.

Der Treiber für den OLED heisst oled.py und enthält die Klasse Oled(), von der du als erstes eine Instanz erstellst. Dann kannst du eine der folgenden Methoden verwenden:

 poweroff()  schalten den Display ab
 show()  zeigt den Bildbuffer an
 fill(color) color = 0, 1  füllt den ganzen Display (color 0: black, 1: white)
 pixel(x, y, color  setzt ein einzelnes Pixel (color 0: black, 1: white)
 scroll(dx, dy)  verschiebt das Bild um dx, dy (in pixels)
 text(string, x, y, color = 1):  schreibt den Text (Start bei x, y (color 0: black, 1: white)
 line(x0, y0, x1, y1):  zeichnet eine Linie von (x0, y0) zu (x1, y1)
 ellipse(xm, ym, a, b):  zeichnet eine Ellipse mit Mitte (xm, ym) und Achsen
 circle(xm, ym, radius):  zeichnet einen K reis mit Mitte (xm, ym) und Radius
 rectangle(xm , ym, a, b):  zeichnet eine Rechteck mit Mitte (xm, ym) und Länge/Breite
 fillRectangle(xm, ym, a, b):  dasselbe, aber gefüllt
 image(filename)  stellt ein Bild dar (Format: ppm 128x64 pixel B/W)


Alle Zeichnungsoperationen werden in einem Bildbuffer durchgeführt, der mit show() angezeigt wird. Im ersten Programm schreibst du lediglich zwei Testzeilen auf den Display.

Programm:

from oled import Oled

oled = Oled()
oled.text('Hello', 0, 0)
oled.text('Python', 0, 10)
oled.show()
► In Zwischenablage kopieren
 

Im nächsten Programm verwendest die Linien zur Erzeugung eines Moiré-Musters.

Programm:

from oled import Oled

n = 5
def moire():
    for i in range(n + 1):
        for k in range(n + 1):
            x1 = round(i / n * 127)
            x2 = round(k / n * 127)
            oled.line(x1, 0, x2, 63)
            oled.show()
    for i in range(n + 1):
        for k in range(n + 1):
            y1 = round(i / n * 63)
            y2 = round(k / n * 63)
            oled.line(0, y1, 127, y2)
            oled.show()

oled = Oled()
moire()
► In Zwischenablage kopieren
 

 

Im Zusammenhang mit Echtzeitanwendungen möchtest du manchmal die Grafik animieren. Hier zeigst du als Demonstration ein animiertes Balkendiagramm.

 

 

 

MERKE DIR...

 

dass  I2C einen Verbindungsbus mit 4 Leitungen GND, VDD, SDA und SCL hat und jedes Gerät eine eindeutige I2C-Adresse verwendet. Um mit einem Gerät zu kommunizieren, muss ein Treiber vorhanden sein, von dem man nur die Klassen- und Funktionsnamen mit ihren Parametern und Rückgabewerten kennen muss (das sogenannte API (Application Programming Interface)).

 

 

ZUM SELBST LÖSEN

 

 

1.
Verwende die Funktion rectangle(xm, ym, a, b), um mehrere konzentrische Rechtecke zu zeichnen. Für die x-Koordinaten wählst du Zahlen im Bereich 0 bis 127, für y im Bereich 0 bis 64.  


2.

Du kannst sogar einfache Grafiken auf dem Display anzeigen. Dazu musst du das Bild im ppm-Format mit 128x64 Pixels (B/W) erstellen, beispielsweise mit Photoshop und dieses in das Filesystem des ESP32 kopieren. Du kannst dazu ein Utility uPyLoader verwenden, das zu von hier herunterladen und installieren kannst.

Erstelle ein Bild von dir selbst und stelle es auf dem Display dar.