Innehållsförteckning:

Bibliotek för BMP280 och BME280: 7 steg
Bibliotek för BMP280 och BME280: 7 steg

Video: Bibliotek för BMP280 och BME280: 7 steg

Video: Bibliotek för BMP280 och BME280: 7 steg
Video: Lesson 96: Barometric Pressure, Temperature, Approximate Altitude Sensor BMP390 with LCD 2024, Juli
Anonim
Bibliotek för BMP280 och BME280
Bibliotek för BMP280 och BME280
Bibliotek för BMP280 och BME280
Bibliotek för BMP280 och BME280
Bibliotek för BMP280 och BME280
Bibliotek för BMP280 och BME280

Introduktion

Jag tänkte inte skriva detta bibliotek. Det "hände" som en bieffekt av ett projekt jag startade som använder en BMP280. Det projektet är ännu inte klart, men jag tror att biblioteket är redo att dela med andra. Därefter hade jag ett behov av att använda en BME280, som lägger till fuktmätning till trycket och temperaturförmågan hos BMP280. BME280 är "bakåtkompatibel" med BMP280 - det vill säga att alla register och de steg som krävs för att läsa av tryck och temperatur från BME280 är desamma som de som används för BMP280. Det finns ytterligare register och steg som krävs för att avläsa luftfuktighet, endast gällande BME280. Detta väcker frågan, ett bibliotek för båda eller två separata bibliotek. Hårdvaran för de två enhetstyperna är fullt utbytbar. Även många av de moduler som säljs (till exempel på Ebay och AliExpress) är märkta BME/P280. För att ta reda på vilken typ det är måste du titta på (miniscule) skrivningen på själva sensorn eller testa enhetens ID -byte. Jag bestämde mig för att gå till ett enda bibliotek. Det verkar ha gått bra.

Feedback, särskilt förslag på förbättringar, uppskattas.

Bibliotekets funktioner och funktioner

Ett bibliotek är en mjukvara som tillhandahåller ett Application Programming Interface (API) för en programmerare att utöva enhetens funktioner, utan att nödvändigtvis behöva hantera alla finkorniga detaljer. Önskvärt bör API: et vara lätt för en nybörjare med enkla krav att komma igång, samtidigt som det ger full användning av enhetens funktioner. Helst bör biblioteket följa alla specifika riktlinjer från enhetstillverkaren, samt allmän praxis för allmän programvara. Jag har strävat efter att uppnå allt detta. När jag började med BMP280 hittade jag tre olika bibliotek för det: Adafruit_BMP280; Seeed_BMP280; och en som heter BMP280 från enhetstillverkaren. Varken Adafruit eller Seeed gav utökade funktioner, även om de fungerade bra och var enkla att använda för grundläggande applikationer. Jag kunde inte räkna ut hur vi använder den som tillverkas av enhetstillverkaren (Bosch Sensortec). Detta kan vara min brist, snarare än deras. Men biblioteket var mycket mer komplicerat än de andra två, jag kunde inte hitta några instruktioner eller exempel på användning (jag fann senare att exemplen fanns i filen "bmp280_support.c", men dessa var inte särskilt hjälpsamma för mig).

Som ett resultat av dessa faktorer bestämde jag mig för att skriva ett eget bibliotek för BMP280.

När jag tittade på bibliotekssituationen för BME280 hittade jag separata bibliotek Adafruit_BME280, Seed_BME280 och en annan BME280_MOD-1022 skriven av Embedded Adventures. Ingen av dem kombinerade funktionerna för BMP280 i ett bibliotek som kan använda BME280. Ingen av dem stödde uttryckligen enheternas förmåga att lagra några bitar av data medan enheten och dess styrande mikroprocessor sover (den här funktionen framgår av databladet och stöds i biblioteket som jag har skrivit och beskrivit här).

Ett kombinerat bibliotek bör ha stöd för alla funktioner i BME280, men när det används med ett BMP280 bör det inte påföra några omkostnader från de oanvända funktionerna. Fördelarna med ett kombinerat bibliotek inkluderar färre biblioteksfiler att hantera, enkel blandning och matchning av olika enheter i samma projekt och förenklade ändringar för underhåll eller uppgraderingar som bara måste göras på ett ställe snarare än två. Dessa är nog alla ganska små, till och med obetydliga, men …

Enhetsfunktioner

BMP280 och BME280 är ytmonterade enheter cirka 5 mm fyrkantiga och 1 mm höga. Det finns 8 gränssnittskuddar, inklusive 2 separata kraftingångskuddar och två markdynor. De är tillgängliga på eBay som en modul med antingen 4 eller 6 stift tagna ut. Den 4-poliga modulen har en fast I2C-adress och kan inte konfigureras för att använda SPI-protokollet.

Den 6-poliga modulen eller den bara enheten kan användas med antingen I2C- eller SPI-protokoll. I I2C -läge kan den ha två olika adresser, som uppnås genom att ansluta SDO -stiftet antingen till Ground (för basadress = 0x76) eller till Vdd (för basadress +1 = 0x77). I SPI -läge har den det vanliga arrangemanget med 1 klocka, 2 data (en för varje riktning) och en enhet för val av enhet (CS).

Biblioteket jag skrev och beskriver här stöder bara I2C. Adafruit_BMP280- och BME_MOD-1022-biblioteken har stöd för både i2C och SPI.

Biblioteket kan laddas ner här:

github.com/farmerkeith/BMP280-library

Steg 1: Konfigurera maskinvaran

Konfigurera hårdvaran
Konfigurera hårdvaran

Innan biblioteket kan vara användbart är det nödvändigt att ansluta en mikrokontroller till BMP280 (eller till två av dem om du vill).

Jag använde ett WeMos D1 mini pro, så jag kommer att visa dess anslutningar. Andra mikrokontroller kommer att vara liknande, du behöver bara ansluta SDA- och SCL -stiften korrekt.

För WeMos D1 mini pro är anslutningarna:

Funktion WeMos pin BMP280 pin Notes

SDA D2 SDA SCL D1 SCL Vdd 3V3 Vin Nominal 3.3V Ground GND Adresskontroll SDO Ground eller Vdd I2C välj CSB Vdd (GND väljer SPI)

Observera att SDO -stiftet på några av MP280 -modulerna är märkt SDD, och Vdd -stiftet kan vara märkt VCC. Obs! SDA- och SCL-ledningar ska ha uppdragningsmotstånd mellan linjen och Vin-stiftet. Normalt bör värdet 4,7K vara OK. Vissa BMP280- och BME280-moduler har 10K uppdragningsmotstånd som ingår i modulen (vilket inte är bra, eftersom att sätta flera enheter på I2C-bussen kan ladda den för mycket). Att använda 2 BME/P280-moduler var och en med ett 10K-motstånd bör dock inte vara ett problem i praktiken så länge det inte finns för många andra enheter på samma buss också med uppdragningsmotstånd.

När du har anslutit hårdvaran kan du enkelt kontrollera om din enhet är en BMP280 eller en BME280 genom att köra skissen I2CScan_ID som du hittar här:

Du kan också kontrollera om du har en BMP280 eller BME280 genom att titta på själva enheten. Jag fann det nödvändigt att använda ett digitalt mikroskop för att göra detta, men om din syn är mycket bra kan du kanske göra det utan hjälpmedel. Det finns två rader med tryck på enhetens hölje. Nyckeln är den första bokstaven på den andra raden, som för BMP280 -enheter är ett "K" och för BME280 -enheter är ett "U".

Steg 2: API: er som tillhandahålls av biblioteket

API: er som tillhandahålls av biblioteket
API: er som tillhandahålls av biblioteket
API: er som tillhandahålls av biblioteket
API: er som tillhandahålls av biblioteket

Inkluderar biblioteket i en skiss

Biblioteket ingår i en skiss på standard sättet med hjälp av uttalandet

#inkludera "farmerkeith_BMP280.h"

Detta uttalande måste inkluderas i den tidiga delen av skissen innan installationen () startas.

Skapa ett BME- eller BMP -programvaruobjekt

Det finns tre nivåer för att skapa BMP280 -programvaruobjektet. Det enklaste är bara

bme280 objektnamn; eller bmp280 objektnamn;

till exempel BMP280 bmp0;

Detta skapar ett programvaruobjekt med standardadressen 0x76 (dvs för SDO ansluten till jord).

Nästa nivå för att skapa ett BME280- eller BMP280 -programvaruobjekt har en parameter antingen 0 eller 1, enligt följande:

bme280 objektnamnA (0);

bmp280 objektnamnB (1);

Parametern (0 eller 1) läggs till I2C -basadressen, så att två BME280- eller BMP280 -enheter kan användas på samma I2C -buss (inklusive en av varje).

Den tredje nivån för att skapa ett BME- eller BMP280 -programvaruobjekt har två parametrar. Den första parametern, som antingen är 0 eller 1, är för adressen, liksom för föregående fall. Den andra parametern styr felsökningsutskrift. Om den är inställd på 1 resulterar varje transaktion med programvaruobjektet i Serial.print -utdata som gör det möjligt för programmeraren att se detaljerna i transaktionen. Till exempel:

bmp280 objectNameB (1, 1);

Om felsökningsparametern är inställd på 0 återgår programvaruobjektet till normalt beteende (ingen utskrift).

Detta eller dessa påståenden måste inkluderas efter #inkludera och före funktionen setup ().

Initierar BME- eller BMP -programvaruobjektet

Innan den används är det nödvändigt att läsa av kalibreringsparametrarna från enheten och konfigurera den för vilket mätläge, översampling och filterinställningar som är lämpliga.

För en enkel initialisering för allmänna ändamål är uttalandet:

objectName.begin ();

Denna version av begin () läser kalibreringsparametrarna från enheten och ställer in osrs_t = 7 (16 temperaturmätningar), osrs_p = 7 (16 tryckmätningar), mode = 3 (kontinuerlig, normal), t_sb = 0 (0,5 ms sömn mellan mätuppsättningar), filter = 0 (K = 1, så ingen filtrering) och spiw_en = 0 (SPI inaktiverat, så använd I2C). När det gäller BME280 finns det en extra parameter osrs_h = 7 för 16 luftfuktighetsmätningar.

Det finns en annan version av begin () som tar alla sex (eller 7) parametrar. Motsvarigheten till ovanstående uttalande är

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

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

Den fullständiga listan över koder och deras betydelser finns i BME280- och BMP280 -databladet, och även i kommentarerna i.cpp -filen i biblioteket.

Enkel temperatur- och tryckmätning

För att få en temperaturmätning är det enklaste sättet

dubbel temperatur = objectName.readTemperature (); // mäta temperatur

För att få en tryckmätning är det enklaste sättet

dubbel tryck = objectName.readPressure (); // mäta tryck

För att få en fuktmätning är det enklaste sättet

dubbel luftfuktighet = objectName.readHumidity (); // mäta luftfuktighet (endast BME280)

För att få både temperatur och tryck kan ovanstående två satser användas efter varandra, men det finns ett annat alternativ, vilket är:

dubbel temperatur;

dubbel tryck = objectName.readPressure (temperatur); // mäta tryck och temperatur

Detta uttalande läser data från BME280- eller BMP280 -enheten bara en gång och returnerar både temperatur och tryck. Detta är något mer effektiv användning av I2C -bussen och säkerställer att de två avläsningarna motsvarar samma mätcykel.

För BME 280 är ett kombinerat uttalande som får alla tre värdena (fuktighet, temperatur och tryck):

dubbel temperatur, tryck; dubbel luftfuktighet = objectName.readHumidity (temperatur, tryck); // mäta luftfuktighet, tryck och temperatur

Detta uttalande läser data från BMP280 -enheten bara en gång och returnerar alla tre värdena. Detta är något mer effektiv användning av I2C -bussen och säkerställer att de tre avläsningarna motsvarar samma mätcykel. Observera att namnen på variablerna kan ändras till allt som användaren gillar, men deras ordning är fast - temperaturen kommer först och trycket kommer i andra hand.

Dessa användningsfall täcks av exempelskisser som medföljer biblioteket, som är basicTemperature.ino, basicPressure.ino, basicHumidity.ino, basicTemperatureAndPressure.ino och basicHumidityAndTemperatureAndPressure.ino.

Mer sofistikerad temperatur- och tryckmätning

Även om ovanstående serie uttalanden fungerar utan problem, finns det ett par frågor:

  1. enheten körs kontinuerligt och förbrukar därför ström vid sin maximala nivå. Om energin kommer från ett batteri kan det vara nödvändigt att minska detta.
  2. på grund av den förbrukade effekten kommer enheten att uppleva uppvärmning, och därför kommer den uppmätta temperaturen att vara högre än omgivningstemperaturen. Jag kommer att täcka detta mer i ett senare steg.

Ett resultat som använder mindre effekt, och ger en temperatur som är närmare omgivningen, kan uppnås genom att använda start () med parametrar som gör det till viloläge (t.ex. läge = 0). Till exempel:

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

När en mätning önskas, väck sedan enheten med ett konfigurationskommando för att registrera F2 (om det behövs) och F4 som ställer in lämpliga värden för osrs_h, osrs_t och osrs_p, plus -läge = 1 (enkelbildsläge). Till exempel:

[objectName.updateF2Control (1);] // osrs_h - behövs aldrig för BMP280, // och behövs inte för BME280 om antalet mätningar inte ändras // från värdet som anges i begin (). objectName.updateF4Control (1, 1, 1); // osrs_t, osrs_p, mode

Efter att ha väckt enheten börjar den mäta, men resultatet kommer inte att vara tillgängligt på några millisekunder - minst 4 ms, kanske upp till 70 ms eller mer, beroende på antalet mätningar som har angetts. Om läskommandot skickas omedelbart returnerar enheten värdena från föregående mätning - vilket kan vara acceptabelt i vissa applikationer, men i de flesta fall är det förmodligen bättre att fördröja tills den nya mätningen är tillgänglig.

Denna fördröjning kan göras på flera sätt.

  1. vänta en viss tid för att täcka den längsta förväntade fördröjningen
  2. vänta en tid beräknad från den maximala mättiden per mätning (dvs. 2,3 ms) gånger antalet mätningar, plus overhead, plus en marginal.
  3. vänta en kortare tid beräknad enligt ovan, men med den nominella mättiden (dvs. 2 ms) plus overhead, och börja sedan kontrollera "Jag mäter" -biten i statusregistret. När statusbiten läser 0 (dvs inte mäter) får du temperatur- och tryckavläsningarna.
  4. börja omedelbart kontrollera statusregistret och få temperatur- och tryckavläsningar när statusbiten läser 0,

Jag kommer att visa ett exempel på ett sätt att göra detta lite senare.

Konfigurationsregisteråtgärder

För att få allt detta att hända behöver vi flera verktyg som jag ännu inte har introducerat. Dom är:

byte readRegister (reg)

void updateRegister (reg, värde)

Var och en av dessa har flera härledda kommandon i biblioteket, vilket gör programvaran för specifika åtgärder lite enklare.

Exemplet powerSaverPressureAndTemperature.ino använder metod nr 3. Kodraden som gör den upprepade kontrollen är

medan (bmp0.readRegister (0xF3) >> 3); // loop till F3bit 3 == 0

Observera att denna skiss är för en ESP8266 mikrokontroller. Jag använde ett WeMos D1 mini pro. Skissen fungerar inte med Atmega -mikrokontroller, som har olika instruktioner för att sova. Denna skiss utövar flera andra kommandon, så jag kommer att introducera dem alla innan jag beskriver den skissen mer detaljerat.

När mikrokontrollern sover parallellt med BMP280 -sensorn kan konfigurationen av sensorn för de nödvändiga mätningarna göras i kommandot start () med de 6 parametrarna. Men om mikrokontrollern inte sover, men sensorn är, måste sensorn vid mätningen väckas och meddelas sin mätkonfiguration. Detta kan göras direkt med

updateRegister (reg, värde)

men är lite lättare med följande tre kommandon:

updateF2Control (osrs_h); // Endast BME280

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

När mätningen är klar, om läget som används är Single shot (Forced mode), kommer enheten automatiskt att somna igen. Men om mätuppsättningen innefattar flera mätningar med kontinuerligt (normalt) läge måste BMP280 sättas i viloläge. Detta kan göras med något av de två följande kommandona:

updateF4Control16xSleep ();

updateF4ControlSleep (värde);

Båda dessa ställer in lägesbitarna till 00 (dvs viloläge). Men den första sätter osrs_t och osrs_p till 111 (dvs 16 mätningar) medan den andra lagrar de låga 6 bitarna från "värde" till bitar 7: 2 i 0xF4 -registret.

På samma sätt lagrar följande uttalande de låga sex bitarna av "värde" i bitarna 7: 2 i 0xF5 -registret.

updateF5ConfigSleep (värde);

Användningen av dessa senare kommandon möjliggör lagring av 12 bitar information i BMP280 -registren F4 och F5. Åtminstone när det gäller ESP8266, när mikrokontrollern vaknar efter en period av sömn, börjar den i början av skissen utan att ha känt till dess tillstånd före sömnkommandot. För att lagra kunskap om dess tillstånd före sömnkommandot kan data lagras i flashminne, antingen med hjälp av EEPROM -funktionerna eller genom att skriva en fil med SPIFFS. Flashminnet har dock en begränsning av antalet skrivcykler, i storleksordningen 10 000 till 100 000. Detta innebär att om mikrokontrollern går igenom en vilovakningscykel med några sekunders mellanrum kan den överskrida den tillåtna minneskrivningen gräns om några månader. Att lagra några bitar av data i BMP280 har ingen sådan begränsning.

Data lagrade i registren F4 och F5 kan återställas när mikrokontrollern vaknar med hjälp av kommandona

readF4Sleep ();

readF5Sleep ();

Dessa funktioner läser motsvarande register, flyttar innehållet för att ta bort de 2 LSB: erna och returnerar de återstående 6 bitarna. Dessa funktioner används i exemplet sketch powerSaverPressureAndTemperatureESP.ino enligt följande:

// läs värdet av EventCounter tillbaka från bmp0

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

Dessa funktioner läser motsvarande register, flyttar innehållet för att ta bort de 2 LSB: erna och returnerar de återstående 6 bitarna. Dessa funktioner används i exemplet sketch powerSaverPressureAndTemperature.ino enligt följande:

// läs värdet av EventCounter tillbaka från bmp1

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

Rå temperatur och tryckfunktioner

De grundläggande funktionerna readTemperature, readPressure och readHumidity har två komponenter. Först erhålls de råa 20-bitars temperatur- och tryckvärdena från BME/P280, eller det råa 16-bitars fuktvärdet erhålls från BME280. Därefter används kompensationsalgoritmen för att generera utgångsvärdena i grader Celsius, hPa eller %RH.

Biblioteket tillhandahåller separata funktioner för dessa komponenter, så att rådata temperatur, trycksäkerhet och fuktighetsdata kan erhållas och kanske manipuleras på något sätt. Algoritmen för att härleda temperaturen, trycket och luftfuktigheten från dessa råvärden tillhandahålls också. I biblioteket implementeras dessa algoritmer med aritmetik med dubbel längd. Det fungerar bra på ESP8266 som är en 32-bitars processor och använder 64 bitar för "dubbla" flottörvariabler. Att göra dessa funktioner tillgängliga kan vara användbart för att bedöma och eventuellt ändra beräkningen för andra plattformar.

Dessa funktioner är:

readRawPressure (rawTemperature); // läser råtrycks- och temperaturdata från BME/P280readRawHumidity (rawTemperature, rawPressure); // läser rå luftfuktighet, temperatur och tryckdata från BME280 calcTemperature (rawTemperature, t_fine); calcPressure (rawPressure, t_fine); calcHumidity (rawHumidity, t_fine)

"T-fin" -argumentet till dessa funktioner är värt lite förklaring. Både tryck- och fuktkompensationsalgoritmer inkluderar en temperaturberoende komponent som uppnås genom variabeln t_fine. CalcTemperature -funktionen skriver ett värde i t_fine baserat på temperaturkompensationsalgoritmlogiken, som sedan används som ingång i både calcPressure och calcHumidity.

Ett exempel på användningen av dessa funktioner finns i exempelskissen rawPressureAndTemperature.ino och även i koden för funktionen readHumidity () i bibliotekets.cpp -fil.

Höjd och havsnivå tryck

Det finns ett känt samband mellan atmosfärstryck och höjd. Vädret påverkar också trycket. När väderorganisationerna publicerar information om atmosfärstryck, brukar de justera den för höjd och så visar det "synoptiska diagrammet" isobarer (linjer med konstant tryck) standardiserade för att betyda havsnivån. Så det finns verkligen tre värden i detta förhållande, och att känna till två av dem möjliggör härledning av det tredje. De tre värdena är:

  • höjd över havet
  • det faktiska lufttrycket på den höjden
  • ekvivalent lufttryck vid havsnivå (mer strikt, medelhög havsnivå, eftersom omedelbar havsnivå ständigt förändras)

Detta bibliotek har två funktioner för denna relation, enligt följande:

calcAltitude (tryck, seaLevelhPa);

calcNormalisedPressure (tryck, höjd);

Det finns också en förenklad version, som antar standard havstryck på 1013,15 hPa.

calcAltitude (tryck); // standard seaLevelPressure antas

Steg 3: BMP280 -enhetsinformation

BMP280 Enhetsinformation
BMP280 Enhetsinformation

Hårdvarumöjligheter

BMP280 har 2 byte konfigurationsdata (vid registeradresser 0xF4 och 0xF5) som används för att styra flera mätnings- och datautmatningsalternativ. Den ger också 2 bitar statusinformation och 24 byte kalibreringsparametrar som används för att omvandla rådata temperatur och tryckvärden till konventionella temperatur- och tryckenheter. BME280 har ytterligare data enligt följande:

  • 1 extra byte konfigurationsdata vid registeradress 0xF2 som används för att styra flera fuktmätningar;
  • 8 extra byte kalibreringsparametrar som används för att omvandla värdet på råfuktighet till relativ fuktighetsprocent.

Temperatur-, tryck- och statusregistren för BME280 är desamma som för BMP280 med mindre undantag enligt följande:

  • "ID" -bitarna i BME280 är inställda på 0x60, så det kan särskiljas från BMP280 som kan vara 0x56, 0x57 eller 0x58
  • sömntidsstyrningen (t_sb) ändras så att de två långa tiderna i BMP280 (2000 ms och 4000 ms) ersätts i BME280 med korta tider på 10 ms och 20 ms. Den maximala sömntiden i BME280 är 1000 ms.
  • I BME280 är temperatur- och tryckråvärdena alltid 20 bitar om filtrering tillämpas. Användningen av 16 till 19 bitars värden är begränsad till fall utan filtrering (dvs filter = 0).

Temperatur och tryck är vardera 20 bitars värden, som måste konverteras till konventionell temperatur och tryck via en ganska komplex algoritm med 3 16 bitars kalibreringsparametrar för temperatur och 9 16 bitars kalibreringsparametrar plus temperaturen för tryck. Temperaturmätningens granulatitet är 0,0003 grader Celsius för en minst signifikant bitändring (20 bitars avläsning) och ökar till 0,0046 grader Celsius om 16 bitars avläsning används.

Luftfuktighet är ett 16 bitars värde som måste konverteras till relativ fuktighet via en annan komplex algoritm med 6 kalibreringsparametrar som är en blandning av 8, 12 och 16 bitar.

Databladet visar den absoluta noggrannheten för temperaturavläsningen som +-0,5 C vid 25 C och +-1 C över intervallet 0 till 65 C.

Storleken på tryckmätningen är 0,15 Pascal (dvs. 0,0015 hektoPascal) vid 20 bitars upplösning, eller 2,5 Pascal vid 16 bitars upplösning. Råttrycksvärdet påverkas av temperaturen, så att cirka 25C, en temperaturökning på 1 grad C minskar det uppmätta trycket med 24 Pascal. Temperaturkänsligheten redovisas i kalibreringsalgoritmen, så de levererade tryckvärdena bör vara exakta vid olika temperaturer.

Databladet visar den absoluta noggrannheten för tryckavläsningen som +-1 hPa för temperaturer mellan 0 C och 65 C.

Fuktighetens noggrannhet anges i databladet som +-3% RH och +-1% hysteres.

Hur det fungerar

De 24 byte med temperatur- och tryckkalibreringsdata, och även i fallet med BME280, måste de 8 bytena med fuktkalibreringsdata läsas från enheten och lagras i variabler. Dessa data är individuellt programmerade i enheten på fabriken, så olika enheter har olika värden - åtminstone för några av parametrarna. En BME/P280 kan vara i ett av två tillstånd. I ett tillstånd mäter den. I den andra staten väntar den (sover).

Vilket tillstånd det är i kan kontrolleras genom att titta på bit 3 i registret 0xF3.

Resultaten av den senaste mätningen kan erhållas när som helst genom att läsa motsvarande datavärde, oavsett om enheten sover eller mäter.

Det finns också två sätt att använda BME/P280. Det ena är Kontinuerligt läge (kallat Normalt läge i databladet) som upprepade gånger växlar mellan mät- och sovlägen. I det här läget utför enheten en uppsättning mätningar, somnar sedan, vaknar sedan för en annan uppsättning mätningar och så vidare. Antalet individuella mätningar och varaktigheten av sömndelen av cykeln kan alla styras genom konfigurationsregistren.

Det andra sättet att använda BME/P280 är Single Shot -läge (kallas Forced mode i databladet). I det här läget väcks enheten från viloläge med ett kommando för att mäta, det gör en uppsättning mätningar och går sedan tillbaka till viloläge. Antalet individuella mätningar i uppsättningen styrs i konfigurationskommandot som väcker enheten.

I BMP280, om en enda mätning görs, fylls de 16 mest signifikanta bitarna i värdet, och de fyra minst signifikanta bitarna i värdeavläsningen är alla nollor. Antalet mätningar kan ställas in på 1, 2, 4, 8 eller 16 och när antalet mätningar ökar ökar antalet bitar som fylls med data, så att med 16 mätningar fylls alla 20 bitar med mätdata. Databladet hänvisar till denna process som översampling.

I BME280 gäller samma arrangemang så länge resultatet inte filtreras. Om filtrering används är värdena alltid 20 bitar, oavsett hur många mätningar som görs i varje mätcykel.

Varje individuell mätning tar cirka 2 millisekunder (typiskt värde; maxvärde är 2,3 ms). Lägg till detta en fast overhead på cirka 2 ms (vanligtvis lite mindre) betyder att en mätsekvens, som kan bestå av från 1 till 32 individuella mätningar, kan ta från 4 ms upp till 66 ms.

Databladet innehåller en uppsättning rekommenderade kombinationer av temperatur- och trycköversampling för olika applikationer.

Konfigurationskontrollregister

De två konfigurationskontrollregistren i BMP280 finns vid registeradresserna 0xF4 och 0xF5 och mappas på 6 individuella konfigurationskontrollvärden. 0xF4 består av:

  • 3 bitar osrs_t (mät temperatur 0, 1, 2, 4, 8 eller 16 gånger);
  • 3 bitar osrs_p (mät tryck 0, 1, 2, 4, 8 eller 16 gånger); och
  • 2 bitars läge (viloläge, tvång (dvs. enkelbild), normalt (dvs. kontinuerligt).

0xF5 består av:

  • 3 bitar t_sb (vänteläge, 0,5 ms till 4000 ms);
  • 3 bitars filter (se nedan); och
  • 1 bit spiw_en som väljer SPI eller I2C.

Filterparametern styr en typ av exponentiell sönderfallalgoritm, eller Infinite Impulse Response (IIR) -filter, som appliceras på värdena för råtryck och temperaturmätning (men inte för fuktighetsvärden). Ekvationen ges i databladet. En annan presentation är:

Värde (n) = Värde (n-1) * (K-1) / K + mätning (n) / K

där (n) anger det senaste mätnings- och utgångsvärdet; och K är filterparametern. Filterparametern K och kan ställas in på 1, 2, 4, 8 eller 16. Om K är satt till 1 blir ekvationen bara Värde (n) = mätning (n). Kodningen av filterparametern är:

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

BME 280 lägger till ett ytterligare konfigurationskontrollregister på adressen 0xF2, "ctrl_hum" med en enda 3-bitars parameter osrs_h (mät fuktighet 0, 1, 2, 4, 8 eller 16 gånger).

Steg 4: Mätning och avläsningstid

Jag planerar att lägga till detta senare och visa tidpunkten för kommandon och mätsvar.

Iddt - ström vid temperaturmätning. Typiskt värde 325 uA

Iddp - ström vid tryckmätning. Typiskt värde 720 uA, max 1120 uA

Iddsb - aktuell i vänteläge. Typiskt värde 0,2 uA, max 0,5 uA

Iddsl - aktuell i viloläge. Typiskt värde 0,1 uA, max 0,3 uA

Steg 5: Riktlinjer för programvara

Riktlinjer för programvara
Riktlinjer för programvara
Riktlinjer för programvara
Riktlinjer för programvara

I2C Burst -läge

BMP280 -databladet ger vägledning om avläsning av data (avsnitt 3.9). Det står "det rekommenderas starkt att använda en burstläsning och inte adressera varje register individuellt. Detta förhindrar en eventuell blandning av byte som hör till olika mätningar och minskar gränssnittstrafiken." Ingen vägledning ges om avläsningen av kompensations-/kalibreringsparametrarna. Förmodligen är dessa inte ett problem eftersom de är statiska och inte ändras.

Detta bibliotek läser alla sammanhängande värden i en enda läsoperation - 24 byte för parametrarna för temperatur och tryckkompensation, 6 byte för temperatur och tryck kombinerat och 8 byte för fuktighet, temperatur och tryck kombinerat. När temperaturen ensam kontrolleras läses endast 3 byte.

Användning av makron (#define etc.)

Det finns inga andra makron i det här biblioteket än det vanliga biblioteket "include guard" -makro som förhindrar dubbelarbete.

Alla konstanter definieras med hjälp av const -nyckelordet, och felsökningsutskrift styrs med standard C -funktioner.

Det har varit källan till viss osäkerhet för mig, men rådet jag får från att läsa många inlägg om detta ämne är att användning av #define för deklaration av konstanter (åtminstone) och (förmodligen) felsökningskontroll är onödig och oönskad.

Fallet för användning av const snarare än #define är ganska klart - const använder samma resurser som #define (dvs noll) och de resulterande värdena följer tillämpningsreglerna och minskar därmed risken för fel.

Fallet för felsökningsutskriftskontroll är lite mindre tydligt, eftersom sättet jag har gjort det innebär att den slutliga koden innehåller logiken för felsökningsutskriftsuttalanden, även om de aldrig utövas. Om biblioteket ska användas i ett stort projekt på en mikrokontroller med mycket begränsat minne kan detta bli ett problem. Eftersom min utveckling var på en ESP8266 med ett stort flashminne verkade detta inte vara ett problem för mig.

Steg 6: Temperaturprestanda

Jag tänker lägga till detta senare.

Steg 7: Tryckprestanda

Jag tänker lägga till detta senare.

Rekommenderad: