Sommario:

Libreria per BMP280 e BME280: 7 passaggi
Libreria per BMP280 e BME280: 7 passaggi

Video: Libreria per BMP280 e BME280: 7 passaggi

Video: Libreria per BMP280 e BME280: 7 passaggi
Video: Usare il sensore BMP280 per temperatura, pressione e umidità con Arduino - Video 313 2024, Novembre
Anonim
Libreria per BMP280 e BME280
Libreria per BMP280 e BME280
Libreria per BMP280 e BME280
Libreria per BMP280 e BME280
Libreria per BMP280 e BME280
Libreria per BMP280 e BME280

introduzione

Non ho deciso di scrivere questa libreria. È "successo" come effetto collaterale di un progetto che ho iniziato che utilizza un BMP280. Quel progetto non è ancora finito, ma penso che la biblioteca sia pronta per condividerla con gli altri. Successivamente ho avuto la necessità di utilizzare un BME280, che aggiunge la misurazione dell'umidità alla capacità di pressione e temperatura del BMP280. Il BME280 è "retrocompatibile" con il BMP280, ovvero tutti i registri e i passaggi necessari per leggere la pressione e la temperatura dal BME280 sono gli stessi utilizzati per il BMP280. Sono necessari ulteriori registri e passaggi per leggere l'umidità, applicabili solo al BME280. Ciò solleva la domanda, una libreria per entrambi o due librerie separate. L'hardware per i due tipi di dispositivi è completamente intercambiabile. Anche molti dei moduli in vendita (ad esempio su Ebay e AliExpress) sono etichettati BME/P280. Per scoprire di che tipo si tratta, bisogna guardare la (minuscola) scritta sul sensore stesso, oppure testare il byte ID del dispositivo. Ho deciso di scegliere un'unica libreria. Sembra aver funzionato bene.

Il feedback, in particolare qualsiasi suggerimento per miglioramenti, sarà apprezzato.

Funzionalità e capacità della libreria

Una libreria è un pezzo di software che fornisce un'interfaccia di programmazione delle applicazioni (API) per consentire a un programmatore di esercitare le capacità del dispositivo, senza dover necessariamente occuparsi di tutti i dettagli più fini. Auspicabilmente, l'API dovrebbe essere facile per un principiante con requisiti semplici per iniziare, fornendo allo stesso tempo il pieno sfruttamento delle capacità del dispositivo. È auspicabile che la libreria segua eventuali linee guida specifiche del produttore del dispositivo, nonché le buone pratiche generali del software. Ho cercato di ottenere tutto questo. Quando ho iniziato con il BMP280, ho trovato 3 diverse librerie per questo: Adafruit_BMP280; Seeed_BMP280; e uno chiamato BMP280 dal produttore del dispositivo. Né Adafruit né Seeed fornivano funzionalità estese, sebbene funzionassero bene e fossero facili da usare per le applicazioni di base. Non sono riuscito a capire come utilizzare quello prodotto dal produttore del dispositivo (Bosch Sensortec). Questa potrebbe essere la mia mancanza, piuttosto che la loro. Tuttavia la libreria era molto più complicata delle altre due, non sono riuscito a trovare istruzioni o esempi di utilizzo (ho trovato successivamente degli esempi nel file "bmp280_support.c", tuttavia questi non mi sono stati particolarmente utili).

Come risultato di questi fattori, ho deciso di scrivere la mia libreria per il BMP280.

Esaminando la situazione della libreria per il BME280, ho trovato librerie separate Adafruit_BME280, Seed_BME280 e un'altra BME280_MOD-1022 scritta da Embedded Adventures. Nessuno di loro ha combinato le funzioni per BMP280 in una libreria in grado di utilizzare il BME280. Nessuno di loro ha supportato esplicitamente la capacità dei dispositivi di memorizzare alcuni bit di dati mentre il dispositivo e il suo microprocessore di controllo sono in modalità di sospensione (questa capacità è evidente nel foglio dati e supportata nella libreria che ho scritto e descritto qui).

Una libreria combinata dovrebbe supportare tutte le funzionalità del BME280, ma se utilizzata con un BMP280 non dovrebbe imporre alcun sovraccarico dalle funzioni inutilizzate. I vantaggi di una libreria combinata includono un minor numero di file di libreria da gestire, una facile combinazione di dispositivi diversi nello stesso progetto e modifiche semplificate per la manutenzione o gli aggiornamenti che devono essere eseguiti in un unico posto anziché in due. Questi sono probabilmente tutti piuttosto minori, anche insignificanti, ma…

Funzionalità del dispositivo

Il BMP280 e il BME280 sono dispositivi a montaggio superficiale di circa 5 mm quadrati e 1 mm di altezza. Sono presenti 8 pad di interfaccia, inclusi 2 pad di ingresso alimentazione separati e due pad di terra. Sono disponibili su eBay come modulo con 4 o 6 pin tirati fuori. Il modulo a 4 pin ha un indirizzo I2C fisso e non può essere configurato per utilizzare il protocollo SPI.

Il modulo a 6 pin o il dispositivo nudo può essere utilizzato con i protocolli I2C o SPI. In modalità I2C può avere due indirizzi differenti, ottenuti collegando il pin SDO a Ground (per indirizzo base = 0x76) oa Vdd (per indirizzo base +1 = 0x77). In modalità SPI ha la consueta disposizione di 1 orologio, 2 dati (uno per ogni direzione) e un pin di selezione del dispositivo (CS).

La libreria che ho scritto e descritto qui supporta solo I2C. Le librerie Adafruit_BMP280 e BME_MOD-1022 supportano sia i2C che SPI.

La libreria è scaricabile qui:

github.com/farmerkeith/BMP280-library

Passaggio 1: configurazione dell'hardware

Configurazione dell'hardware
Configurazione dell'hardware

Prima che la libreria possa essere utile è necessario collegare un microcontrollore al BMP280 (oa due di essi se lo si desidera).

Ho usato un WeMos D1 mini pro, quindi mostrerò le sue connessioni. Altri microcontrollori saranno simili, devi solo collegare correttamente i pin SDA e SCL.

Nel caso del WeMos D1 mini pro, le connessioni sono:

Funzione Pin WeMos Pin BMP280 Note

SDA D2 SDA SCL D1 SCL Vdd 3V3 Vin Nominal 3.3V Ground GND Controllo indirizzo SDO Ground o Vdd I2C select CSB Vdd (GND seleziona SPI)

Notare che il pin SDO su alcuni dei moduli MP280 è etichettato SDD e il pin Vdd potrebbe essere etichettato VCC. Nota: le linee SDA e SCL dovrebbero avere resistori di pull-up tra la linea e il pin Vin. In genere un valore di 4.7K dovrebbe essere OK. Alcuni moduli BMP280 e BME280 hanno resistori pull-up da 10K inclusi nel modulo (che non è una buona pratica, poiché mettere più dispositivi sul bus I2C potrebbe caricarlo eccessivamente). Tuttavia, l'utilizzo di 2 moduli BME/P280 ciascuno con un resistore da 10K non dovrebbe essere un problema nella pratica purché non ci siano troppi altri dispositivi sullo stesso bus anche con resistori di pull-up.

Una volta connesso l'hardware, puoi facilmente verificare se il tuo dispositivo è un BMP280 o un BME280 eseguendo lo sketch I2CScan_ID che puoi trovare qui:

Puoi anche verificare se hai un BMP280 o un BME280 guardando il dispositivo stesso. Ho trovato necessario utilizzare un microscopio digitale per farlo, ma se la tua vista è molto buona potresti essere in grado di farlo senza alcun ausilio. Ci sono due linee di stampa sull'involucro del dispositivo. La chiave è la prima lettera della seconda riga, che nel caso dei dispositivi BMP280 è una "K" e nel caso dei dispositivi BME280 è una "U".

Passaggio 2: API fornite dalla libreria

API fornite dalla Biblioteca
API fornite dalla Biblioteca
API fornite dalla Biblioteca
API fornite dalla Biblioteca

Includere la libreria in uno schizzo

La libreria è inclusa in uno schizzo nel modo standard usando l'istruzione

#include "farmerkeith_BMP280.h"

Questa istruzione deve essere inclusa nella prima parte dello schizzo prima dell'inizio della funzione setup().

Creazione di un oggetto software BME o BMP

Ci sono 3 livelli per la creazione dell'oggetto software BMP280. Il più semplice è solo

bme280 nomeoggetto; o bmp280 nomeoggetto;

ad esempio, BMP280 bmp0;

Questo crea un oggetto software con l'indirizzo di default 0x76 (cioè per SDO connesso a massa).

Il livello successivo per la creazione di un oggetto software BME280 o BMP280 ha un parametro di 0 o 1, come segue:

bme280 nomeoggettoA(0);

bmp280 nomeoggettoB(1);

Il parametro (0 o 1) viene aggiunto all'indirizzo di base I2C, in modo che due dispositivi BME280 o BMP280 possano essere utilizzati sullo stesso bus I2C (incluso uno di ciascuno).

Il terzo livello per la creazione di un oggetto software BME o BMP280 ha due parametri. Il primo parametro, che può essere 0 o 1, è per l'indirizzo, come nel caso precedente. Il secondo parametro controlla la stampa di debug. Se è impostato su 1, ogni transazione con l'oggetto software genera output Serial.print che consentono al programmatore di vedere i dettagli della transazione. Per esempio:

bmp280 nomeoggettoB(1, 1);

Se il parametro di stampa di debug è impostato su 0, l'oggetto software torna al comportamento normale (nessuna stampa).

Questa istruzione o istruzioni devono essere incluse dopo la funzione #include e prima della funzione setup().

Inizializzazione dell'oggetto software BME o BMP

Prima di essere utilizzato, è necessario leggere i parametri di calibrazione dal dispositivo e configurarlo per qualsiasi modalità di misurazione, sovracampionamento e impostazioni del filtro siano appropriate.

Per un'inizializzazione semplice e di uso generale, l'istruzione è:

nomeoggetto.begin();

Questa versione di begin() legge i parametri di calibrazione dal dispositivo e imposta osrs_t=7 (16 misurazioni di temperatura), osrs_p=7 (16 misurazioni di pressione), mode=3 (continuo, Normale), t_sb=0 (0,5 ms di sospensione tra set di misure), filter=0 (K=1, quindi nessun filtro) e spiw_en=0 (SPI disabilitato, quindi usa I2C). Nel caso del BME280, c'è un parametro extra osrs_h=7 per 16 misurazioni di umidità.

Esiste un'altra versione di begin() che accetta tutti i sei (o 7) parametri. L'equivalente della precedente affermazione è

nomeoggetto.begin(7, 7, 3, 0, 0, 0); // osrs_t, osrs_p, modalità, t_sb, filtro, spiw_en

o nomeOggetto.begin(7, 7, 3, 0, 0, 0, 7); // osrs_t, osrs_p, modalità, t_sb, filtro, spiw_en, osrs_h

L'elenco completo dei codici e dei loro significati è nella scheda tecnica del BME280 e del BMP280 e anche nei commenti nel file.cpp della libreria.

Misurazione semplice della temperatura e della pressione

Per ottenere una misurazione della temperatura il modo più semplice è

double temperature=nomeoggetto.readTemperature (); // misura la temperatura

Per ottenere una misurazione della pressione il modo più semplice è

double pressure=objectName.readPressure (); // misura la pressione

Per ottenere una misurazione dell'umidità il modo più semplice è

double umidità=nomeOggetto.readHumidity (); // misura l'umidità (solo BME280)

Per ottenere sia la temperatura che la pressione, le due affermazioni precedenti possono essere utilizzate una dopo l'altra, ma esiste un'altra opzione, ovvero:

doppia temperatura;

double pressure=objectName.readPressure (temperatura); // misura la pressione e la temperatura

Questa dichiarazione legge i dati dal dispositivo BME280 o BMP280 solo una volta e restituisce sia la temperatura che la pressione. Questo è un uso leggermente più efficiente del bus I2C e garantisce che le due letture corrispondano allo stesso ciclo di misurazione.

Per il BME 280, un'istruzione combinata che ottiene tutti e tre i valori (umidità, temperatura e pressione) è:

doppia temperatura, pressione;doppia umidità=nomeoggetto.leggiUmidità (temperatura, pressione); // misura umidità, pressione e temperatura

Questa istruzione legge i dati dal dispositivo BMP280 solo una volta e restituisce tutti e tre i valori. Questo è un uso leggermente più efficiente del bus I2C e garantisce che le tre letture corrispondano allo stesso ciclo di misurazione. Nota che i nomi delle variabili possono essere cambiati con qualsiasi cosa piaccia all'utente, ma il loro ordine è fisso: la temperatura viene prima e la pressione viene dopo.

Questi casi d'uso sono trattati negli schizzi di esempio forniti con la libreria, ovvero basicTemperature.ino, basicPressure.ino, basicHumidity.ino, basicTemperatureAndPressure.ino e basicHumidityAndTemperatureAndPressure.ino.

Misurazione della temperatura e della pressione più sofisticata

Sebbene la serie di istruzioni di cui sopra funzionerà senza problemi, ci sono un paio di problemi:

  1. il dispositivo funziona continuamente e quindi consuma energia al massimo livello. Se l'energia proviene da una batteria, potrebbe essere necessario ridurla.
  2. a causa della potenza consumata, il dispositivo subirà un riscaldamento e quindi la temperatura misurata sarà superiore alla temperatura ambiente. Tratterò questo più in un passaggio successivo.

Un risultato che consuma meno energia e fornisce una temperatura più vicina all'ambiente può essere ottenuto utilizzando begin() con parametri che lo mettono in sleep (es. mode=0). Per esempio:

nomeoggetto.begin(1, 1, 0, 0, 0, 0[, 1]); // osrs_t, osrs_p, modalità, t_sb, filtro, spiw_en [, osrs_h]

Quindi, quando si desidera una misura, svegliare il dispositivo con un comando di configurazione ai registri F2 (se richiesto) e F4 che imposta i valori appropriati di osrs_h, osrs_t e osrs_p, plus mode=1 (modalità single shot). Per esempio:

[objectName.updateF2Control(1);] // osrs_h - mai necessario per BMP280, // e non è necessario per BME280 se il numero di misurazioni non viene modificato // dal valore fornito in begin(). nomeoggetto.updateF4Control(1, 1, 1); // osrs_t, osrs_p, modalità

Dopo aver riattivato il dispositivo, inizierà a misurare, ma il risultato non sarà disponibile per alcuni millisecondi - almeno 4 ms, forse fino a 70 ms o più, a seconda del numero di misurazioni che sono state specificate. Se il comando di lettura viene inviato immediatamente, il dispositivo restituirà i valori della misurazione precedente, il che può essere accettabile in alcune applicazioni, ma nella maggior parte dei casi è probabilmente meglio ritardare fino a quando non sarà disponibile la nuova misurazione.

Questo ritardo può essere eseguito in diversi modi.

  1. attendere un periodo di tempo fisso per coprire il ritardo previsto più lungo
  2. attendere una quantità di tempo calcolata dal tempo di misurazione massimo per misurazione (cioè 2,3 ms) per il numero di misurazioni, più l'overhead, più un margine.
  3. attendere un tempo più breve calcolato come sopra, ma utilizzando il tempo di misurazione nominale (cioè 2 ms) più l'overhead, quindi iniziare a controllare il bit "Sto misurando" nel registro di stato. Quando il bit di stato legge 0 (cioè, non sta misurando), ottenere le letture di temperatura e pressione.
  4. iniziare immediatamente a controllare il registro di stato e ottenere le letture di temperatura e pressione quando il bit di stato legge 0,

Mostrerò un esempio di un modo per farlo un po' più avanti.

Operazioni del registro di configurazione

Per fare in modo che tutto questo accada, abbiamo bisogno di diversi strumenti che non ho ancora introdotto. Loro sono:

byte readRegister(reg)

void updateRegister(reg, value)

Ognuno di questi ha diversi comandi derivati nella libreria, che rendono un po' più semplice il software per azioni specifiche.

L'esempio powerSaverPressureAndTemperature.ino utilizza il metodo n. 3. La riga di codice che esegue il controllo ripetuto è

while (bmp0.readRegister(0xF3)>>3); // loop fino a F3bit 3 ==0

Si noti che questo schizzo è per un microcontrollore ESP8266. Ho usato un WeMos D1 mini pro. Lo schizzo non funzionerà con i microcontrollori Atmega, che hanno istruzioni diverse per dormire. Questo schizzo esercita diversi altri comandi, quindi li introdurrò tutti prima di descrivere lo schizzo in modo più dettagliato.

Quando il microcontrollore dorme in parallelo con il sensore BMP280, la configurazione del sensore per le misurazioni richieste può essere eseguita nel comando begin(), utilizzando i 6 parametri. Tuttavia, se il microcontrollore non sta dormendo, ma il sensore lo è, allora al momento della misurazione il sensore deve essere svegliato e comunicato la sua configurazione di misurazione. Questo può essere fatto direttamente con

updateRegister(reg, value)

ma è un po' più semplice con i seguenti tre comandi:

updateF2Control(osrs_h); // Solo BME280

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

Al termine della misurazione, se la modalità utilizzata è Scatto singolo (modalità forzata), il dispositivo tornerà automaticamente in modalità di sospensione. Tuttavia, se il set di misurazioni prevede più misurazioni utilizzando la modalità continua (Normale), il BMP280 dovrà essere rimesso in modalità di sospensione. Questo può essere fatto con uno dei due seguenti comandi:

updateF4Control16xSleep();

updateF4ControlSleep(valore);

Entrambi impostano i bit di modalità su 00 (cioè modalità di sospensione). Tuttavia il primo imposta osrs_t e osrs_p a 111 (cioè 16 misure) mentre il secondo memorizza i 6 bit bassi da "value" nei bit 7:2 del registro 0xF4.

Allo stesso modo, la seguente istruzione memorizza i sei bit bassi di "valore" nei bit 7:2 del registro 0xF5.

updateF5ConfigSleep(valore);

L'utilizzo di questi ultimi comandi consente la memorizzazione di 12 bit di informazioni nei registri BMP280 F4 e F5. Almeno nel caso dell'ESP8266, quando il microcontrollore si sveglia dopo un periodo di sospensione, si avvia all'inizio dello schizzo senza conoscere il suo stato prima del comando di sospensione. Per memorizzare la conoscenza del suo stato prima del comando sleep, i dati possono essere archiviati nella memoria flash, utilizzando le funzioni EEPROM o scrivendo un file utilizzando SPIFFS. Tuttavia, la memoria flash ha una limitazione del numero di cicli di scrittura, dell'ordine da 10.000 a 100.000. Ciò significa che se il microcontrollore sta attraversando un ciclo di sonno-veglia ogni pochi secondi, può superare la scrittura di memoria consentita limite in pochi mesi. L'archiviazione di alcuni bit di dati nel BMP280 non ha tali limitazioni.

I dati memorizzati nei registri F4 e F5 possono essere recuperati quando il microcontrollore si sveglia utilizzando i comandi

leggiF4Sleep();

readF5Sleep();

Queste funzioni leggono il registro corrispondente, spostano il contenuto per rimuovere i 2 LSB e restituiscono i restanti 6 bit. Queste funzioni vengono utilizzate nello schizzo di esempio powerSaverPressureAndTemperatureESP.ino come segue:

// rilegge il valore di EventCounter da bmp0

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

Queste funzioni leggono il registro corrispondente, spostano il contenuto per rimuovere i 2 LSB e restituiscono i restanti 6 bit. Queste funzioni vengono utilizzate nello schizzo di esempio powerSaverPressureAndTemperature.ino come segue:

// rilegge il valore di EventCounter da bmp1

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

Funzioni grezze di temperatura e pressione

Le funzioni di base readTemperature, readPressure e readHumidity hanno due componenti. Innanzitutto i valori grezzi di temperatura e pressione a 20 bit sono ottenuti dal BME/P280, oppure il valore grezzo di umidità a 16 bit è ottenuto dal BME280. Quindi l'algoritmo di compensazione viene utilizzato per generare i valori di uscita in gradi Celsius, hPa o %UR.

La libreria fornisce funzioni separate per questi componenti, in modo che i dati grezzi di temperatura, pressione e umidità possano essere ottenuti e forse manipolati in qualche modo. Viene fornito anche l'algoritmo per ricavare la temperatura, la pressione e l'umidità da questi valori grezzi. Nella libreria questi algoritmi sono implementati utilizzando l'aritmetica in virgola mobile a doppia lunghezza. Funziona bene su ESP8266 che è un processore a 32 bit e utilizza 64 bit per variabili float "doppie". Rendere accessibili queste funzioni può essere utile per valutare ed eventualmente modificare il calcolo per altre piattaforme.

Queste funzioni sono:

readRawPressure (rawTemperature); // legge i dati grezzi di pressione e temperatura da BME/P280readRawHumidity (rawTemperature, rawPressure); // legge i dati grezzi di umidità, temperatura e pressione da BME280 calcTemperature (rawTemperature, t_fine); calcPressure (rawPressure, t_fine); calcHumidity (rawHumidity, t_fine)

L'argomento "t-fine" di queste funzioni merita un po' di spiegazione. Entrambi gli algoritmi di compensazione della pressione e dell'umidità includono una componente dipendente dalla temperatura che si ottiene attraverso la variabile t_fine. La funzione calcTemperature scrive un valore in t_fine basato sulla logica dell'algoritmo di compensazione della temperatura, che viene quindi utilizzato come input sia in calcPressure che in calcHumidity.

Un esempio dell'utilizzo di queste funzioni si trova nello sketch di esempio rawPressureAndTemperature.ino, e anche nel codice per la funzione readHumidity() nel file.cpp della libreria.

Altitudine e pressione sul livello del mare

Esiste una relazione nota tra la pressione atmosferica e l'altitudine. Anche il tempo influenza la pressione. Quando le organizzazioni meteorologiche pubblicano le informazioni sulla pressione atmosferica, di solito le regolano per l'altitudine e quindi la "carta sinottica" mostra le isobare (linee di pressione costante) standardizzate sul livello medio del mare. Quindi in realtà ci sono 3 valori in questa relazione e conoscerne due consente la derivazione del terzo. I 3 valori sono:

  • altitudine sul livello del mare
  • pressione atmosferica effettiva a quell'altitudine
  • pressione atmosferica equivalente al livello del mare (più precisamente, livello medio del mare, perché il livello del mare istantaneo cambia costantemente)

Questa libreria fornisce due funzioni per questa relazione, come segue:

calcAltitude (pressione, seaLevelhPa);

calcNormalizedPressure (pressione, altitudine);

Esiste anche una versione semplificata, che assume la pressione standard al livello del mare di 1013,15 hPa.

calcAltitude (pressione); // pressione del livello del mare standard presunta

Passaggio 3: dettagli del dispositivo BMP280

Dettagli del dispositivo BMP280
Dettagli del dispositivo BMP280

Funzionalità hardware

Il BMP280 dispone di 2 byte di dati di configurazione (agli indirizzi di registro 0xF4 e 0xF5) che vengono utilizzati per controllare più opzioni di misurazione e uscita dati. Fornisce inoltre 2 bit di informazioni sullo stato e 24 byte di parametri di calibrazione che vengono utilizzati per convertire i valori grezzi di temperatura e pressione in unità di temperatura e pressione convenzionali. Il BME280 dispone di dati aggiuntivi come segue:

  • 1 byte aggiuntivo di dati di configurazione all'indirizzo di registro 0xF2 utilizzato per controllare più misurazioni di umidità;
  • 8 byte extra di parametri di calibrazione utilizzati per convertire il valore di umidità grezzo in percentuale di umidità relativa.

I registri di temperatura, pressione e stato per il BME280 sono gli stessi del BMP280 con le seguenti eccezioni:

  • i bit "ID" del BME280 sono impostati a 0x60, quindi può essere distinto da BMP280 che può essere 0x56, 0x57 o 0x58
  • il controllo del tempo di sospensione (t_sb) viene modificato in modo che i due tempi lunghi nel BMP280 (2000 ms e 4000 ms) siano sostituiti nel BME280 con tempi brevi di 10 ms e 20 ms. Il tempo di sospensione massimo nel BME280 è di 1000 ms.
  • Nel BME280 i valori grezzi di temperatura e pressione sono sempre 20 bit se viene applicato il filtraggio. L'uso di valori da 16 a 19 bit è limitato ai casi senza filtraggio (es. filtro=0).

Temperatura e pressione sono valori a 20 bit ciascuno, che devono essere convertiti in temperatura e pressione convenzionali tramite un algoritmo piuttosto complesso che utilizza 3 parametri di calibrazione a 16 bit per la temperatura e 9 parametri di calibrazione a 16 bit più la temperatura per la pressione. La granulosità della misurazione della temperatura è di 0,0003 gradi Celsius per una variazione di bit meno significativa (lettura a 20 bit), aumentando a 0,0046 gradi Celsius se si utilizza la lettura a 16 bit.

L'umidità è un valore a 16 bit che deve essere convertito in umidità relativa tramite un altro complesso algoritmo che utilizza 6 parametri di calibrazione che sono un mix di 8, 12 e 16 bit.

La scheda tecnica mostra l'accuratezza assoluta della lettura della temperatura come +-0,5 C a 25 C e +-1 C nell'intervallo da 0 a 65 C.

La granularità della misurazione della pressione è 0,15 Pascal (cioè 0,0015 ettoPascal) a una risoluzione di 20 bit o 2,5 Pascal a una risoluzione di 16 bit. Il valore della pressione grezza è influenzato dalla temperatura, per cui intorno ai 25 C, un aumento della temperatura di 1 grado C diminuisce la pressione misurata di 24 Pascal. La sensibilità alla temperatura è considerata nell'algoritmo di calibrazione, quindi i valori di pressione forniti dovrebbero essere accurati a temperature diverse.

La scheda tecnica mostra l'accuratezza assoluta della lettura della pressione come +-1 hPa per temperature comprese tra 0 C e 65 C.

La precisione dell'umidità è indicata nella scheda tecnica come +-3% UR e +-1% isteresi.

Come funziona

I 24 byte di dati di calibrazione di temperatura e pressione, e anche nel caso del BME280 gli 8 byte di dati di calibrazione di umidità, devono essere letti dal dispositivo e memorizzati in variabili. Questi dati sono programmati individualmente nel dispositivo in fabbrica, quindi dispositivi diversi hanno valori diversi, almeno per alcuni parametri. Un BME/P280 può trovarsi in uno di due stati. In uno stato sta misurando. Nell'altro stato è in attesa (dormiente).

Lo stato in cui si trova può essere verificato guardando il bit 3 del registro 0xF3.

I risultati della misurazione più recente possono essere ottenuti in qualsiasi momento leggendo il valore dei dati corrispondente, indipendentemente dal fatto che il dispositivo stia dormendo o stia misurando.

Ci sono anche due modi di far funzionare il BME/P280. Uno è la modalità continua (chiamata modalità normale nella scheda tecnica) che alterna ripetutamente gli stati di misurazione e sospensione. In questa modalità il dispositivo esegue una serie di misurazioni, quindi va in sospensione, quindi si riattiva per un'altra serie di misurazioni e così via. Il numero di misurazioni individuali e la durata della parte di sonno del ciclo possono essere controllati attraverso i registri di configurazione.

L'altro modo di utilizzare il BME/P280 è la modalità Single Shot (chiamata modalità Forced nella scheda tecnica). In questa modalità il dispositivo viene riattivato dalla modalità di sospensione da un comando di misurazione, esegue una serie di misurazioni, quindi torna in modalità di sospensione. Il numero di misurazioni individuali nel set è controllato nel comando di configurazione che attiva il dispositivo.

Nel BMP280, se viene effettuata una singola misurazione, i 16 bit più significativi del valore vengono popolati e i quattro bit meno significativi nella lettura del valore sono tutti zeri. Il numero di misurazioni può essere impostato su 1, 2, 4, 8 o 16 e all'aumentare del numero di misurazioni, aumenta il numero di bit popolati con i dati, in modo che con 16 misurazioni tutti i 20 bit vengano popolati con i dati di misurazione. La scheda tecnica fa riferimento a questo processo come sovracampionamento.

Nel BME280, si applica la stessa disposizione finché il risultato non viene filtrato. Se si utilizza il filtraggio, i valori sono sempre di 20 bit, indipendentemente da quante misurazioni vengono effettuate in ciascun ciclo di misurazione.

Ogni singola misurazione dura circa 2 millisecondi (valore tipico; il valore massimo è 2,3 ms). Aggiungete a questo un sovraccarico fisso di circa 2 ms (di solito un po' meno) significa che una sequenza di misura, che può consistere da 1 a 32 misurazioni singole, può richiedere da 4 ms fino a 66 ms.

La scheda tecnica fornisce una serie di combinazioni consigliate di sovracampionamento di temperatura e pressione per varie applicazioni.

Registri di controllo della configurazione

I due registri di controllo della configurazione nel BMP280 si trovano agli indirizzi di registro 0xF4 e 0xF5 e sono mappati su 6 valori di controllo della configurazione individuali. 0xF4 è composto da:

  • 3 bit osrs_t (misura temperatura 0, 1, 2, 4, 8 o 16 volte);
  • 3 bit osrs_p (misura la pressione 0, 1, 2, 4, 8 o 16 volte); e
  • Modalità a 2 bit (Sleep, Forced (cioè scatto singolo), Normal (cioè continua).

0xF5 è composto da:

  • 3 bit t_sb (tempo di standby, da 0,5 ms a 4000 ms);
  • filtro a 3 bit (vedi sotto); e
  • 1 bit spiw_en che seleziona SPI o I2C.

Il parametro del filtro controlla un tipo di algoritmo di decadimento esponenziale, o filtro Infinite Impulse Response (IIR), applicato ai valori grezzi di misurazione della pressione e della temperatura (ma non ai valori di umidità). L'equazione è riportata nella scheda tecnica. Un'altra presentazione è:

Valore(n) = Valore(n-1) * (K-1)/K + misura(n) / K

dove (n) indica la misurazione e il valore di output più recenti; e K è il parametro del filtro. Il parametro del filtro K e può essere impostato su 1, 2, 4, 8 o 16. Se K è impostato su 1, l'equazione diventa Value(n) = misura(n). La codifica del parametro filter è:

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

Il BME 280 aggiunge un ulteriore registro di controllo della configurazione all'indirizzo 0xF2, "ctrl_hum" con un singolo parametro a 3 bit osrs_h (misura umidità 0, 1, 2, 4, 8 o 16 volte).

Passaggio 4: tempi di misurazione e lettura

Ho intenzione di aggiungerlo in seguito, mostrando i tempi dei comandi e le risposte di misurazione.

Iddt - corrente alla misurazione della temperatura. Valore tipico 325 uA

Iddp - corrente alla misurazione della pressione. Valore tipico 720 uA, max 1120 uA

Iddsb - corrente in modalità standby. Valore tipico 0,2 uA, max 0,5 uA

Iddsl - corrente in modalità di sospensione. Valore tipico 0,1 uA, massimo 0,3 uA

Passaggio 5: linee guida software

Linee guida per il software
Linee guida per il software
Linee guida per il software
Linee guida per il software

Modalità burst I2C

La scheda tecnica BMP280 fornisce indicazioni sulla lettura dei dati (sezione 3.9). Dice "si consiglia vivamente di utilizzare una lettura burst e di non indirizzare ogni registro individualmente. Ciò impedirà un possibile scambio di byte appartenenti a misurazioni diverse e ridurrà il traffico di interfaccia". Non vengono fornite indicazioni circa la lettura dei parametri di compensazione/calibrazione. Presumibilmente questi non sono un problema perché sono statici e non cambiano.

Questa libreria legge tutti i valori contigui in un'unica operazione di lettura: 24 byte nel caso dei parametri di compensazione di temperatura e pressione, 6 byte per temperatura e pressione combinate e 8 byte per umidità, temperatura e pressione combinate. Quando viene controllata la sola temperatura, vengono letti solo 3 byte.

Utilizzo di macro (#define ecc.)

Non ci sono macro in questa libreria oltre alla solita macro libreria "include guard" che impedisce la duplicazione.

Tutte le costanti sono definite utilizzando la parola chiave const e la stampa di debug è controllata con le funzioni C standard.

È stata fonte di qualche incertezza per me, ma il consiglio che ricevo leggendo molti post su questo argomento è che l'uso di #define per la dichiarazione di costanti (almeno) e (probabilmente) il controllo della stampa di debug non è necessario e non è auspicabile.

Il caso per l'uso di const piuttosto che #define è abbastanza chiaro: const utilizza le stesse risorse di #define (cioè nil) ei valori risultanti seguono le regole di ambito, riducendo così la possibilità di errori.

Il caso del controllo della stampa di debug è un po' meno chiaro, perché il modo in cui l'ho fatto significa che il codice finale contiene la logica per le istruzioni di stampa di debug, anche se non vengono mai esercitate. Se la libreria deve essere utilizzata in un grande progetto su un microcontrollore con memoria molto limitata, questo potrebbe diventare un problema. Poiché il mio sviluppo era su un ESP8266 con una grande memoria flash, questo non sembrava essere un problema per me.

Passaggio 6: prestazioni della temperatura

Ho intenzione di aggiungere questo più tardi.

Passaggio 7: prestazioni della pressione

Ho intenzione di aggiungere questo più tardi.

Consigliato: