I2C ist ein serieller Bus, der nur zwei Leitungen benötigt:
Da alle Geräte an der selben Leitung hängen, braucht jedes Gerät eine Adresse.
Der Controller sendet zuerst die Adresse. Nur das Gerät mit dieser Adresse antwortet.
In MicroPython definieren wir den Bus über die Klasse I2C:
from machine import I2C, Pin
# 1. Bus initialisieren (Hardware I2C 0)
i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)
# 2. Geräte suchen (Scan liefert Adressen in Dezimal)
geraete = i2c.scan()
print("Gefundene Adressen:", [hex(a) for a in geraete])
Man beachte bei der Verwendung von I2C-Sensoren oder -Aktoren wird dann bei der Initialisierung das I2C-Objekt mit übergeben. Hier wird dies am bereits eingeführten OLED-Display gezeigt:
oled = SSD1306_I2C(128, 64, i2c)
Erfahre mehr in der [MicroPython I2C Dokumentation](https://docs.micropython.org).
Zur Vermeidung von Schimmel sollte die Luftfeuchtigkeit in Innenräumen unter 60 % bleiben. Hierzu werden Luftfeuchtigkeitssensoren eingesetzt.
Die DHT-Sensoren (Digital Humidity & Temperature) sind kostengünstige digitale Sensoren mit einem kapazitiven Feuchtigkeitssensor und einem NTC-Temperatursensor zur Messung der Umgebungsluft. Der Sensor in Abb. 3 verfügt über eine I2C-Schnittstelle.
Micropython bietet eine DHT-Bibliothek, welche importiert wird. Einmal eingebunden kann ein Objekt der entsprechenden DHT-Klasse erzeugt werden.
Mit dem Aufruf dht.measurements wird die Messung durchgeführt und die Messwerte in einem Dictonary zurückgegeben. Zum extrahieren der beiden Messwerte greifen wir über den Schlüssel auf den jeweiligen Messwert zu. In diesem Fall wird die Messung und Ausgabe jede Sekunde zyklisch wiederholt.
from machine import Pin, I2C
import ssd1306, dht20, time
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
dht=dht20.DHT20(0x38,i2c)
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
while True:
temperature = dht.measurements["t"]
humidity = dht.measurements["rh"]
oled.fill(0) #clear display
oled.text(f"T: {temperature:.2f} `C", 0, 0)
oled.text(f"H: {humidity:.2f} %", 0, 10)
oled.show()
time.sleep(1)
Mit einem Luftdrucksensor lässt sich ein Tief- oder Hochdruckgebiet vorhersagen, aber ggf. auch die Höhe bestimmen. Der BMP180-Sensor in Abb. 4 misst sowohl die Temperatur als auch den Druck. Die Auflösung ist dabei so gut, dass damit auch die Höhe berechnet werden kann.
Der Beschleunigunssensor in Abb. 4 misst eine Änderung der Bewegung in x-, y- und z-Richtung. So kann man erkennen ob ein Gerät gedreht wird oder fällt. Auf dieser Basis funktioniert die Sturz- und Unfallerkennung, Bild- und Flugstabilisierung als auch die Schwingungserkennung. Die Kommunikation beider Sensoren läuft über die integrierte I2C-Schnittstelle.
Um die Klasse BMP180 verwenden zu können muss die Bibliothek bmp180.py auf dem ESP-Controller kopiert werden.
Beim Erzeugen des BMP-Objekts wird zur Berechnung der Höhe der aktuelle Luftdruck in hPa übergeben.
Auf die Sensorwerte Luftdruck, Temperatur und Höhe kann dann über die drei Objektattribute bmp.pressure, bmp.temperature und bmp.altitude zugegriffen werden.
from machine import Pin, I2C
import ssd1306, bmp280, time
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
bmp = bmp280.BMP280(i2c, 0x77, 101700) #Tagesluftdruck
while True:
oled.fill(0) #clear display
oled.text(f"Temp: {bmp.temperature:.2f} `C", 0, 0)
oled.text(f"Druck: {bmp.pressure:.1f} hPa", 0, 10)
oled.text(f"Hoehe: {bmp.altitude:.1f} m", 0, 20)
oled.show()
time.sleep(1)
Um die Klasse LIS3DHTR verwenden zu können muss die Bibliothek lis3dhtr.py auf dem ESP-Controller kopiert werden.
Beim Erzeugen des lis-Objekts kann die I2C-Adresse optional angegeben werden.
Auf die drei Sensorwerte x,y und z kann dann über die Funktion lis.read() zugegriffen werden. Diese Funktion gibt alle drei Werte zurück.
Das Auslesen wird alle halbe Sekunde zyklisch wiederholt.
from machine import Pin, I2C
import ssd1306, lis3dhtr, time
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
lis=lis3dhtr.LIS3DHTR(i2c,0x19)
while True:
x, y, z = lis.read()
oled.fill(0) #clear display
oled.text(f"x: {x:.2f}", 0, 0)
oled.text(f"y: {y:.2f}", 0, 10)
oled.text(f"z: {z:.2f}", 0, 20)
oled.show()
time.sleep(0.5)
Taster
Light and Sound Umgebungslicht und Lärmpegel mit dem ADC
Mit dieser Vorgehensweise lassen sich weitere Sensoren einfach integrieren.
Luftfeuchte und Temperaturmessung
Luftdruck, Temperatur und Höhe
messwerte={
"pressure": bmp.pressure,
"temperatureBMP": bmp.temperature,
...
}
from machine import Pin, I2C |
importieren der Klassen Pin und I2Caus dem Modul machine |
i2c = I2C(0, scl=Pin(22), sda=Pin(21)) |
I2C-Objekt am Pin 21 und 22 erzeugen |
print(f"H: {humidity:.2f} %") |
Formatierte Ausgabe eines Sensorwertes |
x, y, z = lis.read() |
Funktionsaufruf mit drei Rückgabewerten |
messwerte={"wert1": 20.1, "wert2": 36.2} |
Aufbau eines Dictionaries |