Bibliothek für BMP280 und BME280: 7 Schritte

Bibliothek für BMP280 und BME280: 7 Schritte

Inhaltsverzeichnis:

Anonim

Einführung

Ich wollte diese Bibliothek nicht schreiben. Es "passierte" als Nebeneffekt eines Projekts, das ich mit einem BMP280 gestartet habe. Dieses Projekt ist noch nicht abgeschlossen, aber ich denke, die Bibliothek ist bereit, es mit anderen zu teilen.

Anschließend musste ich einen BME280 verwenden, der die Druck- und Temperaturfähigkeit des BMP280 um eine Feuchtigkeitsmessung erweitert. Der BME280 ist "abwärtskompatibel" mit dem BMP280 - das heißt, alle Register und die Schritte, die zum Lesen von Druck und Temperatur vom BME280 erforderlich sind, sind die gleichen wie beim BMP280. Es sind zusätzliche Register und Schritte zum Lesen der Luftfeuchtigkeit erforderlich, die nur für den BME280 gelten. Dies wirft die Frage auf, eine Bibliothek für beide oder zwei separate Bibliotheken. Die Hardware für die beiden Gerätetypen ist vollständig austauschbar. Sogar viele der verkauften Module (zum Beispiel bei Ebay und AliExpress) sind mit BME / P280 gekennzeichnet. Um herauszufinden, um welchen Typ es sich handelt, müssen Sie die (winzige) Schrift auf dem Sensor selbst lesen oder das Geräte-ID-Byte testen. Ich entschied mich für eine einzelne Bibliothek. Es scheint gut geklappt zu haben.

Feedback, insbesondere Verbesserungsvorschläge, sind willkommen.

Bibliotheksfunktionen und -fähigkeiten

Eine Bibliothek ist eine Software, die einem Programmierer eine Anwendungsprogrammierschnittstelle (Application Programming Interface, API) zur Verfügung stellt, mit der er die Funktionen des Geräts ausüben kann, ohne sich unbedingt mit allen Feinheiten befassen zu müssen. Wünschenswerterweise sollte die API für Anfänger mit einfachen Voraussetzungen einfach zu handhaben sein und gleichzeitig eine vollständige Ausnutzung der Gerätefunktionen ermöglichen. Wünschenswerterweise sollte die Bibliothek alle spezifischen Richtlinien des Geräteherstellers sowie allgemeine bewährte Verfahren für Software befolgen. Ich habe mich bemüht, all dies zu erreichen.

Als ich mit dem BMP280 angefangen habe, habe ich 3 verschiedene Bibliotheken dafür gefunden: Adafruit_BMP280; Seeed_BMP280; und eine namens BMP280 vom Gerätehersteller. Weder Adafruit noch Seeed boten erweiterte Funktionen, obwohl sie gut funktionierten und für grundlegende Anwendungen einfach zu verwenden waren. Ich konnte nicht herausfinden, wie wir den vom Gerätehersteller (Bosch Sensortec) hergestellten verwenden sollen. Dies mag eher mein Mangel sein als ihr. Die Bibliothek war jedoch viel komplizierter als die anderen beiden, ich konnte keine Anweisungen oder Anwendungsbeispiele finden (anschließend fand ich Beispiele in der Datei "bmp280_support.c", die mir jedoch nicht besonders hilfreich waren).

Aufgrund dieser Faktoren habe ich beschlossen, eine eigene Bibliothek für das BMP280 zu schreiben.

Als ich die Bibliotheksituation für das BME280 untersuchte, fand ich separate Bibliotheken Adafruit_BME280, Seed_BME280 und ein weiteres BME280_MOD-1022, das von Embedded Adventures geschrieben wurde. Keiner von ihnen kombinierte die Funktionen für BMP280 in einer Bibliothek, die das BME280 verwenden kann. Keiner von ihnen hat ausdrücklich die Fähigkeit der Geräte unterstützt, ein paar Datenbits zu speichern, während das Gerät und der steuernde Mikroprozessor im Ruhezustand sind (diese Fähigkeit ist im Datenblatt ersichtlich und wird in der hier beschriebenen Bibliothek unterstützt).

Eine kombinierte Bibliothek sollte alle Funktionen des BME280 unterstützen, bei Verwendung mit einem BMP280 sollte jedoch kein Overhead für die nicht verwendeten Funktionen entstehen. Zu den Vorteilen einer kombinierten Bibliothek gehören weniger zu verwaltende Bibliotheksdateien, einfaches Mischen und Zuordnen verschiedener Geräte im selben Projekt sowie vereinfachte Änderungen für Wartungen oder Upgrades, die nur an einem Ort und nicht an zwei Orten durchgeführt werden müssen. Dies sind wahrscheinlich alle recht unbedeutend, sogar unbedeutend, aber …

Gerätefunktionen

Beim BMP280 und BME280 handelt es sich um Aufputzgeräte mit einem Quadrat von 5 mm und einer Höhe von 1 mm. Es gibt 8 Schnittstellen-Pads, darunter 2 separate Power-Input-Pads und zwei Ground-Pads. Sie sind bei eBay als Modul mit 4 oder 6 herausgebrachten Pins erhältlich.

Das 4-polige Modul hat eine feste I2C-Adresse und kann nicht für die Verwendung des SPI-Protokolls konfiguriert werden.

Das 6-polige Modul oder das nackte Gerät kann entweder mit I2C- oder SPI-Protokollen verwendet werden. Im I2C-Modus können zwei verschiedene Adressen verwendet werden, indem der SDO-Pin entweder mit Masse (für Basisadresse = 0x76) oder mit Vdd (für Basisadresse +1 = 0x77) verbunden wird. Im SPI-Modus besteht die übliche Anordnung aus 1 Takt, 2 Daten (eine für jede Richtung) und einem Geräteauswahlstift (CS).

Die Bibliothek, die ich hier geschrieben und beschrieben habe, unterstützt nur I2C. Die Bibliotheken Adafruit_BMP280 und BME_MOD-1022 unterstützen sowohl i2C als auch SPI.

Die Bibliothek kann hier heruntergeladen werden:

github.com/farmerkeith/BMP280-library

Zubehör:

Schritt 1: Einrichten der Hardware

Bevor die Bibliothek nützlich sein kann, muss ein Mikrocontroller an den BMP280 angeschlossen werden (oder an zwei, wenn Sie dies wünschen).

Ich habe einen WeMos D1 mini pro verwendet, daher zeige ich seine Verbindungen. Andere Mikrocontroller sind ähnlich. Sie müssen lediglich die SDA- und SCL-Pins korrekt verbinden.

Beim WeMos D1 mini pro sind die Anschlüsse:

Funktion WeMos Pin BMP280 Pin Hinweise SDA D2 SDA SCL D1 SCL Vdd 3V3 Vin Nominal 3.3V Masse GND Adresssteuerung SDO Masse oder Vdd I2C CSB Vdd auswählen (GND SPI auswählen)

Beachten Sie, dass der SDO-Pin einiger MP280-Module mit SDD und der Vdd-Pin mit VCC gekennzeichnet ist.

Hinweis: SDA- und SCL-Leitungen sollten Pull-up-Widerstände zwischen der Leitung und dem Vin-Pin haben. Normalerweise sollte ein Wert von 4,7 KB in Ordnung sein.Einige BMP280- und BME280-Module verfügen über 10K-Pull-up-Widerstände im Modul (was nicht empfehlenswert ist, da mehrere Geräte den I2C-Bus überlasten können). Die Verwendung von 2 BME / P280-Modulen mit jeweils einem 10K-Widerstand sollte jedoch in der Praxis kein Problem sein, solange nicht zu viele andere Geräte am selben Bus angeschlossen sind, auch nicht mit Pull-up-Widerständen.

Sobald Sie die Hardware angeschlossen haben, können Sie leicht überprüfen, ob Ihr Gerät ein BMP280 oder ein BME280 ist, indem Sie die Skizze I2CScan_ID ausführen, die Sie hier finden:

Sie können auch überprüfen, ob Sie einen BMP280 oder BME280 haben, indem Sie sich das Gerät selbst ansehen. Ich fand es notwendig, ein digitales Mikroskop zu verwenden, aber wenn Ihr Sehvermögen sehr gut ist, können Sie es möglicherweise ohne Hilfsmittel tun. Auf dem Gehäuse des Geräts befinden sich zwei Drucklinien. Der Schlüssel ist der erste Buchstabe in der zweiten Zeile, der bei BMP280-Geräten ein "K" und bei BME280-Geräten ein "U" ist.

Schritt 2: Von der Bibliothek bereitgestellte APIs

Einbinden der Bibliothek in eine Skizze

Die Bibliothek wird standardmäßig mit der Anweisung in eine Skizze eingebunden

#include "farmerkeith_BMP280.h"

Diese Anweisung muss vor dem Start der setup () - Funktion im frühen Teil der Skizze enthalten sein.

Erstellen eines BME- oder BMP-Softwareobjekts

Es gibt 3 Ebenen zum Erstellen des BMP280-Softwareobjekts. Das einfachste ist nur

bme280 objectName;

oder bmp280 objectName;

zum Beispiel BMP280 bmp0;

Dadurch wird ein Softwareobjekt mit der Standardadresse 0x76 erstellt (dh für SDO, das mit Masse verbunden ist).

Die nächste Ebene zum Erstellen eines BME280- oder BMP280-Softwareobjekts hat den folgenden Parameter 0 oder 1:

bme280 objectNameA (0); bmp280 objectNameB (1);

Der Parameter (0 oder 1) wird zur I2C-Basisadresse hinzugefügt, sodass zwei BME280- oder BMP280-Geräte am gleichen I2C-Bus (einschließlich jeweils eines) verwendet werden können.

Die dritte Ebene zum Erstellen eines BME- oder BMP280-Softwareobjekts weist zwei Parameter auf. Der erste Parameter, entweder 0 oder 1, gilt für die Adresse wie für den vorherigen Fall. Der zweite Parameter steuert den Debug-Druck. Wenn der Wert auf 1 gesetzt ist, führt jede Transaktion mit dem Softwareobjekt zu Serial.print-Ausgaben, mit denen der Programmierer die Details der Transaktion anzeigen kann. Zum Beispiel:

bmp280 objectNameB (1,1);

Wenn der Debug-Druckparameter auf 0 gesetzt ist, kehrt das Softwareobjekt zum normalen Verhalten zurück (kein Druck).

Diese Anweisung oder Anweisungen müssen nach dem # include und vor der setup () -Funktion eingefügt werden.

Initialisieren des BME- oder BMP-Softwareobjekts

Vor der Verwendung müssen die Kalibrierungsparameter vom Gerät gelesen und für den jeweiligen Messmodus, die Überabtastung und die Filtereinstellungen konfiguriert werden.

Für eine einfache Universalinitialisierung lautet die Anweisung:

objectName.begin ();

Diese Version von begin () liest die Kalibrierungsparameter vom Gerät und setzt osrs_t = 7 (16 Temperaturmessungen), osrs_p = 7 (16 Druckmessungen), mode = 3 (kontinuierlich, normal), t_sb = 0 (0,5 ms Ruhezeit dazwischen) Messsätze), filter = 0 (K = 1, also keine Filterung) und spiw_en = 0 (SPI deaktiviert, also I2C verwenden). Beim BME280 gibt es einen zusätzlichen Parameter osrs_h = 7 für 16 Feuchtemessungen.

Es gibt eine andere Version von begin (), die alle sechs (oder 7) Parameter akzeptiert. Das Äquivalent der obigen Aussage ist

objectName.begin (7,7,3,0,0,0); // osrs_t, osrs_p, mode, t_sb, filter, spiw_en oder objectName.begin (7,7,3,0,0,0,7); // osrs_t, osrs_p, mode, t_sb, filter, spiw_en, osrs_h

Die vollständige Liste der Codes und ihrer Bedeutungen finden Sie im BME280- und BMP280-Datenblatt sowie in den Kommentaren in der CPP-Datei in der Bibliothek.

Einfache Temperatur- und Druckmessung

Am einfachsten ist es, eine Temperaturmessung durchzuführen

double temperature = objectName.readTemperature (); // Temperatur messen

Am einfachsten ist es, eine Druckmessung durchzuführen

double pressure = objectName.readPressure (); // Druck messen

Am einfachsten ist es, eine Feuchtemessung durchzuführen

doppelte Luftfeuchtigkeit = objectName.readHumidity (); // Feuchte messen (nur BME280)

Um sowohl Temperatur als auch Druck zu erhalten, können die beiden obigen Anweisungen nacheinander verwendet werden. Es gibt jedoch eine andere Option:

doppelte Temperatur; doppelter Druck = objectName.readPressure (Temperatur); // Druck und Temperatur messen

Diese Anweisung liest die Daten nur einmal vom BME280- oder BMP280-Gerät und gibt sowohl Temperatur als auch Druck zurück. Dies ist eine etwas effizientere Nutzung des I2C-Busses und stellt sicher, dass die beiden Messwerte dem gleichen Messzyklus entsprechen.

Für das BME 280 lautet eine kombinierte Aussage, die alle drei Werte (Luftfeuchtigkeit, Temperatur und Druck) abruft:

doppelte Temperatur, doppelter Druck;

doppelte Luftfeuchtigkeit = objectName.readHumidity (Temperatur, Druck); // Feuchte, Druck und Temperatur messen

Diese Anweisung liest die Daten nur einmal vom BMP280-Gerät und gibt alle drei Werte zurück. Dies ist eine etwas effizientere Nutzung des I2C-Busses und stellt sicher, dass die drei Messwerte dem gleichen Messzyklus entsprechen. Beachten Sie, dass die Namen der Variablen beliebig geändert werden können, ihre Reihenfolge jedoch festgelegt ist - Temperatur steht an erster Stelle und Druck an zweiter Stelle.

Diese Anwendungsfälle werden in den mit der Bibliothek gelieferten Beispielskizzen (basicTemperature.ino, basicPressure.ino, basicHumidity.ino, basicTemperatureAndPressure.ino und basicHumidityAndTemperatureAndPressure.ino) behandelt.

Anspruchsvollere Temperatur- und Druckmessung

Obwohl die obige Anweisungsreihe problemlos funktioniert, gibt es einige Probleme:

  1. Das Gerät läuft ununterbrochen und verbraucht daher maximal Strom. Wenn die Energie aus einer Batterie stammt, muss diese möglicherweise reduziert werden.
  2. Aufgrund des verbrauchten Stroms erwärmt sich das Gerät und daher ist die gemessene Temperatur höher als die Umgebungstemperatur. Ich werde dies in einem späteren Schritt näher erläutern.

Ein Ergebnis, das weniger Energie verbraucht und eine Temperatur liefert, die näher an der Umgebungstemperatur liegt, kann durch Verwenden von begin () mit Parametern erzielt werden, die es in den Ruhezustand versetzen (z. B. mode = 0). Zum Beispiel:

objectName.begin (1,1,0,0,0,0, 1); // osrs_t, osrs_p, mode, t_sb, filter, spiw_en, osrs_h

Wenn eine Messung gewünscht wird, aktivieren Sie das Gerät mit einem Konfigurationsbefehl, um die Register F2 (falls erforderlich) und F4 zu registrieren, mit denen die entsprechenden Werte für osrs_h, osrs_t und osrs_p plus mode = 1 (Einzelbildmodus) festgelegt werden. Zum Beispiel:

objectName.updateF2Control (1); // osrs_h - wird für BMP280 nie // und für BME280 nicht benötigt, wenn die Anzahl der Messungen nicht // von dem in begin () angegebenen Wert geändert wird. objectName.updateF4Control (1,1,1); // osrs_t, osrs_p, mode

Nach dem Aufwecken des Geräts wird die Messung gestartet, das Ergebnis wird jedoch für einige Millisekunden nicht verfügbar sein - mindestens 4 ms, möglicherweise bis zu 70 ms oder mehr, abhängig von der Anzahl der angegebenen Messungen. Wenn der Lesebefehl sofort gesendet wird, gibt das Gerät die Werte der vorherigen Messung zurück - was in einigen Anwendungen möglicherweise akzeptabel ist, aber in den meisten Fällen ist es wahrscheinlich besser, zu verzögern, bis die neue Messung verfügbar ist.

Diese Verzögerung kann auf verschiedene Arten erfolgen.

  1. Warten Sie eine bestimmte Zeit, um die längste zu erwartende Verzögerung abzudecken
  2. Warten Sie eine Zeitspanne, die aus der maximalen Messzeit pro Messung (dh 2,3 ms) multipliziert mit der Anzahl der Messungen plus Overhead plus einer Marge berechnet wurde.
  3. Warten Sie eine kürzere Zeitspanne, die wie oben berechnet wurde, verwenden Sie jedoch die nominelle Messzeit (dh 2 ms) plus Overhead, und überprüfen Sie dann das Bit "Ich messe" im Statusregister. Wenn das Statusbit 0 anzeigt (dh nicht misst), werden die Temperatur- und Druckwerte abgerufen.
  4. Sofort mit der Überprüfung des Statusregisters beginnen und die Temperatur- und Druckwerte abrufen, wenn das Statusbit 0 lautet.

Ich werde später ein Beispiel für eine Möglichkeit zeigen, dies zu tun.

Konfigurationsregisteroperationen

Um dies zu erreichen, benötigen wir einige Tools, die ich noch nicht eingeführt habe. Sie sind:

Byte readRegister (reg) void updateRegister (reg, value)

Jeder dieser Befehle verfügt über mehrere abgeleitete Befehle in der Bibliothek, die die Software für bestimmte Aktionen etwas vereinfachen.

Das Beispiel powerSaverPressureAndTemperature.ino verwendet die Methode Nr. 3. Die Codezeile, die die wiederholte Überprüfung durchführt, lautet

while (bmp0.readRegister (0xF3) >> 3); // Schleife bis F3bit 3 == 0

Beachten Sie, dass diese Skizze für einen ESP8266-Mikrocontroller gilt. Ich habe einen WeMos D1 mini pro verwendet. Die Skizze funktioniert nicht mit Atmega-Mikrocontrollern, die unterschiedliche Anweisungen zum Schlafen haben. In dieser Skizze werden mehrere andere Befehle ausgeführt, daher werde ich sie alle vorstellen, bevor ich diese Skizze ausführlicher beschreibe.

Wenn der Mikrocontroller parallel zum BMP280-Sensor schläft, kann die Konfiguration des Sensors für die erforderlichen Messungen im Befehl begin () unter Verwendung der 6 Parameter vorgenommen werden. Wenn jedoch der Mikrocontroller nicht schläft, sondern der Sensor, muss der Sensor zum Zeitpunkt der Messung aufgeweckt und über seine Messkonfiguration informiert werden. Dies kann direkt mit erfolgen

updateRegister (reg, value)

ist aber mit den folgenden drei Befehlen etwas einfacher:

updateF2Control (osrs_h); // Nur BME280 updateF4Control (osrs_t, osrs_p, mode); updateF5Config (t_sb, filter, spi3W_en);

Wenn nach Abschluss der Messung der Modus Einzelaufnahme (Erzwungener Modus) verwendet wird, geht das Gerät automatisch in den Ruhezustand zurück. Wenn der Messsatz jedoch mehrere Messungen im Dauermodus (Normal) umfasst, muss der BMP280 wieder in den Ruhezustand versetzt werden. Dies kann mit einem der beiden folgenden Befehle erfolgen:

updateF4Control16xSleep (); updateF4ControlSleep (Wert);

Beide setzen die Modusbits auf 00 (dh Schlafmodus). Das erste setzt jedoch osrs_t und osrs_p auf 111 (dh 16 Messungen), während das zweite die niedrigen 6 Bits von "value" in Bits 7: 2 des 0xF4-Registers speichert.

In ähnlicher Weise speichert die folgende Anweisung die niedrigen sechs Bits von "value" in den Bits 7: 2 des 0xF5-Registers.

updateF5ConfigSleep (Wert);

Die Verwendung dieser letzteren Befehle ermöglicht die Speicherung von 12 Informationsbits in den BMP280-Registern F4 und F5. Zumindest im Fall des ESP8266 beginnt der Mikrocontroller, wenn er nach einer Ruhephase aufwacht, am Anfang der Skizze ohne Kenntnis seines Zustands vor dem Ruhebefehl. Um die Kenntnis seines Zustands vor dem Schlafbefehl zu speichern, können Daten entweder mit den EEPROM-Funktionen oder durch Schreiben einer Datei mit SPIFFS im Flash-Speicher gespeichert werden. Der Flash-Speicher hat jedoch eine Begrenzung der Anzahl der Schreibzyklen in der Größenordnung von 10.000 bis 100.000. Das heißt, wenn der Mikrocontroller alle paar Sekunden einen Schlaf-Wach-Zyklus durchläuft, kann er in einigen Monaten die zulässige Speicherschreibgrenze überschreiten. Das Speichern einiger Datenbits im BMP280 unterliegt keiner solchen Einschränkung.

Die in den Registern F4 und F5 gespeicherten Daten können wiederhergestellt werden, wenn der Mikrocontroller mit den Befehlen aufwacht

readF4Sleep (); readF5Sleep ();

Diese Funktionen lesen das entsprechende Register, verschieben den Inhalt, um die 2 LSBs zu entfernen und die verbleibenden 6 Bits zurückzugeben. Diese Funktionen werden in der Beispielskizze powerSaverPressureAndTemperatureESP.ino wie folgt verwendet:

// Wert von EventCounter aus dem bmp0-Byte zurücklesen bmp0F4value = bmp0.readF4Sleep (); // 0 bis 63 Byte bmp0F5value = bmp0.readF5Sleep (); // 0 bis 63 eventCounter = bmp0F5value * 64 + bmp0F4value; // 0 bis 4095

Diese Funktionen lesen das entsprechende Register, verschieben den Inhalt, um die 2 LSBs zu entfernen und die verbleibenden 6 Bits zurückzugeben. Diese Funktionen werden in der Beispielskizze powerSaverPressureAndTemperature.ino wie folgt verwendet:

// Wert von EventCounter aus dem bmp1-Byte zurücklesen bmp1F4value = bmp1.readF4Sleep (); // 0 bis 63 Byte bmp1F5value = bmp1.readF5Sleep (); // 0 bis 63 eventCounter = bmp1F5value * 64 + bmp1F4value; // 0 bis 4095

Rohe Temperatur- und Druckfunktionen

Die grundlegenden Funktionen readTemperature, readPressure und readHumidity bestehen aus zwei Komponenten. Zuerst werden die rohen 20-Bit-Temperatur- und -Druckwerte vom BME / P280 erhalten, oder der rohe 16-Bit-Feuchtigkeitswert wird vom BME280 erhalten. Anschließend werden mit dem Kompensationsalgorithmus die Ausgangswerte in Grad Celsius, hPa oder% rF generiert.

Die Bibliothek bietet separate Funktionen für diese Komponenten, sodass die Rohdaten für Temperatur, Druck und Luftfeuchtigkeit abgerufen und möglicherweise auf irgendeine Weise manipuliert werden können. Der Algorithmus zum Ableiten der Temperatur, des Drucks und der Feuchtigkeit aus diesen Rohwerten wird ebenfalls bereitgestellt. In der Bibliothek werden diese Algorithmen unter Verwendung von Gleitkomma-Arithmetik doppelter Länge implementiert. Es funktioniert gut auf dem ESP8266, der ein 32-Bit-Prozessor ist und 64 Bit für "doppelte" Float-Variablen verwendet. Das Zugreifen auf diese Funktionen kann nützlich sein, um die Berechnung für andere Plattformen zu bewerten und möglicherweise zu ändern.

Diese Funktionen sind:

readRawPressure (rawTemperature); // liest Rohdruck- und Temperaturdaten aus BME / P280

readRawHumidity (rawTemperature, rawPressure); // liest Rohdaten zu Luftfeuchtigkeit, Temperatur und Druck aus BME280 calcTemperature (rawTemperature, t_fine); calcPressure (rawPressure, t_fine); calcHumidity (rawHumidity, t_fine)

Das Argument "t-fine" für diese Funktionen ist eine Erklärung wert. Sowohl Druck- als auch Feuchtigkeitskompensationsalgorithmen enthalten eine temperaturabhängige Komponente, die durch die Variable t_fine erreicht wird. Die Funktion calcTemperature schreibt einen Wert in t_fine basierend auf der Logik des Temperaturkompensationsalgorithmus, der dann sowohl in calcPressure als auch in calcHumidity als Eingabe verwendet wird.

Ein Beispiel für die Verwendung dieser Funktionen finden Sie in der Beispielskizze rawPressureAndTemperature.ino sowie im Code für die Funktion readHumidity () in der CPP-Datei der Bibliothek.

Höhen- und Meeresspiegeldruck

Es gibt eine bekannte Beziehung zwischen Luftdruck und Höhe. Das Wetter beeinflusst auch den Druck. Wenn die Wetterorganisationen Luftdruckinformationen veröffentlichen, passen sie diese normalerweise an die Höhe an. Die "Übersichtskarte" zeigt Isobaren (Linien mit konstantem Druck), die auf den mittleren Meeresspiegel normiert sind. Es gibt also wirklich 3 Werte in dieser Beziehung, und wenn zwei davon bekannt sind, kann der dritte abgeleitet werden. Die 3 Werte sind:

  • Höhe über dem Meeresspiegel
  • tatsächlicher Luftdruck in dieser Höhe
  • äquivalenter Luftdruck auf Meereshöhe (genauer gesagt mittlerer Meeresspiegel, da sich der momentane Meeresspiegel ständig ändert)

Diese Bibliothek bietet zwei Funktionen für diese Beziehung:

KalkHöhe (Druck, MeereshöhePa); calcNormalisedPressure (Druck, Höhe);

Es gibt auch eine vereinfachte Version, die den Standard-Meeresspiegeldruck von 1013,15 hPa annimmt.

calcAltitude (Druck); // standard seaLevelPressure angenommen

Schritt 3: BMP280-Gerätedetails

Hardware-Funktionen

Der BMP280 verfügt über 2 Byte Konfigurationsdaten (an den Registeradressen 0xF4 und 0xF5), die zur Steuerung mehrerer Mess- und Datenausgabeoptionen verwendet werden. Es enthält außerdem 2 Bit Statusinformationen und 24 Byte Kalibrierungsparameter, die zur Umrechnung der rohen Temperatur- und Druckwerte in herkömmliche Temperatur- und Druckeinheiten verwendet werden.

Der BME280 verfügt über folgende zusätzliche Daten:

  • 1 zusätzliches Byte Konfigurationsdaten an der Registeradresse 0xF2 zur Steuerung mehrerer Feuchtemessungen;
  • 8 zusätzliche Bytes an Kalibrierungsparametern, die zur Umrechnung des Rohfeuchtigkeitswerts in den relativen Feuchtigkeitsprozentsatz verwendet werden.

Die Temperatur-, Druck- und Statusregister für den BME280 sind dieselben wie für den BMP280, mit geringfügigen Ausnahmen wie folgt:

  • Die "ID" -Bits des BME280 sind auf 0x60 gesetzt, daher kann es von BMP280 unterschieden werden, das 0x56, 0x57 oder 0x58 sein kann
  • Die Sleep-Time-Steuerung (t_sb) wird so geändert, dass die beiden langen Zeiten im BMP280 (2000 ms und 4000 ms) im BME280 durch kurze Zeiten von 10 ms und 20 ms ersetzt werden. Die maximale Ruhezeit im BME280 beträgt 1000 ms.
  • Beim BME280 betragen die Rohwerte für Temperatur und Druck bei Filterung immer 20 Bit. Die Verwendung von 16 bis 19 Bit-Werten ist auf Fälle ohne Filterung beschränkt (dh Filter = 0).

Temperatur und Druck sind jeweils 20-Bit-Werte, die über einen recht komplexen Algorithmus mit 3 16-Bit-Kalibrierungsparametern für die Temperatur und 9 16-Bit-Kalibrierungsparametern plus der Temperatur für den Druck in herkömmliche Temperatur und Druck umgewandelt werden müssen. Die Körnigkeit der Temperaturmessung beträgt 0,0003 Grad Celsius für eine am wenigsten signifikante Bitänderung (20-Bit-Auslesung) und steigt auf 0,0046 Grad Celsius, wenn die 16-Bit-Auslesung verwendet wird.

Die Luftfeuchtigkeit ist ein 16-Bit-Wert, der mithilfe von 6 Kalibrierungsparametern, die eine Mischung aus 8, 12 und 16 Bit darstellen, über einen anderen komplexen Algorithmus in relative Luftfeuchtigkeit umgewandelt werden muss.

Das Datenblatt zeigt die absolute Genauigkeit der Temperaturanzeige mit + -0,5 ° C bei 25 ° C und + -1 ° C über den Bereich von 0 bis 65 ° C.

Die Granularität der Druckmessung beträgt 0,15 Pascal (dh 0,0015 Hektopascal) bei einer Auflösung von 20 Bit oder 2,5 Pascal bei einer Auflösung von 16 Bit. Der Rohdruckwert wird von der Temperatur beeinflusst, so dass bei 25 ° C ein Temperaturanstieg um 1 ° C den gemessenen Druck um 24 Pascal senkt. Die Temperaturempfindlichkeit wird im Kalibrierungsalgorithmus berücksichtigt, daher sollten die gelieferten Druckwerte bei verschiedenen Temperaturen genau sein.

Das Datenblatt zeigt die absolute Genauigkeit der Druckanzeige als + -1 hPa für Temperaturen zwischen 0 ° C und 65 ° C.

Die Genauigkeit der Luftfeuchtigkeit wird im Datenblatt als + -3% relative Luftfeuchtigkeit und + -1% Hysterese angegeben.

Wie es funktioniert

Die 24 Byte Temperatur- und Druckkalibrierungsdaten sowie beim BME280 die 8 Byte Feuchtekalibrierungsdaten müssen aus dem Gerät gelesen und in Variablen gespeichert werden. Diese Daten werden werkseitig individuell in das Gerät programmiert, sodass unterschiedliche Geräte unterschiedliche Werte haben - zumindest für einige der Parameter.

Ein BME / P280 kann sich in einem von zwei Zuständen befinden. In einem Zustand misst es. Im anderen Zustand wartet es (schläft).

Welchen Status es hat, können Sie anhand von Bit 3 des Registers 0xF3 überprüfen.

Die Ergebnisse der letzten Messung können jederzeit durch Ablesen des entsprechenden Datenwerts abgerufen werden, unabhängig davon, ob das Gerät schläft oder misst.

Es gibt auch zwei Möglichkeiten, den BME / P280 zu bedienen. Eine davon ist der kontinuierliche Modus (im Datenblatt als normaler Modus bezeichnet), der wiederholt zwischen den Zuständen Messen und Schlafen wechselt.In diesem Modus führt das Gerät eine Reihe von Messungen durch, geht dann in den Ruhezustand und wacht dann für eine weitere Reihe von Messungen auf und so weiter. Die Anzahl der Einzelmessungen und die Dauer des Ruheteils des Zyklus können alle über die Konfigurationsregister gesteuert werden.

Die andere Betriebsart des BME / P280 ist der Single Shot-Modus (im Datenblatt als Forced-Modus bezeichnet). In diesem Modus wird das Gerät durch einen Befehl zum Messen aus dem Ruhezustand geweckt, führt eine Reihe von Messungen durch und geht dann wieder in den Ruhezustand. Die Anzahl der Einzelmessungen im Set wird im Konfigurationsbefehl gesteuert, der das Gerät aufweckt.

Wenn im BMP280 eine einzelne Messung durchgeführt wird, werden die 16 höchstwertigen Bits im Wert gefüllt, und die vier niedrigstwertigen Bits im ausgelesenen Wert sind alle Nullen. Die Anzahl der Messungen kann auf 1, 2, 4, 8 oder 16 eingestellt werden, und wenn die Anzahl der Messungen erhöht wird, erhöht sich die Anzahl der mit Daten besetzten Bits, so dass bei 16 Messungen alle 20 Bits mit Messdaten besetzt werden. Das Datenblatt bezeichnet diesen Vorgang als Oversampling.

Im BME280 gilt die gleiche Anordnung, solange das Ergebnis nicht gefiltert wird. Bei Verwendung der Filterung sind die Werte immer 20 Bit, unabhängig davon, wie viele Messungen in jedem Messzyklus durchgeführt werden.

Jede Einzelmessung dauert ca. 2 Millisekunden (typischer Wert; maximaler Wert 2,3 ms). Hinzu kommt, dass ein fester Overhead von ca. 2 ms (in der Regel etwas weniger) bedeutet, dass eine Messsequenz, die aus 1 bis 32 Einzelmessungen bestehen kann, 4 ms bis 66 ms dauern kann.

Das Datenblatt enthält eine Reihe empfohlener Kombinationen von Temperatur- und Drucküberabtastungen für verschiedene Anwendungen.

Konfigurationssteuerregister

Die beiden Konfigurationssteuerregister im BMP280 befinden sich an den Registeradressen 0xF4 und 0xF5 und sind auf 6 einzelne Konfigurationssteuerwerte abgebildet. 0xF4 besteht aus:

  • 3 Bits osrs_t (Messen der Temperatur 0, 1, 2, 4, 8 oder 16 Mal);
  • 3 Bits osrs_p (Druck 0, 1, 2, 4, 8 oder 16-mal messen); und
  • 2-Bit-Modus (Sleep, Forced (dh Single Shot), Normal (dh kontinuierlich).

0xF5 besteht aus:

  • 3 Bits t_sb (Standby-Zeit, 0,5 ms bis 4000 ms);
  • 3-Bit-Filter (siehe unten); und
  • 1 Bit spiw_en, das SPI oder I2C auswählt.

Der Filterparameter steuert eine Art Exponential Decay-Algorithmus oder Infinite Impulse Response (IIR) -Filter, der auf die Rohdruck- und Temperaturmesswerte angewendet wird (jedoch nicht auf die Feuchtigkeitswerte). Die Gleichung ist im Datenblatt angegeben. Eine weitere Präsentation ist:

Wert (n) = Wert (n-1) * (K-1) / K + Messung (n) / K

wobei (n) den neuesten Mess- und Ausgabewert angibt; und K ist der Filterparameter. Der Filterparameter K und kann auf 1,2,4,8 oder 16 gesetzt werden. Wenn K auf 1 gesetzt ist, wird die Gleichung einfach zu Wert (n) = Maß (n). Die Kodierung des Filterparameters lautet:

  • Filter = 000, K = 1
  • Filter = 001, K = 2
  • Filter = 010, K = 4
  • Filter = 011, K = 8
  • Filter = 1xx, K = 16

Das BME 280 fügt ein weiteres Konfigurationssteuerregister unter der Adresse 0xF2 "ctrl_hum" mit einem einzelnen 3-Bit-Parameter osrs_h hinzu (misst die Luftfeuchtigkeit 0, 1, 2, 4, 8 oder 16 Mal).

Schritt 4: Messung und Auslesezeit

Ich plane, dies später hinzuzufügen und das Timing von Befehlen und Messungsantworten zu zeigen.

Iddt - Strom bei Temperaturmessung. Typischer Wert 325 uA

Iddp - Strom bei Druckmessung. Typischer Wert 720 uA, max. 1120 uA

Iddsb - aktuell im Standby-Modus. Typischer Wert 0,2 uA, max. 0,5 uA

Iddsl - aktuell im Schlafmodus. Typischer Wert 0,1 uA, maximal 0,3 uA

Schritt 5: Softwarerichtlinien

I2C-Burst-Modus

Das BMP280-Datenblatt enthält Anleitungen zum Auslesen von Daten (Abschnitt 3.9). "Es wird dringend empfohlen, ein Burst-Lesen zu verwenden und nicht jedes Register einzeln zu adressieren. Dies verhindert eine mögliche Verwechslung von Bytes, die zu verschiedenen Messungen gehören, und verringert den Schnittstellenverkehr."

Es wird keine Anleitung zum Ablesen der Kompensations- / Kalibrierungsparameter gegeben. Vermutlich sind diese kein Problem, da sie statisch sind und sich nicht ändern.

Diese Bibliothek liest alle zusammenhängenden Werte in einem Lesevorgang - 24 Bytes bei den Temperatur- und Druckkompensationsparametern, 6 Bytes bei Temperatur und Druck zusammen und 8 Bytes bei Feuchtigkeit, Temperatur und Druck zusammen. Wenn nur die Temperatur geprüft wird, werden nur 3 Bytes gelesen.

Verwendung von Makros (#define etc.)

Diese Bibliothek enthält keine anderen Makros als das übliche "include guard" -Makro der Bibliothek, mit dem Duplizierungen verhindert werden.

Alle Konstanten werden mit dem Schlüsselwort const definiert, und der Debug-Druck wird mit Standard-C-Funktionen gesteuert.

Es war die Quelle einiger Unsicherheiten für mich, aber der Ratschlag, den ich beim Lesen vieler Posts zu diesem Thema bekomme, ist, dass die Verwendung von #define zur Deklaration von Konstanten (zumindest) und (wahrscheinlich) zur Debug-Drucksteuerung unnötig und unerwünscht ist.

Der Fall für die Verwendung von const anstelle von #define ist ziemlich klar - const verwendet die gleichen Ressourcen wie #define (dh nil) und die resultierenden Werte folgen den Gültigkeitsregeln, wodurch die Wahrscheinlichkeit von Fehlern verringert wird.

Der Fall für die Debug-Drucksteuerung ist etwas unklarer, da der endgültige Code, wie ich es getan habe, die Logik für die Debug-Druckanweisungen enthält, auch wenn sie nie ausgeführt werden. Wenn die Bibliothek in einem großen Projekt auf einem Mikrocontroller mit sehr begrenztem Speicher verwendet werden soll, kann dies zu einem Problem werden. Da sich meine Entwicklung auf einem ESP8266 mit großem Flash-Speicher befand, schien dies für mich kein Problem zu sein.

Schritt 6: Temperaturleistung

Ich habe vor, dies später hinzuzufügen.

Schritt 7: Druckleistung

Ich habe vor, dies später hinzuzufügen.