Inhaltsverzeichnis:

Bibliothek für BMP280 und BME280 - Gunook
Bibliothek für BMP280 und BME280 - Gunook

Video: Bibliothek für BMP280 und BME280 - Gunook

Video: Bibliothek für BMP280 und BME280 - Gunook
Video: Arduino - Library BME280 installation / Beispielsketch 2024, Juli
Anonim
Bibliothek für BMP280 und BME280
Bibliothek für BMP280 und BME280
Bibliothek für BMP280 und BME280
Bibliothek für BMP280 und BME280
Bibliothek für BMP280 und BME280
Bibliothek für BMP280 und BME280

Einführung

Ich hatte nicht vor, diese Bibliothek zu schreiben. Es "passierte" als Nebeneffekt eines von mir gestarteten Projekts, das einen BMP280 verwendet. Dieses Projekt ist noch nicht abgeschlossen, aber ich denke, die Bibliothek ist bereit, sie mit anderen zu teilen. Später musste ich einen BME280 verwenden, der die Druck- und Temperaturfähigkeit des BMP280 um Feuchtigkeitsmessung ergänzt. Der BME280 ist mit dem BMP280 "abwärtskompatibel" - das heißt, alle Register und Schritte, die zum Lesen von Druck und Temperatur vom BME280 erforderlich sind, sind dieselben wie beim BMP280. Zum Lesen der Luftfeuchtigkeit sind zusätzliche Register und Schritte erforderlich, die nur für das 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 (zB bei Ebay und AliExpress) sind mit BME/P280 gekennzeichnet. Um herauszufinden, um welchen Typ es sich handelt, muss man sich die (kleine) Schrift auf dem Sensor selbst anschauen oder das Geräte-ID-Byte testen. Ich habe mich für eine einzelne Bibliothek entschieden. Es scheint gut geklappt zu haben.

Feedback, insbesondere Verbesserungsvorschläge, sind willkommen.

Bibliotheksfunktionen und -funktionen

Eine Bibliothek ist eine Software, die einem Programmierer eine Anwendungsprogrammierschnittstelle (API) zur Verfügung stellt, um die Fähigkeiten des Geräts auszuüben, ohne sich unbedingt mit allen feinkörnigen Details befassen zu müssen. Wünschenswerterweise sollte die API für einen Anfänger mit einfachen Anforderungen einfach sein und gleichzeitig die volle Ausschöpfung der Gerätefunktionen ermöglichen. Es ist wünschenswert, dass die Bibliothek alle spezifischen Richtlinien des Geräteherstellers sowie allgemeine bewährte Softwarepraktiken befolgt. Ich habe mich bemüht, all dies zu erreichen. Als ich mit dem BMP280 anfing, fand ich 3 verschiedene Bibliotheken dafür: Adafruit_BMP280; Seeed_BMP280; und einer 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 man das vom Gerätehersteller (Bosch Sensortec) produzierte verwendet. Das mag eher mein Mangel sein als ihrer. Allerdings war die Bibliothek viel komplizierter als die beiden anderen, ich konnte keine Anleitungen oder Anwendungsbeispiele finden (ich habe später Beispiele in der Datei "bmp280_support.c" gefunden, die mir jedoch nicht besonders geholfen haben).

Aufgrund dieser Faktoren habe ich mich entschieden, eine eigene Bibliothek für den BMP280 zu schreiben.

Als ich die Bibliothekssituation für das BME280 untersuchte, fand ich separate Bibliotheken Adafruit_BME280, Seed_BME280 und eine weitere BME280_MOD-1022, die von Embedded Adventures geschrieben wurde. Keiner von ihnen kombinierte die Funktionen für BMP280 in einer Bibliothek, die den BME280 verwenden kann. Keiner von ihnen unterstützte ausdrücklich die Fähigkeit der Geräte, einige Datenbits zu speichern, während das Gerät und sein steuernder Mikroprozessor im Ruhezustand sind (diese Fähigkeit ist im Datenblatt ersichtlich und wird in der Bibliothek unterstützt, die ich hier geschrieben und beschrieben habe).

Eine kombinierte Bibliothek sollte alle Fähigkeiten des BME280 unterstützen, aber wenn sie mit einem BMP280 verwendet wird, sollte sie keinen Overhead durch die ungenutzten Funktionen verursachen. Zu den Vorteilen einer kombinierten Bibliothek gehören weniger zu verwaltende Bibliotheksdateien, einfaches Mischen und Abgleichen verschiedener Geräte im selben Projekt und vereinfachte Änderungen für Wartung oder Upgrades, die nur an einer Stelle statt an zwei durchgeführt werden müssen. Diese sind wahrscheinlich alle ziemlich unbedeutend, sogar unbedeutend, aber …

Gerätefunktionen

Der BMP280 und BME280 sind oberflächenmontierte Geräte mit etwa 5 mm im Quadrat und 1 mm Höhe. Es gibt 8 Schnittstellen-Pads, darunter 2 separate Stromeingangs-Pads und zwei Ground-Pads. Sie sind bei eBay als Modul mit entweder 4 oder 6 herausgebrachten Pins erhältlich. Das 4-Pin-Modul hat eine feste I2C-Adresse und kann nicht für die Verwendung des SPI-Protokolls konfiguriert werden.

Das 6-Pin-Modul oder das Bare-Device können entweder mit I2C- oder SPI-Protokollen verwendet werden. Im I2C-Modus kann es zwei verschiedene Adressen haben, die durch Verbinden des SDO-Pins entweder mit Masse (für Basisadresse = 0x76) oder mit Vdd (für Basisadresse +1 = 0x77) erreicht werden. Im SPI-Modus hat er die übliche Anordnung von 1 Takt, 2 Daten (einer für jede Richtung) und einem Geräteauswahl-Pin (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

Schritt 1: Einrichten der Hardware

Einrichten der Hardware
Einrichten der Hardware

Bevor die Bibliothek nützlich sein kann, muss ein Mikrocontroller an den BMP280 (oder auf Wunsch an zwei davon) angeschlossen werden.

Ich habe ein WeMos D1 mini pro verwendet, daher werde ich seine Verbindungen zeigen. Andere Mikrocontroller werden ähnlich sein, Sie müssen nur die SDA- und SCL-Pins richtig anschließen.

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 Ground GND Adresssteuerung SDO Ground oder Vdd I2C Select CSB Vdd (GND wählt SPI)

Beachten Sie, dass der SDO-Pin einiger MP280-Module mit SDD und der Vdd-Pin möglicherweise mit VCC bezeichnet ist. Hinweis: SDA- und SCL-Leitungen sollten Pullup-Widerstände zwischen der Leitung und dem Vin-Pin haben. Normalerweise sollte ein Wert von 4,7 KB OK sein. Einige BMP280- und BME280-Module verfügen über 10K-Pull-up-Widerstände im Modul (was keine gute Praxis ist, da das Anschließen mehrerer Geräte an den I2C-Bus diesen übermäßig belasten kann). Die Verwendung von 2 BME/P280-Modulen mit jeweils einem 10K-Widerstand sollte jedoch in der Praxis kein Problem darstellen, solange nicht zu viele andere Geräte am gleichen Bus auch mit Pull-Up-Widerständen vorhanden sind.

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:

Ob Sie einen BMP280 oder BME280 besitzen, können Sie auch am Gerät selbst überprüfen. Ich fand es notwendig, dafür ein digitales Mikroskop zu verwenden, aber wenn Sie sehr gut sehen, können Sie dies möglicherweise ohne Hilfsmittel tun. Auf dem Gehäuse des Geräts befinden sich zwei Druckzeilen. 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

Von der Bibliothek bereitgestellte APIs
Von der Bibliothek bereitgestellte APIs
Von der Bibliothek bereitgestellte APIs
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 in den frühen Teil der Skizze eingefügt werden.

Erstellen eines BME- oder BMP-Softwareobjekts

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

bme280 Objektname; oder bmp280 Objektname;

zum Beispiel BMP280 bmp0;

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

Die nächste Ebene zum Erstellen eines BME280- oder BMP280-Softwareobjekts hat einen Parameter von entweder 0 oder 1, wie folgt:

bme280 ObjektnameA(0);

bmp280 ObjektnameB(1);

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

Die dritte Ebene zum Erstellen eines BME- oder BMP280-Softwareobjekts hat zwei Parameter. Der erste Parameter, der entweder 0 oder 1 ist, ist wie im vorherigen Fall für die Adresse. Der zweite Parameter steuert das Debug-Drucken. Wenn es auf 1 gesetzt ist, führt jede Transaktion mit dem Softwareobjekt zu Serial.print-Ausgaben, die es dem Programmierer ermöglichen, die Details der Transaktion zu sehen. Zum Beispiel:

bmp280 ObjektnameB(1, 1);

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

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

Initialisieren des BME- oder BMP-Softwareobjekts

Vor der Verwendung ist es notwendig, die Kalibrierparameter aus dem Gerät auszulesen und es für jeden geeigneten Messmodus, Oversampling und Filtereinstellungen zu konfigurieren.

Für eine einfache, universelle Initialisierung lautet die Anweisung:

Objektname.begin();

Diese Version von begin() liest die Kalibrierparameter aus dem Gerät und setzt osrs_t=7 (16 Temperaturmessungen), osrs_p=7 (16 Druckmessungen), mode=3 (kontinuierlich, Normal), t_sb=0 (0,5 ms Schlaf zwischen Messreihen), 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 benötigt. Das Äquivalent der obigen Aussage ist

Objektname.begin(7, 7, 3, 0, 0, 0); // osrs_t, osrs_p, Modus, 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 Datenblatt BME280 und BMP280 sowie in den Kommentaren in der.cpp-Datei in der Bibliothek.

Einfache Temperatur- und Druckmessung

Um eine Temperaturmessung zu erhalten, ist der einfachste Weg

doppelte Temperatur = Objektname.readTemperature (); // Temperatur messen

Um eine Druckmessung zu erhalten, ist der einfachste Weg

doppelter Druck = Objektname.readPressure (); // Druck messen

Um eine Feuchtigkeitsmessung zu erhalten, ist der einfachste Weg

doppelte Feuchtigkeit = Objektname.readHumidity (); // Feuchtigkeit messen (nur BME280)

Um sowohl Temperatur als auch Druck zu erhalten, können die obigen beiden Aussagen nacheinander verwendet werden, aber es gibt noch eine andere Option, nämlich:

doppelte Temperatur;

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

Diese Anweisung liest die Daten vom BME280- oder BMP280-Gerät nur einmal 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 den BME 280 lautet eine kombinierte Aussage, die alle drei Werte (Feuchtigkeit, Temperatur und Druck) erhält:

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

Diese Anweisung liest die Daten vom BMP280-Gerät nur einmal 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 nach Belieben geändert werden können, aber ihre Reihenfolge ist festgelegt - Temperatur steht an erster Stelle und Druck an zweiter Stelle.

Diese Anwendungsfälle werden in Beispielskizzen behandelt, die mit der Bibliothek bereitgestellt werden, nämlich basicTemperature.ino, basicPressure.ino, basicHumidity.ino, basicTemperatureAndPressure.ino und basicHumidityAndTemperatureAndPressure.ino.

Anspruchsvollere Temperatur- und Druckmessung

Obwohl die obige Reihe von Anweisungen ohne Probleme funktioniert, gibt es ein paar Probleme:

  1. das Gerät läuft ununterbrochen und verbraucht daher maximal Strom. Wenn die Energie aus einer Batterie stammt, kann es erforderlich sein, diese zu reduzieren.
  2. Aufgrund des verbrauchten Stroms erwärmt sich das Gerät und die gemessene Temperatur ist daher höher als die Umgebungstemperatur. Ich werde dies in einem späteren Schritt mehr behandeln.

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

Objektname.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, wecken Sie das Gerät dann mit einem Konfigurationsbefehl in den Registern F2 (falls erforderlich) und F4 auf, der die entsprechenden Werte von osrs_h, osrs_t und osrs_p setzt, plus mode=1 (Single-Shot-Modus). Zum Beispiel:

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

Nachdem das Gerät aufgeweckt wurde, beginnt es mit der Messung, aber das Ergebnis steht für einige Millisekunden nicht zur Verfügung - 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 akzeptabel sein kann, aber in den meisten Fällen ist es wahrscheinlich besser, zu warten, bis die neue Messung verfügbar ist.

Diese Verzögerung kann auf verschiedene Weise erfolgen.

  1. warten Sie eine bestimmte Zeit, um die längste erwartete Verzögerung abzudecken
  2. Warten Sie eine Zeit, die aus der maximalen Messzeit pro Messung (dh 2,3 ms) mal der Anzahl der Messungen plus Overhead plus Spielraum berechnet wird.
  3. Warten Sie eine kürzere Zeit, die wie oben berechnet wurde, verwenden Sie jedoch die nominelle Messzeit (dh 2 ms) plus Overhead, und beginnen Sie dann mit der Überprüfung des "Ich messe"-Bits im Statusregister. Wenn das Statusbit 0 anzeigt (dh keine Messung), rufen Sie die Temperatur- und Druckwerte ab.
  4. Beginnen Sie sofort mit der Überprüfung des Statusregisters und erhalten Sie die Temperatur- und Druckwerte, wenn das Statusbit 0 anzeigt,

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

Konfigurationsregisteroperationen

Um all dies zu ermöglichen, benötigen wir mehrere Tools, die ich noch nicht vorgestellt habe. Sie sind:

Byte readRegister(reg)

void updateRegister(reg, Wert)

Jeder davon hat mehrere abgeleitete Befehle in der Bibliothek, die die Software für bestimmte Aktionen etwas einfacher machen.

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

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

Beachten Sie, dass diese Skizze für einen ESP8266-Mikrocontroller gilt. Ich habe ein WeMos D1 Mini Pro verwendet. Die Skizze funktioniert nicht mit Atmega-Mikrocontrollern, die unterschiedliche Anweisungen zum Schlafen haben. Diese Skizze übt mehrere andere Befehle aus, daher werde ich sie alle vorstellen, bevor ich diese Skizze genauer beschreibe.

Wenn der Mikrocontroller parallel zum BMP280-Sensor schläft, kann die Konfiguration des Sensors für die erforderlichen Messungen im Befehl begin() mit den 6 Parametern vorgenommen werden. Wenn jedoch der Mikrocontroller nicht schläft, der Sensor jedoch, dann muss der Sensor zum Zeitpunkt der Messung aufgeweckt und seine Messkonfiguration mitgeteilt werden. Das geht direkt mit

updateRegister(reg, Wert)

ist aber mit den folgenden drei Befehlen etwas einfacher:

updateF2Control(osrs_h); // Nur BME280

updateF4Control(osrs_t, osrs_p, Modus); updateF5Config(t_sb, filter, spi3W_en);

Wenn nach der Messung der verwendete Modus Einzelschuss (erzwungener Modus) ist, geht das Gerät automatisch in den Ruhezustand zurück. Wenn der Messsatz jedoch mehrere Messungen im kontinuierlichen Modus (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). Der erste setzt jedoch osrs_t und osrs_p auf 111 (dh 16 Messungen), während der zweite die unteren 6 Bits von "value" in Bits 7:2 des 0xF4-Registers speichert.

In ähnlicher Weise speichert die folgende Anweisung die unteren sechs Bits von "Wert" 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 beim ESP8266 startet der Mikrocontroller beim Aufwachen nach einer Schlafphase am Anfang des Sketches, ohne seinen Zustand vor dem Schlafbefehl zu kennen. Um das Wissen über seinen Zustand vor dem Sleep-Befehl zu speichern, können Daten im Flash-Speicher gespeichert werden, entweder unter Verwendung der EEPROM-Funktionen oder durch Schreiben einer Datei mit SPIFFS. Flash-Speicher hat jedoch eine Begrenzung der Anzahl der Schreibzyklen in der Größenordnung von 10.000 bis 100.000. Dies bedeutet, dass der Mikrocontroller, wenn er alle paar Sekunden einen Schlaf-Wach-Zyklus durchläuft, die zulässigen Speicherschreibvorgänge überschreiten kann in einigen Monaten begrenzen. Das Speichern einiger Datenbits im BMP280 hat keine solche Einschränkung.

Die in den Registern F4 und F5 gespeicherten Daten können beim Aufwachen des Mikrocontrollers mit den Befehlen wiederhergestellt werden

readF4Sleep();

readF5Sleep();

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

// Wert von EventCounter von bmp0 zurücklesen

Byte 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 geben die restlichen 6 Bits zurück. Diese Funktionen werden in der Beispielskizze powerSaverPressureAndTemperature.ino wie folgt verwendet:

// Wert von EventCounter von bmp1 zurücklesen

Byte bmp1F4value= bmp1.readF4Sleep(); // 0 bis 63 Byte bmp1F5value= bmp1.readF5Sleep(); // 0 bis 63 eventCounter= bmp1F5value*64+bmp1F4value; // 0 bis 4095

Rohtemperatur- 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 oder der rohe 16-Bit-Feuchtewert vom BME280 abgerufen. Anschließend werden über den Kompensationsalgorithmus die Ausgabewerte in Grad Celsius, hPa oder %RH generiert.

Die Bibliothek bietet separate Funktionen für diese Komponenten, so dass die Rohdaten für Temperatur, Druck und Feuchtigkeit erhalten und möglicherweise in irgendeiner Weise manipuliert werden können. Der Algorithmus zur Ableitung von Temperatur, Druck und Feuchtigkeit aus diesen Rohwerten wird ebenfalls bereitgestellt. In der Bibliothek sind diese Algorithmen unter Verwendung von Gleitkommaarithmetik mit doppelter Länge implementiert. Es funktioniert gut auf dem ESP8266, einem 32-Bit-Prozessor, der 64 Bit für "doppelte" Float-Variablen verwendet. Die Zugänglichmachung dieser Funktionen kann hilfreich sein, um die Berechnung für andere Plattformen zu bewerten und möglicherweise zu ändern.

Diese Funktionen sind:

readRawPressure (rawTemperature); // liest Rohdruck- und Temperaturdaten von BME/P280readRawHumidity (rawTemperature, rawPressure); // liest rohe Feuchtigkeits-, Temperatur- und Druckdaten von BME280 calcTemperature (rawTemperature, t_fine); calcPressure (rawPressure, t_fine); calcHumidity (rawHumidity, t_fine)

Das Argument "t-fine" für diese Funktionen ist eine Erläuterung wert. Sowohl Druck- als auch Feuchtigkeitskompensationsalgorithmen enthalten eine temperaturabhängige Komponente, die durch die Variable t_fine erreicht wird. Die Funktion calcTemperature schreibt basierend auf der Logik des Temperaturkompensationsalgorithmus einen Wert in t_fine, der dann als Eingabe in calcPressure und calcHumidity 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öhe und Meeresspiegeldruck

Es gibt eine bekannte Beziehung zwischen Atmosphärendruck und Höhe. Auch das Wetter beeinflusst den Druck. Wenn die Wetterorganisationen Luftdruckinformationen veröffentlichen, passen sie diese normalerweise an die Höhe an, und so zeigt die "Synoptische Karte" Isobaren (Linien konstanten Drucks), die auf den mittleren Meeresspiegel standardisiert sind. Es gibt also wirklich 3 Werte in dieser Beziehung, und die Kenntnis von zwei davon ermöglicht die Ableitung des dritten. 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, wie folgt:

calcAltitude (Druck, seaLevelhPa);

calcNormalisedPressure (Druck, Höhe);

Es gibt auch eine vereinfachte Version, die den Standarddruck auf Meereshöhe von 1013,15 hPa annimmt.

calcHöhe (Druck); // Standard seaLevelPressure angenommen

Schritt 3: BMP280-Gerätedetails

BMP280 Gerätedetails
BMP280 Gerätedetails

Hardwarefunktionen

Der BMP280 verfügt über 2 Byte Konfigurationsdaten (an den Registeradressen 0xF4 und 0xF5), die zur Steuerung mehrerer Mess- und Datenausgabeoptionen verwendet werden. Es bietet auch 2 Bit Statusinformationen und 24 Byte Kalibrierparameter, die bei der Umwandlung der Rohtemperatur- und Druckwerte in konventionelle Temperatur- und Druckeinheiten verwendet werden. Der BME280 hat folgende zusätzliche Daten:

  • 1 zusätzliches Byte Konfigurationsdaten an der Registeradresse 0xF2 zur Steuerung mehrerer Feuchtigkeitsmessungen;
  • 8 zusätzliche Bytes Kalibrierungsparameter, die bei der Umwandlung des rohen Feuchtigkeitswerts in den Prozentsatz der relativen Feuchtigkeit verwendet werden.

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

  • die "ID"-Bits des BME280 sind auf 0x60 gesetzt, so dass es von BMP280 unterschieden werden kann, die 0x56, 0x57 oder 0x58 sein können
  • 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 Temperatur- und Druck-Rohwerte 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 ziemlich komplexen Algorithmus unter Verwendung von 3 16-Bit-Kalibrierparametern für die Temperatur und 9 16-Bit-Kalibrierparametern plus der Temperatur für Druck in konventionelle Temperatur und Druck umgewandelt werden müssen. Die Granularität der Temperaturmessung beträgt 0,0003 Grad Celsius für eine niedrigstwertige Bitänderung (20-Bit-Auslesung) und erhöht sich auf 0,0046 Grad Celsius, wenn die 16-Bit-Auslesung verwendet wird.

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

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

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

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

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

Wie es funktioniert

Die 24 Byte Temperatur- und Druck-Kalibrierdaten sowie beim BME280 auch die 8 Byte Feuchte-Kalibrierdaten müssen aus dem Gerät gelesen und in Variablen gespeichert werden. Diese Daten werden werkseitig individuell in das Gerät einprogrammiert, so dass unterschiedliche Geräte unterschiedliche Werte haben – zumindest für einige Parameter. Ein BME/P280 kann sich in einem von zwei Zuständen befinden. In einem Zustand misst es. Im anderen Zustand wartet (schläft).

In welchem Zustand es sich befindet, kann anhand von Bit 3 von Register 0xF3 überprüft werden.

Das Ergebnis der letzten Messung kann jederzeit durch Ablesen des entsprechenden Datenwertes abgerufen werden, unabhängig davon, ob das Gerät schläft oder misst.

Es gibt auch zwei Möglichkeiten, das BME/P280 zu bedienen. Einer ist der kontinuierliche Modus (im Datenblatt als Normalmodus 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 Schlafmodus, wacht dann für eine weitere Reihe von Messungen auf und so weiter. Die Anzahl der Einzelmessungen und die Dauer des Schlafabschnitts des Zyklus können alle über die Konfigurationsregister gesteuert werden.

Die andere Möglichkeit, das BME/P280 zu bedienen, ist der Single Shot-Modus (im Datenblatt als Forced-Modus bezeichnet). In diesem Modus wird das Gerät durch einen Messbefehl aus dem Schlaf geweckt, führt eine Reihe von Messungen durch und geht dann wieder in den Schlaf zurück. 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 belegt und die vier niedrigstwertigen Bits in der Wertanzeige sind alle Nullen. Die Anzahl der Messungen kann auf 1, 2, 4, 8 oder 16 eingestellt werden und mit zunehmender Anzahl von Messungen erhöht sich die Anzahl der Bits, die mit Daten gefüllt sind, so dass bei 16 Messungen alle 20 Bits mit Messdaten gefüllt sind. Im Datenblatt wird dieser Vorgang als Oversampling bezeichnet.

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

Jede einzelne Messung dauert ca. 2 Millisekunden (typischer Wert; Maximalwert 2,3 ms). Hinzu kommt ein fester Overhead von ca. 2 ms (meist etwas weniger), 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überabtastung für verschiedene Anwendungen.

Konfigurationssteuerregister

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

  • 3 Bit osrs_t (Temperatur 0, 1, 2, 4, 8 oder 16 mal messen);
  • 3 Bit 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 Bit 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 exponentiellen Abklingalgorithmus oder Infinite Impulse Response (IIR)-Filter, der auf die Rohdruck- und Temperaturmesswerte (aber nicht auf die Feuchtigkeitswerte) angewendet wird. Die Gleichung ist im Datenblatt angegeben. Eine andere Präsentation ist:

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

wobei (n) den letzten Mess- und Ausgabewert angibt; und K ist der Filterparameter. Der Filterparameter K und kann auf 1, 2, 4, 8 oder 16 eingestellt werden. Wenn K auf 1 gesetzt wird, wird die Gleichung nur Wert(n) = Messung(n). Die Codierung 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 an Adresse 0xF2, "ctrl_hum" mit einem einzigen 3-Bit-Parameter osrs_h (Feuchte 0, 1, 2, 4, 8 oder 16 mal messen) hinzu.

Schritt 4: Mess- und Auslesezeitpunkt

Ich plane, dies später hinzuzufügen und das Timing von Befehlen und Messantworten anzuzeigen.

Iddt - Strom bei Temperaturmessung. Typischer Wert 325 uA

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

Iddsb - Strom im Standby-Modus. Typischer Wert 0,2 µA, max 0,5 µA

Iddsl - Strom im Ruhemodus. Typischer Wert 0,1 µA, max 0,3 µA

Schritt 5: Softwarerichtlinien

Software-Richtlinien
Software-Richtlinien
Software-Richtlinien
Software-Richtlinien

I2C Burst-Modus

Das Datenblatt des BMP280 enthält eine Anleitung zum Auslesen der Daten (Abschnitt 3.9). Darin heißt es: "Es wird dringend empfohlen, einen Burst-Read zu verwenden und nicht jedes Register einzeln anzusprechen. Dies verhindert eine mögliche Verwechslung von Bytes, die zu verschiedenen Messungen gehören, und reduziert den Schnittstellenverkehr." Es wird keine Anleitung zum Ablesen der Kompensations-/Kalibrierungsparameter gegeben. Vermutlich sind diese kein Thema, da sie statisch sind und sich nicht ändern.

Diese Bibliothek liest alle zusammenhängenden Werte in einem einzigen Lesevorgang – 24 Byte bei den Temperatur- und Druckkompensationsparametern, 6 Byte für Temperatur und Druck kombiniert und 8 Byte für Feuchte, Temperatur und Druck kombiniert. Wenn nur die Temperatur geprüft wird, werden nur 3 Byte gelesen.

Verwendung von Makros (#define etc.)

Es gibt keine anderen Makros in dieser Bibliothek als das übliche "include guard"-Makro, das eine Duplizierung verhindert.

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

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

Die Argumente für die Verwendung von const anstelle von #define sind ziemlich klar - const verwendet die gleichen Ressourcen wie #define (dh nil) und die resultierenden Werte folgen den Bereichsregeln, wodurch die Fehlerwahrscheinlichkeit verringert wird.

Der Fall für die Debug-Drucksteuerung ist etwas weniger klar, da meine Vorgehensweise bedeutet, dass der endgültige Code die Logik für die Debug-Druckanweisungen enthält, obwohl 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 zum Problem werden. Da meine Entwicklung auf einem ESP8266 mit großem Flashspeicher lag, schien dies für mich kein Thema zu sein.

Schritt 6: Temperaturleistung

Ich plane, dies später hinzuzufügen.

Schritt 7: Druckleistung

Ich plane, dies später hinzuzufügen.

Empfohlen: