I2C-Sensoren am Elecrow LoRaWAN LR1262 Dev.-Board mit Raspi-Pico 2040


In diesem Artikel hatte ich ja schon das LoRaWAN LR1262 Development Board mit RP2040 und 1.8 “ LCD für LoRa-Anwendungen von der Hardwareseite her vorgestellt.

Nachdem wir es softwaretechnisch ausgestattet, mit Libraries bestückt und die Hauptkomponenten auf dem Board getestet haben, wollen wir uns heute mit dem Auslesen von Sensoren via I2C-Bus beschäftigen.

Als Beispiel soll hier ein Bosch Sensortec BMP280 Sensor dienen, der Temperatur und Luftdruck misst und dabei ziemlich genau sein soll. Dabei kostet der BMP280 nicht viel Geld und ist auf einem Breakout-Board gelötet praktisch zu verwenden und besonders aus China günstig zu haben.

Der I2C-Bus auf dem LR1262 Dev.-Board

Der I2C ist auf dem Dev.-Board mit PIN_SDA=20 und PIN_SCL=21 verdrahtet, was sich mit der Standard-Konfiguration für platform = raspberrypi beißt, weswegen wir nicht den Standard mbed-Core, sondern den EarlePhilhower-Core benutzen. Alles dazu in meinem Artikel Installation des Core von Earle Philhower für PlatformIO.

Denn dann können wir mit Wire.setSDA(PIN_SDA); Wire.setSCL(PIN_SCL); die I2C-Pins selbst angeben und Wire ganz normal benutzen. Das ist wichtig, wenn wir Libraries benutzen wollen, die wie selbstverständlich Wire für die I2C-Kommunikation benutzen.

Damit können wir den I2C-Bus ganz normal wie unter Arduino gewohnt abfragen. Ich habe mehrere Artikel zu dem Thema I2C geschrieben, in die ihr euch gerne tiefer einlesen könnt:

Ein I2C-Scanner auf dem LR1262 Dev.-Board


Auf dem LR1262 Dev.-Board möchte ich nun auch einen I2C-Scanner wie in dem letzten Artikel in der Liste realisieren. Nur halt nicht mit LCD 1602 Display und STM32, sondern mit dem, was wir auf dem Dev.-Board haben.

Damit kann ich dann gleich feststellen, ob Wire mit dem EarlePhilhower-Core richtig funktioniert und zudem schauen, was ich für I2C-Geräte an die Header oder Grove-I2C-Ports des Dev.-Boards angeschlossen habe und welche I2C-Adresse diese haben.

Diese Funktion findet sich in meiner Menüführung unter Test Sensors / Scan I2C Bus.


Führen wir doch mal einen Scan mit an einem der beiden Grove-I2C-Ports angeschlossenen BMP280-Sensor durch...

Okay, es werden zwei I2C-Devices gefunden: Die 0x76 merken wir, damit wir später den BMP280 darüber ansprechen können.

Bosch Sensortec BMP280


Um die Werte für Temperatur und Luftdruck aus dem BMP280 kitzeln zu können, gibt es zwei Möglichkeiten.

Erstens: wir benutzen die Adafruit Library Adafruit BMP280 Driver (Barometric Pressure Sensor), die unter Github zu finden ist und die wir mit lib_deps = adafruit/Adafruit BMP280 Library@^2.6.8 in der platformio.ini in unser Projekt einbinden können.

Das klappt ganz gut und vor allem mit wenig Aufwand.

Oder Zweitens: Wir quälen uns durch das Datenblatt des Bosch Sensortec BMP280 und nutzen direkt das I2C-Protokoll, um die Rohwerte und die Kalibrierungswerte aus dem BMP280 zu holen, und benutzen dann ein wenig Mathematik, um dann schließlich auf die Temperatur und den Luftdruck zu kommen, wie ich es bereits getan habe und haarklein in meinem Artikel Den Sensor BMP280 als Thermometer und Barometer nutzen und über den I2C-Bus auslesen beschreibe.

Da ich den Code sozusagen eh schon fertig hatte - okay, er war in Raspberry Pi Python und nicht in Arduino C++, aber die Portierung sollte kein Problem sein, entschied ich mich für Möglichkeit Zwei.


Insbesondere, weil mir die Temperatur, welche die Adafruit-Library anzeigte, zu hoch erschien. Und dafür der Luftdruck zu niedrig.

Aber es stellte sich heraus, dass ich unter Zuhilfenahme des Datenblattes und auch schon mit meinem eigenen alten Code exakt die gleichen Werte wie die Adafruit-Library herausbekam: Adafruit-Library BMP280 Forced Mode Test. Temperature = 27.38 *C Pressure = 96901.51 Pa Approx altitude = 374.97 m Der Luftdruck stimmt. Ich hatte die irrtümliche Annahme getroffen, hier den barometrischen Luftdruck vorzufinden, wie man ihn ständig hört und zum Beispiel auch auf Wetter-Webseiten wie dem Deutschen Wetterdienst wiederfindet:



Der dort angezeigte und umgängliche "Wetter-Luftdruck" ist aber nicht der wahre Luftdruck, sondern die 969 hPa sind es.

Mein Garmin Oregon 600 kann auch den Realwert anzeigen und nennt dies dann "Umgebungsdruck", während es mit "Barometer" den "Wetter-Luftdruck" meint:



Wie bekommen immer den "Wetter-Luftdruck" zu hören, weil man nur damit vernünftig vergleichen kann. Man rechnet einfach auf Meereshöhe um und vergleicht dann mit dem Normaldruck von 1 bar. Unter 1 bar ist Tiefdruck, über 1 bar ist Hochdruck. Nur dass 1 bar nicht ganz exakt ist. Irgendwann hat nämlich mal jemand seinen Luftdruck auf Meereshöhe gemessen und dann mit 1000 mbar bzw. hPa festgelegt und ein wenig danebengelangt. Für Deutschland sind eher im Jahresmittel so 1013.25 hPa angesagt aus Meereshöhe.

Man kann aus dem realen Umgebungs-Luftdruck den Wetter-Luftdruck herleiten, wenn man die Höhe weiß. Anders herum kann man die Höhe herleiten, wenn man den Wetter-Luftdruck weiß. Aber eine der Angaben muss man haben, wenn man genau sein will.

Da sich die Luft ja aufeinander stapelt und - wenn auch nur ganz wenig - etwas wiegt, ist der Druck, der auf der Erdoberfläche (Meereshöhe) lastet, am größten. Je weiter man noch oben kommt, desto weniger Luft stapelt sich über einem und je weniger Luftgewicht muss man tragen: der Luftdruck nimmt ab. Und das tut er so mit 8 bis 10 Meter pro HektoPascal. Wobei gilt, dass Luftdruck nicht linear abnimmt, sondern desto schneller, je höher man sich befindet.

Man kann also ganz grob für die Höhe rechnen: (1013.25 - Umgebungsdruck) * 8 = Höhe über NN (Normalnull, gleich Meereshöhe), was dann für die 969 hPa rechts im Bild 354 Meter über NN, also 354 Höhenmeter (hm) wären. Was ganz gut hinkommt, ich befinde mich auf 343 Meter.

Es gibt aber noch komplexere Formeln, die die Temperatur mit einbeziehen und noch genauer sind als der Schätzwert. Luft hat nämlich je nach Temperatur eine andere Ausdehnung und Feuchtigkeitssättigung. Wenn man natürlich Indoor misst und damit höhere Temperaturen als draußen, verfälscht das eher das Ergebnis. Mein Algorithmus und der von Adafruit schätzen beide zu hoch.

Und natürlich sollte man mit dem lokalen Wetter-Luftdruck (derzeit 1007 hPa) rechnen statt fest mit 1013.25, denn nicht nur die Luftsäule über einem, sondern auch das Wetter hat einen Einfluss auf den Luftdruck - darum macht man wettertechnisch ja den ganzen Spaß mit dem Luftdruck.

Wie gesagt, kann man auch aus dem realen Umgebungs-Luftdruck den Wetter-Luftdruck herleiten, wenn man die Höhe weiß. Die habe ich mal mit den realen 343 Höhenmetern in die Formel einfließen lassen und komme damit ziemlich exakt auf den Wetter-Luftdruck: 1007 hPa. Die Berechnung hat die Adafruit-Library nicht eingebaut. Die 1007 hPa kann ich dann mit den normalen 1013.25 hPa Luftdruck vergleichen und sehen, dass ich mich in einem Tiefdruckgebiet befinde. Tja, das hätte ich auch mit einem Blick aus dem Fenster regeln können, den es regnet gerade.

Lange Rede, kurzer Sinn: die Luftdruck-Angabe des BMP280 stimmt genau. Und natürlich misst der auf aktueller Höhe und nicht auf Meereshöhe - wie sollte er das auch machen - er befindet sich dort, wo er sich befindet.

Und der praktische Nutzen? Nun: wenn ich den Sensor auf einer festen Höhe montiert habe, weiß ich die genaue Höhe. Die kann ich anhand von Karten wie zum Beispiel den Bayernatlas nachschauen oder mit dem eigenen GPS-Empfänger und einem 3D-Fix herausfinden. Und damit kann ich den Umgebungsdruck zusammen mit der Temperatur zum Wetter-Luftdruck umrechnen und aufzeichnen. Dann erkenne ich, wenn der Luftdruck plötzlich fällt, was heißt, dass es jetzt vielleicht stürmisch und gewittrig werden könnte. Und dann sollte ich vielleicht den Sonnenschirm auf der Terrasse einklappen. Wobei natürlich in diesem Fall ein plötzlicher nicht umgerechneter Umgebungs-Luftdruck-Abfall genauso aussagekräftig wäre.

Und eigentlich gäbe es da noch ein Drittens: Die BME280 Sensor API von Bosch Sensortec selbst. Bosch empfiehlt, diese zu benutzen. Nur ist die in C geschrieben und nicht Arduino-kompatibel. Aber falls jemand eine andere Entwicklungsumgebung benutzt...

Videos

Hier ein kurzer Demo-Video über den I2C-Scanner und den Test des BMP280:



Auch über die Board-Tests (Buzzer, Screen, LEDs, Buttons) habe ich ein kleines Demo-Video davon aufgenommen:



Nachtrag 2025-08-31

Mir waren doch über die ca. 2 bis 3 Grad zu hohen Temperaturen, die der BMP280 ausgibt, aufgefallen. Nach ein wenig Recherche habe ich folgende Anmerkung auf Seite 8 des Datenblattes gefunden:
3 Temperature measured by the internal temperature sensor. This temperature value depends on the PCB temperature, sensor element self-heating and ambient temperature and is typically above ambient temperature.
Aha! Die Ursache ist also, dass der Sensor für eine genauere Messung ein wenig aufgeheizt wird. Und natürlich braucht der Luftdrucksensor als Kompensationsfaktor die Temperatur, die in seiner unmittelbaren Umgebung herrscht, also in dem kleinen silbernen und aufgeheiztem Kästchen.

Was da vom BMP280 ausgegeben wird, ist also gar nicht die "Ambient Temperature", also nicht die Umgebungstemperatur, sondern die Temperatur auf der Platine bzw. im Sensor ("PCB-Temperature"). Und die ist wegen des Heizens natürlich höher, eben diese 2 bis 3 Grad.

Der Sensor ist also auf einen möglichst genauen Luftdruck ausgelegt. Die Umgebungstemperatur, gleich Zimmertemperatur bzw. Außentemperatur ist also niedriger. Leider gibt es hier keine fertigen Kompensationsformeln. Man müsste da mal eine Messreihe mit einem die Umgebungstemperatur genau messenden Thermometer und dem BMP280 machen und die Temperaturen miteinander vergleichen, um herauszufinden, ob der Unterschied immer gleich ist, es einen lineare oder vielleicht sogar einen nichtliniearen Unterschied gibt.

Das mach ich vielleicht mal, wenn ich zu viel Zeit haben. Ansonsten bleibe ich erst einmal bei meiner Faustformel

Umgebungstemperatur = BMP280-PCB-Temperatur - 2 °C

Und so geht es weiter...

Im nächsten Artikel zu diesem Board wird es darum gehen, wie man Strom sparen kann und wie man den RP2040 in Deep Sleep versetzen kann.



Quellen, Literaturverweise und weiterführende Links