Inhoudsopgave:

Bibliotheek voor BMP280 en BME280: 7 stappen
Bibliotheek voor BMP280 en BME280: 7 stappen

Video: Bibliotheek voor BMP280 en BME280: 7 stappen

Video: Bibliotheek voor BMP280 en BME280: 7 stappen
Video: BME280, Датчик атмосферного давления с гигрометром 2024, Juli-
Anonim
Bibliotheek voor BMP280 en BME280
Bibliotheek voor BMP280 en BME280
Bibliotheek voor BMP280 en BME280
Bibliotheek voor BMP280 en BME280
Bibliotheek voor BMP280 en BME280
Bibliotheek voor BMP280 en BME280

Invoering

Het was niet mijn bedoeling om deze bibliotheek te schrijven. Het "gebeurde" als een neveneffect van een project dat ik begon dat een BMP280 gebruikt. Dat project is nog niet af, maar ik denk dat de bibliotheek klaar is om met anderen te delen. Vervolgens moest ik een BME280 gebruiken, die vochtigheidsmeting toevoegt aan de druk- en temperatuurcapaciteit van de BMP280. De BME280 is "achterwaarts compatibel" met de BMP280 - dat wil zeggen dat alle registers en de stappen die nodig zijn om de druk en temperatuur van de BME280 af te lezen, dezelfde zijn als die voor de BMP280. Er zijn extra registers en stappen nodig om de vochtigheid te lezen, alleen van toepassing op de BME280. Dit roept de vraag op, één bibliotheek voor beide, of twee afzonderlijke bibliotheken. De hardware voor de twee apparaattypen is volledig uitwisselbaar. Zelfs veel van de verkochte modules (bijvoorbeeld op Ebay en AliExpress) hebben het label BME/P280. Om erachter te komen welk type het is, moet je kijken naar de (minuscule) tekst op de sensor zelf, of de apparaat-ID-byte testen. Ik besloot voor een enkele bibliotheek te gaan. Het lijkt goed te zijn gelukt.

Feedback, met name suggesties voor verbeteringen, wordt op prijs gesteld.

Bibliotheekfuncties en -mogelijkheden

Een bibliotheek is een stuk software dat een programmeur een Application Programming Interface (API) biedt om de mogelijkheden van het apparaat uit te oefenen, zonder noodzakelijkerwijs met alle fijnmazige details te maken te hebben. Het is wenselijk dat de API gemakkelijk is voor een beginner met eenvoudige vereisten om aan de slag te gaan, terwijl de mogelijkheden van het apparaat volledig worden benut. Het is wenselijk dat de bibliotheek eventuele specifieke richtlijnen van de fabrikant van het apparaat volgt, evenals algemene goede praktijken op het gebied van software. Ik heb geprobeerd om dit allemaal te bereiken. Toen ik begon met de BMP280, vond ik er 3 verschillende bibliotheken voor: Adafruit_BMP280; Seeed_BMP280; en een genaamd BMP280 van de fabrikant van het apparaat. Noch Adafruit, noch Seeed boden uitgebreide mogelijkheden, hoewel ze goed werkten en gemakkelijk te gebruiken waren voor basistoepassingen. Ik kon er niet achter komen hoe ik die van de apparaatfabrikant (Bosch Sensortec) moest gebruiken. Dit kan mijn tekortkoming zijn, in plaats van die van hen. Hoewel de bibliotheek veel gecompliceerder was dan de andere twee, kon ik geen instructies of gebruiksvoorbeelden vinden (ik ontdekte later dat voorbeelden in het bestand "bmp280_support.c" stonden, maar deze waren niet bijzonder nuttig voor mij).

Als gevolg van deze factoren besloot ik mijn eigen bibliotheek voor de BMP280 te schrijven.

Toen ik de bibliotheeksituatie voor de BME280 onderzocht, vond ik afzonderlijke bibliotheken Adafruit_BME280, Seed_BME280 en nog een BME280_MOD-1022 geschreven door Embedded Adventures. Geen van hen combineerde de functies voor BMP280 in een bibliotheek die de BME280 kan gebruiken. Geen van hen ondersteunde expliciet de mogelijkheid van de apparaten om een paar stukjes gegevens op te slaan terwijl het apparaat en de controlerende microprocessor slapen (deze mogelijkheid is duidelijk in de datasheet en wordt ondersteund in de bibliotheek die ik hier heb geschreven en beschreven).

Een gecombineerde bibliotheek zou alle mogelijkheden van de BME280 moeten ondersteunen, maar bij gebruik met een BMP280 zou het geen overhead met zich mee moeten brengen van de ongebruikte functies. Voordelen van een gecombineerde bibliotheek zijn onder meer minder bibliotheekbestanden om te beheren, eenvoudig mixen en matchen van verschillende apparaten in hetzelfde project en vereenvoudigde wijzigingen voor onderhoud of upgrades die slechts op één plaats hoeven te worden uitgevoerd in plaats van op twee. Deze zijn waarschijnlijk allemaal vrij klein, zelfs onbeduidend, maar …

Apparaatmogelijkheden

De BMP280 en BME280 zijn apparaten voor opbouwmontage van ongeveer 5 mm in het vierkant en 1 mm hoog. Er zijn 8 interface-pads, waaronder 2 afzonderlijke voedingsingangspads en twee aardingspads. Ze zijn beschikbaar op eBay als een module met 4 of 6 pinnen. De 4-pins module heeft een vast I2C-adres en kan niet worden geconfigureerd om het SPI-protocol te gebruiken.

De 6-pins module of het kale apparaat kan worden gebruikt met I2C- of SPI-protocollen. In I2C-modus kan het twee verschillende adressen hebben, bereikt door de SDO-pin aan te sluiten op Ground (voor basisadres = 0x76) of op Vdd (voor basisadres +1 = 0x77). In SPI-modus heeft het de gebruikelijke opstelling van 1 klok, 2 gegevens (één voor elke richting) en een apparaatselectiepen (CS).

De bibliotheek die ik hier heb geschreven en beschreven, ondersteunt alleen I2C. De Adafruit_BMP280 en de BME_MOD-1022 bibliotheken hebben ondersteuning voor zowel i2C als SPI.

De bibliotheek is hier te downloaden:

github.com/farmerkeith/BMP280-library

Stap 1: De hardware instellen

De hardware instellen
De hardware instellen

Voordat de bibliotheek nuttig kan zijn, is het noodzakelijk om een microcontroller aan te sluiten op de BMP280 (of op twee als u dat wenst).

Ik heb een WeMos D1 mini pro gebruikt, dus ik zal de verbindingen laten zien. Andere microcontrollers zullen vergelijkbaar zijn, u hoeft alleen de SDA- en SCL-pinnen correct aan te sluiten.

In het geval van de WeMos D1 mini pro zijn de aansluitingen:

Functie WeMos-pin BMP280-pin Opmerkingen:

SDA D2 SDA SCL D1 SCL Vdd 3V3 Vin Nominaal 3,3V Aarde GND Adrescontrole SDO Aarde of Vdd I2C selecteer CSB Vdd (GND selecteert SPI)

Merk op dat de SDO-pin op sommige MP280-modules SDD is gelabeld en dat de Vdd-pin VCC kan zijn. Opmerking: SDA- en SCL-lijnen moeten pull-up-weerstanden hebben tussen de lijn en de Vin-pin. Normaal gesproken zou een waarde van 4,7K OK moeten zijn. Sommige BMP280- en BME280-modules hebben 10K pull-up-weerstanden in de module (wat geen goede gewoonte is, aangezien het plaatsen van meerdere apparaten op de I2C-bus deze overmatig kan belasten). Het gebruik van 2 BME/P280-modules met elk een 10K-weerstand zou in de praktijk echter geen probleem moeten zijn, zolang er niet te veel andere apparaten op dezelfde bus ook met pull-up-weerstanden zitten.

Zodra u de hardware hebt aangesloten, kunt u eenvoudig controleren of uw apparaat een BMP280 of een BME280 is door de schets I2CScan_ID uit te voeren die u hier kunt vinden:

Je kunt ook controleren of je een BMP280 of BME280 hebt door naar het apparaat zelf te kijken. Ik vond het nodig om hiervoor een digitale microscoop te gebruiken, maar als je gezichtsvermogen heel goed is, kun je het misschien zonder hulpmiddelen doen. Op de behuizing van het apparaat staan twee bedrukkingslijnen. De sleutel is de eerste letter op de tweede regel, die in het geval van BMP280-apparaten een "K" is en in het geval van BME280-apparaten een "U".

Stap 2: API's geleverd door de bibliotheek

API's geleverd door de bibliotheek
API's geleverd door de bibliotheek
API's geleverd door de bibliotheek
API's geleverd door de bibliotheek

De bibliotheek opnemen in een schets

De bibliotheek wordt standaard opgenomen in een schets met behulp van de instructie

#include "farmerkeith_BMP280.h"

Deze verklaring moet worden opgenomen in het eerste deel van de schets voordat de functie setup() wordt gestart.

Een BME- of BMP-softwareobject maken

Er zijn 3 niveaus voor het maken van het BMP280-softwareobject. De eenvoudigste is gewoon

bme280 objectnaam; of bmp280 objectnaam;

bijvoorbeeld BMP280 bmp0;

Hiermee wordt een softwareobject gemaakt met het standaardadres 0x76 (dwz voor SDO aangesloten op aarde).

Het volgende niveau voor het maken van een BME280- of BMP280-softwareobject heeft een parameter van 0 of 1, als volgt:

bme280 objectNaamA(0);

bmp280 objectNaamB(1);

De parameter (0 of 1) wordt toegevoegd aan het I2C-basisadres, zodat twee BME280- of BMP280-apparaten op dezelfde I2C-bus kunnen worden gebruikt (inclusief één van elk).

Het derde niveau voor het maken van een BME- of BMP280-softwareobject heeft twee parameters. De eerste parameter, die 0 of 1 is, is voor het adres, net als in het vorige geval. De tweede parameter regelt het afdrukken van foutopsporing. Als deze is ingesteld op 1, resulteert elke transactie met het softwareobject in Serial.print-uitvoer waarmee de programmeur de details van de transactie kan zien. Bijvoorbeeld:

bmp280 objectNameB(1, 1);

Als de debug-afdrukparameter is ingesteld op 0, keert het softwareobject terug naar normaal gedrag (niet afdrukken).

Deze instructie of instructies moeten worden opgenomen na de #include en vóór de setup() functie.

Initialiseren van het BME- of BMP-softwareobject

Alvorens te worden gebruikt, is het noodzakelijk om de kalibratieparameters van het apparaat te lezen en het te configureren voor elke meetmodus, oversampling en filterinstellingen die geschikt zijn.

Voor een eenvoudige initialisatie voor algemene doeleinden is de instructie:

objectNaam.begin();

Deze versie van begin() leest de kalibratieparameters van het apparaat en stelt osrs_t=7 (16 temperatuurmetingen), osrs_p=7 (16 drukmetingen), mode=3 (continu, normaal), t_sb=0 (0,5 ms slaap tussen meetsets), filter=0 (K=1, dus geen filtering) en spiw_en=0 (SPI uitgeschakeld, dus gebruik I2C). In het geval van de BME280 is er een extra parameter osrs_h=7 voor 16 vochtigheidsmetingen.

Er is een andere versie van begin() die alle zes (of 7) parameters nodig heeft. Het equivalent van de bovenstaande verklaring is:

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

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

De volledige lijst met codes en hun betekenis staat in de BME280 en BMP280 datasheet, en ook in de opmerkingen in het.cpp-bestand in de bibliotheek.

Eenvoudige temperatuur- en drukmeting

Om een temperatuurmeting te krijgen, is de eenvoudigste manier:

dubbele temperatuur=objectName.readTemperature (); // meet temperatuur

Om een drukmeting te krijgen is de eenvoudigste manier:

dubbele druk=objectName.readPressure (); // druk meten

Om een vochtigheidsmeting te krijgen, is de eenvoudigste manier:

dubbele vochtigheid = objectName.readHumidity (); // vochtigheid meten (alleen BME280)

Om zowel temperatuur als druk te krijgen, kunnen de bovenstaande twee uitspraken na elkaar worden gebruikt, maar er is nog een andere optie, namelijk:

dubbele temperatuur;

dubbele druk = objectName.readPressure (temperatuur); // meet druk en temperatuur

Deze instructie leest de gegevens van het BME280- of BMP280-apparaat slechts één keer en retourneert zowel temperatuur als druk. Dit is iets efficiënter gebruik van de I2C-bus en zorgt ervoor dat de twee uitlezingen overeenkomen met dezelfde meetcyclus.

Voor de BME 280 is een gecombineerde verklaring die alle drie de waarden (vochtigheid, temperatuur en druk) krijgt:

dubbele temperatuur, druk; dubbele vochtigheid = objectName.readHumidity (temperatuur, druk); // meet vochtigheid, druk en temperatuur

Deze instructie leest de gegevens van het BMP280-apparaat slechts één keer en retourneert alle drie de waarden. Dit is iets efficiënter gebruik van de I2C-bus en zorgt ervoor dat de drie uitlezingen overeenkomen met dezelfde meetcyclus. Merk op dat de namen van de variabelen kunnen worden veranderd in alles wat de gebruiker wil, maar hun volgorde is vast - temperatuur komt eerst en druk komt op de tweede plaats.

Deze gebruiksscenario's worden behandeld in voorbeeldschetsen die bij de bibliotheek worden geleverd, namelijk basicTemperature.ino, basicPressure.ino, basicHumidity.ino, basicTemperatureAndPressure.ino en basicHumidityAndTemperatureAndPressure.ino.

Meer geavanceerde temperatuur- en drukmeting

Hoewel de bovenstaande reeks uitspraken zonder problemen zal werken, zijn er een aantal problemen:

  1. het apparaat is continu in bedrijf en verbruikt daarom maximaal stroom. Als de energie afkomstig is van een batterij, kan het nodig zijn deze te verminderen.
  2. vanwege het verbruikte vermogen zal het apparaat opwarmen en daarom zal de gemeten temperatuur hoger zijn dan de omgevingstemperatuur. Ik zal dit meer in een latere stap behandelen.

Een resultaat dat minder stroom verbruikt en een temperatuur geeft die dichter bij de omgevingstemperatuur ligt, kan worden verkregen door begin() te gebruiken met parameters die het in de slaapstand zetten (bijv. mode=0). Bijvoorbeeld:

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

Wanneer een meting gewenst is, activeert u het apparaat met een configuratiecommando voor de registers F2 (indien nodig) en F4 die de juiste waarden van osrs_h, osrs_t en osrs_p, plus mode=1 (single shot-modus) instelt. Bijvoorbeeld:

[objectName.updateF2Control(1);] // osrs_h - nooit nodig voor BMP280, // en niet nodig voor BME280 als het aantal metingen niet wordt gewijzigd // van de waarde die is opgegeven in begin(). objectName.updateF4Control(1, 1, 1); // osrs_t, osrs_p, modus

Nadat het apparaat is gewekt, begint het te meten, maar het resultaat zal enkele milliseconden niet beschikbaar zijn - minstens 4 ms, misschien tot 70 ms of meer, afhankelijk van het aantal metingen dat is opgegeven. Als het leescommando onmiddellijk wordt verzonden, retourneert het apparaat de waarden van de vorige meting - wat in sommige toepassingen acceptabel kan zijn, maar in de meeste gevallen is het waarschijnlijk beter om te wachten totdat de nieuwe meting beschikbaar is.

Deze vertraging kan op verschillende manieren worden gedaan.

  1. wacht een vaste hoeveelheid tijd om de langste verwachte vertraging te dekken
  2. wacht een hoeveelheid tijd berekend op basis van de maximale meettijd per meting (dwz 2,3 ms) maal het aantal metingen, plus overhead, plus een marge.
  3. wacht een kortere tijd berekend zoals hierboven, maar gebruik de nominale meettijd (dwz 2 ms) plus overhead, en begin dan met het controleren van het "Ik ben aan het meten"-bit in het statusregister. Wanneer de statusbit 0 aangeeft (dwz niet meet), ontvang dan de temperatuur- en drukmetingen.
  4. begin onmiddellijk met het controleren van het statusregister en ontvang de temperatuur- en drukmetingen wanneer het statusbit 0 aangeeft,

Ik zal later een voorbeeld laten zien van een manier om dit te doen.

Configuratie register bewerkingen

Om dit allemaal mogelijk te maken, hebben we verschillende tools nodig die ik nog niet heb geïntroduceerd. Zij zijn:

byte lezenRegister(reg)

void updateRegister(reg, waarde)

Elk van deze heeft verschillende afgeleide commando's in de bibliotheek, die de software voor specifieke acties een beetje eenvoudiger maken.

Het voorbeeld powerSaverPressureAndTemperature.ino gebruikt methode nr. 3. De regel code die de herhaalde controle uitvoert, is

while (bmp0.readRegister(0xF3)>>3); // lus tot F3bit 3 ==0

Merk op dat deze schets voor een ESP8266-microcontroller is. Ik gebruikte een WeMos D1 mini pro. De schets werkt niet met Atmega-microcontrollers, die verschillende slaapinstructies hebben. Deze schets oefent verschillende andere commando's uit, dus ik zal ze allemaal introduceren voordat ik die schets in meer detail beschrijf.

Wanneer de microcontroller parallel slaapt met de BMP280-sensor, kan de configuratie van de sensor voor de vereiste metingen worden gedaan in het begin()-commando, met behulp van de 6 parameters. Als de microcontroller echter niet slaapt, maar de sensor wel, dan moet de sensor op het moment van de meting gewekt worden en zijn meetconfiguratie doorgeven. Dit kan direct met

updateRegister(reg, waarde)

maar is een beetje makkelijker met de volgende drie commando's:

updateF2Control(osrs_h); // Alleen BME280

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

Nadat de meting is uitgevoerd en de gebruikte modus Single shot (geforceerde modus) is, zal het apparaat automatisch weer in slaapstand gaan. Als de meetset echter meerdere metingen omvat in de continue (Normale) modus, moet de BMP280 weer in de slaapstand worden gezet. Dit kan met een van de volgende twee commando's:

updateF4Control16xSleep();

updateF4ControlSleep(waarde);

Beide stellen de modusbits in op 00 (dwz slaapmodus). De eerste stelt echter de osrs_t en osrs_p in op 111 (dwz 16 metingen), terwijl de tweede de lage 6 bits van "waarde" opslaat in bits 7:2 van het 0xF4-register.

Evenzo slaat de volgende instructie de lage zes bits van "waarde" op in bits 7:2 van het 0xF5-register.

updateF5ConfigSleep(waarde);

Het gebruik van deze laatste commando's maakt opslag van 12 bits informatie in de BMP280 registers F4 en F5 mogelijk. Tenminste in het geval van de ESP8266, wanneer de microcontroller wakker wordt na een slaapperiode, begint deze aan het begin van de schets zonder kennis van de staat voorafgaand aan het slaapcommando. Om kennis van de status op te slaan voorafgaand aan het slaapcommando, kunnen gegevens worden opgeslagen in flash-geheugen, met behulp van de EEPROM-functies of door een bestand te schrijven met SPIFFS. Flash-geheugen heeft echter een beperking van het aantal schrijfcycli, in de orde van 10.000 tot 100.000. Dit betekent dat als de microcontroller om de paar seconden een slaap-waakcyclus doorloopt, deze de toegestane geheugenschrijfcyclus kan overschrijden binnen enkele maanden beperken. Het opslaan van een paar databits in de BMP280 kent zo'n beperking niet.

De gegevens die zijn opgeslagen in registers F4 en F5 kunnen worden hersteld wanneer de microcontroller ontwaakt met behulp van de opdrachten

leesF4Slaap();

leesF5Slaap();

Deze functies lezen het corresponderende register, verschuiven de inhoud om de 2 LSB's te verwijderen en retourneren de resterende 6 bits. Deze functies worden als volgt gebruikt in de voorbeeldschets powerSaverPressureAndTemperatureESP.ino:

// lees de waarde van EventCounter terug van bmp0

byte bmp0F4value= bmp0.readF4Sleep(); // 0 tot 63 byte bmp0F5value= bmp0.readF5Sleep(); // 0 tot 63 eventCounter= bmp0F5value*64+bmp0F4value; // 0 tot 4095

Deze functies lezen het corresponderende register, verschuiven de inhoud om de 2 LSB's te verwijderen en retourneren de resterende 6 bits. Deze functies worden als volgt gebruikt in de voorbeeldschets powerSaverPressureAndTemperature.ino:

// lees de waarde van EventCounter terug van bmp1

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

Ruwe temperatuur- en drukfuncties

De basisfuncties readTemperature, readPressure en readhumidity hebben twee componenten. Eerst worden de ruwe 20-bits temperatuur- en drukwaarden verkregen van de BME/P280, of de ruwe 16-bits vochtigheidswaarde wordt verkregen van de BME280. Vervolgens wordt het compensatiealgoritme gebruikt om de uitgangswaarden in graden Celsius, hPa of %RV te genereren.

De bibliotheek biedt afzonderlijke functies voor deze componenten, zodat de ruwe temperatuur-, druk- en vochtigheidsgegevens kunnen worden verkregen en misschien op de een of andere manier kunnen worden gemanipuleerd. Het algoritme om de temperatuur, druk en vochtigheid uit deze ruwe waarden af te leiden, wordt ook gegeven. In de bibliotheek worden deze algoritmen geïmplementeerd met behulp van drijvende-kommaberekeningen met dubbele lengte. Het werkt goed op de ESP8266, een 32-bits processor en gebruikt 64 bits voor "dubbele" float-variabelen. Het toegankelijk maken van deze functies kan handig zijn voor het beoordelen en eventueel wijzigen van de berekening voor andere platformen.

Deze functies zijn:

readRawPressure (ruwe temperatuur); // leest onbewerkte druk- en temperatuurgegevens van BME/P280readRawHumidity (rawTemperature, rawPressure); // leest ruwe vochtigheids-, temperatuur- en drukgegevens van BME280 calcTemperature (rawTemperature, t_fine); calcPressure (rawPressure, t_fine); calcHumidity (ruwe vochtigheid, t_fine)

Het argument "t-fine" voor deze functies is een beetje uitleg waard. Zowel algoritmen voor druk- als vochtigheidscompensatie bevatten een temperatuurafhankelijke component die wordt bereikt door de variabele t_fine. De functie calcTemperature schrijft een waarde in t_fine op basis van de logica van het temperatuurcompensatiealgoritme, die vervolgens wordt gebruikt als invoer in zowel calcPressure als calcHumidity.

Een voorbeeld van het gebruik van deze functies is te vinden in de voorbeeldschets rawPressureAndTemperature.ino, en ook in de code voor de functie readHumidity() in het.cpp-bestand van de bibliotheek.

Hoogte- en zeespiegeldruk

Er is een bekend verband tussen atmosferische druk en hoogte. Het weer heeft ook invloed op de druk. Wanneer de weerorganisaties informatie over de atmosferische druk publiceren, passen ze deze meestal aan voor de hoogte en dus toont de "synoptische kaart" isobaren (lijnen van constante druk) die gestandaardiseerd zijn om het zeeniveau te betekenen. Er zijn dus echt 3 waarden in deze relatie, en als je er twee kent, kun je de derde afleiden. De 3 waarden zijn:

  • hoogte boven zeeniveau
  • werkelijke luchtdruk op die hoogte
  • equivalente luchtdruk op zeeniveau (meer strikt, gemiddeld zeeniveau, omdat het momentane zeeniveau voortdurend verandert)

Deze bibliotheek biedt twee functies voor deze relatie, namelijk:

calcAltitude (druk, zeeniveauhPa);

calcGenormaliseerdeDruk (druk, hoogte);

Er is ook een vereenvoudigde versie, die uitgaat van de standaarddruk op zeeniveau van 1013,15 hPa.

calcHoogte (druk); // standaard zeeniveau aangenomen druk

Stap 3: BMP280-apparaatgegevens

BMP280-apparaatgegevens
BMP280-apparaatgegevens

Hardwaremogelijkheden

De BMP280 heeft 2 bytes aan configuratiegegevens (op registeradressen 0xF4 en 0xF5) die worden gebruikt om meerdere meet- en gegevensuitvoeropties te regelen. Het biedt ook 2 bits statusinformatie en 24 bytes aan kalibratieparameters die worden gebruikt bij het converteren van de ruwe temperatuur- en drukwaarden naar conventionele temperatuur- en drukeenheden. De BME280 heeft de volgende aanvullende gegevens:

  • 1 extra byte aan configuratiegegevens op registeradres 0xF2 gebruikt om meerdere vochtigheidsmetingen te regelen;
  • 8 extra bytes aan kalibratieparameters die worden gebruikt bij het converteren van de ruwe vochtigheidswaarde naar het relatieve vochtigheidspercentage.

De temperatuur-, druk- en statusregisters voor de BME280 zijn hetzelfde als voor de BMP280 met kleine uitzonderingen als volgt:

  • de "ID"-bits van de BME280 zijn ingesteld op 0x60, zodat het kan worden onderscheiden van BMP280, wat 0x56, 0x57 of 0x58 kan zijn
  • de slaaptijdregeling (t_sb) is gewijzigd zodat de twee lange tijden in de BMP280 (2000 ms en 4000 ms) in de BME280 worden vervangen door korte tijden van 10 ms en 20 ms. De maximale slaaptijd in de BME280 is 1000 ms.
  • In de BME280 zijn de ruwe temperatuur- en drukwaarden altijd 20 bits als er gefilterd wordt. Het gebruik van 16 tot 19 bit-waarden is beperkt tot gevallen zonder filtering (dwz filter=0).

Temperatuur en druk zijn elk 20-bits waarden, die moeten worden omgezet in conventionele temperatuur en druk via een nogal complex algoritme met 3 16-bits kalibratieparameters voor temperatuur en 9 16-bits kalibratieparameters plus de temperatuur voor druk. De granulatie van de temperatuurmeting is 0,0003 graden Celsius voor een minst significante bitverandering (20 bit uitlezing), oplopend tot 0,0046 graden Celsius als de 16 bit uitlezing wordt gebruikt.

Vochtigheid is een 16-bits waarde die moet worden omgezet in relatieve vochtigheid via een ander complex algoritme met behulp van 6 kalibratieparameters die een mix zijn van 8, 12 en 16 bits.

Het datablad toont de absolute nauwkeurigheid van de temperatuuruitlezing als +-0,5 C bij 25 C en +-1 C over het bereik 0 tot 65 C.

De granulariteit van de drukmeting is 0,15 Pascal (dwz 0,0015 hectoPascal) bij een resolutie van 20 bits, of 2,5 Pascal bij een resolutie van 16 bits. De waarde van de ruwe druk wordt beïnvloed door de temperatuur, zodat rond de 25C een temperatuurstijging van 1 graad C de gemeten druk met 24 Pascal verlaagt. Met de temperatuurgevoeligheid wordt rekening gehouden in het kalibratiealgoritme, dus de geleverde drukwaarden moeten nauwkeurig zijn bij verschillende temperaturen.

Het datablad toont de absolute nauwkeurigheid van de drukuitlezing als +-1 hPa voor temperaturen tussen 0 C en 65 C.

De nauwkeurigheid van de luchtvochtigheid wordt in het datablad aangegeven als +-3% RV, en +-1% hysterese.

Hoe het werkt

De 24 bytes aan temperatuur- en drukkalibratiegegevens, en ook in het geval van de BME280 de 8 bytes aan vochtigheidskalibratiegegevens, moeten uit het apparaat worden gelezen en in variabelen worden opgeslagen. Deze gegevens zijn in de fabriek individueel in het apparaat geprogrammeerd, dus verschillende apparaten hebben verschillende waarden - althans voor sommige parameters. Een BME/P280 kan zich in een van twee toestanden bevinden. In één staat is het meten. In de andere staat is het wachten (slapen).

In welke staat het zich bevindt, kan worden gecontroleerd door te kijken naar bit 3 van register 0xF3.

De resultaten van de meest recente meting kunnen op elk moment worden verkregen door de bijbehorende gegevenswaarde uit te lezen, ongeacht of het apparaat slaapt of meet.

Er zijn ook twee manieren om de BME/P280 te bedienen. Een daarvan is de continue modus (in het gegevensblad de normale modus genoemd) die herhaaldelijk wisselt tussen de meet- en slaapstanden. In deze modus voert het apparaat een reeks metingen uit, gaat dan slapen, wordt dan wakker voor een andere reeks metingen, enzovoort. Het aantal individuele metingen en de duur van het slaapgedeelte van de cyclus kunnen allemaal worden gecontroleerd via de configuratieregisters.

De andere manier om de BME/P280 te bedienen is de Single Shot-modus (geforceerde modus genoemd in het gegevensblad). In deze modus wordt het apparaat uit de slaapstand gehaald door een opdracht om te meten, voert het een reeks metingen uit en gaat vervolgens weer in slaapstand. Het aantal individuele metingen in de set wordt geregeld in het configuratiecommando dat het apparaat wekt.

Als in de BMP280 een enkele meting wordt uitgevoerd, worden de 16 meest significante bits in de waarde ingevuld en zijn de vier minst significante bits in de waarde-uitlezing allemaal nullen. Het aantal metingen kan worden ingesteld op 1, 2, 4, 8 of 16 en naarmate het aantal metingen toeneemt, neemt het aantal bits gevuld met gegevens toe, zodat bij 16 metingen alle 20 bits worden gevuld met meetgegevens. Het datablad verwijst naar dit proces als oversampling.

In de BME280 geldt dezelfde regeling zolang het resultaat niet wordt gefilterd. Als filtering wordt gebruikt, zijn de waarden altijd 20 bits, ongeacht hoeveel metingen er in elke meetcyclus worden uitgevoerd.

Elke afzonderlijke meting duurt ongeveer 2 milliseconden (typische waarde; maximale waarde is 2,3 ms). Tel daarbij op dat een vaste overhead van ongeveer 2 ms (meestal iets minder) betekent dat een meetreeks, die kan bestaan uit 1 tot 32 afzonderlijke metingen, van 4 ms tot 66 ms kan duren.

Het gegevensblad biedt een reeks aanbevolen combinaties van temperatuur- en drukoverbemonstering voor verschillende toepassingen.

Configuratie controle registers

De twee configuratiecontroleregisters in de BMP280 bevinden zich op registeradressen 0xF4 en 0xF5 en zijn toegewezen aan 6 individuele configuratiecontrolewaarden. 0xF4 bestaat uit:

  • 3 bits osrs_t (meet temperatuur 0, 1, 2, 4, 8 of 16 keer);
  • 3 bits osrs_p (meet druk 0, 1, 2, 4, 8 of 16 keer); en
  • 2-bits modus (slaapstand, geforceerd (dwz enkele opname), normaal (dwz continu).

0xF5 bestaat uit:

  • 3 bits t_sb (standby-tijd, 0,5 ms tot 4000 ms);
  • 3 bits filter (zie hieronder); en
  • 1 bit spiw_en die SPI of I2C selecteert.

De filterparameter regelt een soort exponentieel vervalalgoritme, of Infinite Impulse Response (IIR)-filter, toegepast op de ruwe druk- en temperatuurmeetwaarden (maar niet op de vochtigheidswaarden). De vergelijking wordt gegeven in het gegevensblad. Een andere presentatie is:

Waarde(n) = Waarde(n-1) * (K-1)/K + meting(n) / K

waarbij (n) de meest recente meet- en uitvoerwaarde aangeeft; en K is de filterparameter. De filterparameter K en kan worden ingesteld op 1, 2, 4, 8 of 16. Als K is ingesteld op 1 wordt de vergelijking gewoon Waarde(n) = meting(n). De codering van de filterparameter is:

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

De BME 280 voegt nog een configuratiecontroleregister toe op adres 0xF2, "ctrl_hum" met een enkele 3-bit parameter osrs_h (meet de vochtigheid 0, 1, 2, 4, 8 of 16 keer).

Stap 4: Meet- en uitleestiming

Ik ben van plan dit later toe te voegen, met de timing van opdrachten en meetreacties.

Iddt - stroom bij temperatuurmeting. Typische waarde 325 uA

Iddp - stroom bij drukmeting. Typische waarde 720 uA, max 1120 uA

Iddsb - stroom in standby-modus. Typische waarde 0,2 uA, max 0,5 uA

Iddsl - stroom in slaapstand. Typische waarde 0,1 uA, max 0,3 uA

Stap 5: Softwarerichtlijnen

Softwarerichtlijnen
Softwarerichtlijnen
Softwarerichtlijnen
Softwarerichtlijnen

I2C Burst-modus

Het BMP280-gegevensblad biedt richtlijnen voor het uitlezen van gegevens (paragraaf 3.9). Er staat "het wordt sterk aanbevolen om een burst read te gebruiken en niet elk register afzonderlijk te adresseren. Dit voorkomt een mogelijke verwisseling van bytes die bij verschillende metingen horen en vermindert het interfaceverkeer." Er worden geen richtlijnen gegeven met betrekking tot het uitlezen van de compensatie-/kalibratieparameters. Vermoedelijk zijn deze geen probleem omdat ze statisch zijn en niet veranderen.

Deze bibliotheek leest alle aangrenzende waarden in een enkele leesbewerking - 24 bytes in het geval van de temperatuur- en drukcompensatieparameters, 6 bytes voor temperatuur en druk gecombineerd en 8 bytes voor vochtigheid, temperatuur en druk gecombineerd. Wanneer alleen de temperatuur wordt gecontroleerd, worden slechts 3 bytes gelezen.

Gebruik van macro's (#define etc.)

Er zijn geen andere macro's in deze bibliotheek dan de gebruikelijke bibliotheek "inclusief guard"-macro die duplicatie voorkomt.

Alle constanten worden gedefinieerd met behulp van het const-sleutelwoord en het afdrukken van foutopsporing wordt bestuurd met standaard C-functies.

Het is voor mij de bron van enige onzekerheid geweest, maar het advies dat ik krijg door het lezen van veel berichten over dit onderwerp is dat het gebruik van #define voor het declareren van constanten (tenminste) en (waarschijnlijk) debug-afdrukcontrole onnodig en ongewenst is.

Het argument voor het gebruik van const in plaats van #define is vrij duidelijk - const gebruikt dezelfde bronnen als #define (dwz nul) en de resulterende waarden volgen de scopingregels, waardoor de kans op fouten wordt verkleind.

Het argument voor debug-afdrukcontrole is iets minder duidelijk, omdat de manier waarop ik het heb gedaan betekent dat de uiteindelijke code de logica bevat voor de debug-afdrukinstructies, ook al worden ze nooit uitgeoefend. Als de bibliotheek moet worden gebruikt in een groot project op een microcontroller met een zeer beperkt geheugen, kan dit een probleem worden. Aangezien mijn ontwikkeling op een ESP8266 met een groot flashgeheugen was, leek dit voor mij geen probleem.

Stap 6: Temperatuurprestaties

Ik ben van plan dit later toe te voegen.

Stap 7: Drukprestaties

Ik ben van plan dit later toe te voegen.

Aanbevolen: