OS6. i2s BME280 library, also works with BMP280 without Humidity. See BME280.h for example code.

Files at this revision

API Documentation at this revision

Comitter:
star297
Date:
Sat Jan 02 10:32:48 2021 +0000
Commit message:
initial commit

Changed in this revision

BME280.cpp Show annotated file Show diff for this revision Revisions of this file
BME280.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BME280.cpp	Sat Jan 02 10:32:48 2021 +0000
@@ -0,0 +1,183 @@
+#include "BME280.h"
+
+BME::BME(PinName sda, PinName scl, char slave_adr) : bme(sda, scl)
+{       
+    address=slave_adr;
+    bme.frequency(100000);
+}
+    
+void BME::initialize()
+{
+    char cmd[18]; 
+    wait_us(5000);  
+    
+    if(_debug)printf("\033[0m\033[2J\033[H ++++ BME-P register's ++++\r\n\n");
+     
+    cmd[0] = 0xF2;                  // ctrl_hum
+    cmd[1] = 0x01;                  // Humidity oversampling x1
+    bme.write(address, cmd, 2);
+ 
+    cmd[0] = 0xF4;                  // ctrl_meas
+    cmd[1] = 0x27;                  // Temparature oversampling x1, Pressure oversampling x1, Normal mode
+    bme.write(address, cmd, 2);
+ 
+    cmd[0] = 0xF5;                  // config
+    cmd[1] = 0xa0;                  // Standby 1000ms, Filter off
+    bme.write(address, cmd, 2);
+    
+    // sensor registers
+    if(_debug)printf("chip_id = 0x%x\n\n", chip_id);
+     
+    cmd[0] = 0x88;                  // read dig_T calibration regs
+    bme.write(address, cmd, 1);
+    bme.read(address, cmd, 6); 
+    dig_T1 = (cmd[1] << 8) | cmd[0];
+    dig_T2 = (cmd[3] << 8) | cmd[2];
+    dig_T3 = (cmd[5] << 8) | cmd[4]; 
+    if(_debug)printf("Temp Cal reg's:\nT1 = 0x%x\nT2 = 0x%x\nT3 = 0x%x\n\n", dig_T1, dig_T2, dig_T3);
+    
+    cmd[0] = 0x8E;                  // read dig_P calibration regs
+    bme.write(address, cmd, 1);
+    bme.read(address, cmd, 18); 
+    dig_P1 = (cmd[ 1] << 8) | cmd[ 0];
+    dig_P2 = (cmd[ 3] << 8) | cmd[ 2];
+    dig_P3 = (cmd[ 5] << 8) | cmd[ 4];
+    dig_P4 = (cmd[ 7] << 8) | cmd[ 6];
+    dig_P5 = (cmd[ 9] << 8) | cmd[ 8];
+    dig_P6 = (cmd[11] << 8) | cmd[10];
+    dig_P7 = (cmd[13] << 8) | cmd[12];
+    dig_P8 = (cmd[15] << 8) | cmd[14];
+    dig_P9 = (cmd[17] << 8) | cmd[16];    
+    if(_debug)printf("Pressure Cal reg's:\nP1 = 0x%x\nP2 = 0x%x\nP3 = 0x%x\nP4 = 0x%x\n", dig_P1, dig_P2, dig_P3, dig_P4);
+    if(_debug)printf("P5 = 0x%x\nP6 = 0x%x\nP7 = 0x%x\nP8 = 0x%x\nP9 = 0x%x\n\n", dig_P5, dig_P6, dig_P7, dig_P8, dig_P9);
+    
+    if(chip_id == 0x60){            // Only BME280 has Humidity     
+        cmd[0] = 0xA1;              // read dig_H calibration LSB regs
+        bme.write(address, cmd, 1);
+        bme.read(address, cmd, 1);
+        cmd[1] = 0xE1;              // read dig_H calibration MSB regs
+        bme.write(address, &cmd[1], 1);
+        bme.read(address, &cmd[1], 7);
+        dig_H1 = cmd[0];
+        dig_H2 = (cmd[2] << 8) | cmd[1];
+        dig_H3 = cmd[3];
+        dig_H4 = (cmd[4] << 4) | (cmd[5] & 0x0f);
+        dig_H5 = (cmd[6] << 4) | ((cmd[5]>>4) & 0x0f);
+        dig_H6 = cmd[7];    
+        if(_debug)printf("Humidity Cal reg's:\nH1 = 0x%x\nH2 = 0x%x\nH3 = 0x%x\n", dig_H1, dig_H2, dig_H3);
+        if(_debug)printf("H4 = 0x%x\nH5 = 0x%x\nH6 = 0x%x\n", dig_H4, dig_H5, dig_H6);
+    }
+} 
+
+int BME::init()
+{
+    char cmd[2];
+    cmd[0] = 0xE0;      // reset reg
+    cmd[1] = 0xB6;
+    bme.write(address, cmd, 2);
+    if(chipID()){
+        initialize();
+        return chip_id;
+        }
+        else return 0;            
+}
+
+int BME::chipID()
+{
+    char cmd[1];
+    cmd[0] = 0xD0;      // chip_id
+    bme.write(address, cmd, 1);
+    cmd[0] = 0x00;
+    bme.read(address, cmd, 1);
+    chip_id = cmd[0];
+    return chip_id;
+}
+
+float BME::getTemperature()
+{
+    if(!chipID()){init();}     // check if live sensor
+        
+    int32_t var1, var2, T, adc_T;
+    float temp;
+    char cmd[4];
+    cmd[0] = 0xFA;      // temp_msb
+    bme.write(address, cmd, 1);
+    bme.read(address, &cmd[1], 3);
+    
+    adc_T = (cmd[1] << 12) | (cmd[2] << 4) | (cmd[3] >> 4);
+        
+    var1  = ((((adc_T>>3) - ((int32_t)dig_T1 <<1))) *
+       ((int32_t)dig_T2)) >> 11;    
+    var2  = (((((adc_T>>4) - ((int32_t)dig_T1)) *
+         ((adc_T>>4) - ((int32_t)dig_T1))) >> 12) *
+       ((int32_t)dig_T3)) >> 14;    
+    t_fine = var1 + var2;    
+    T  = (t_fine * 5 + 128) >> 8;
+    temp = T/100.0;    
+    if(temp>-41 && temp<86){    // return temperature if within device limits.
+        return temp;
+        }
+        else return 99.99;      // error value     
+}
+ 
+float BME::getPressure()
+{
+    if(!chipID()){init();}     // check if live sensor
+    
+    uint32_t adc_P;
+    int64_t var1, var2, p;
+    float press;
+    char cmd[4]; 
+    cmd[0] = 0xF7;      // press_msb
+    bme.write(address, cmd, 1);
+    bme.read(address, &cmd[1], 3);
+     
+    adc_P = (cmd[1] << 12) | (cmd[2] << 4) | (cmd[3] >> 4);
+     
+    var1 = ((int64_t)t_fine) - 128000;
+    var2 = var1 * var1 * (int64_t)dig_P6;
+    var2 = var2 + ((var1 * (int64_t)dig_P5) << 17);
+    var2 = var2 + (((int64_t)dig_P4) << 35);
+    var1 = ((var1 * var1 * (int64_t)dig_P3)>>8)+((var1 * (int64_t)dig_P2)<<12);
+    var1 = (((((int64_t)1)<<47)+var1)) * ((int64_t)dig_P1)>>33;
+    if (var1 == 0) {return 0;}
+    p = 1048576-adc_P;
+    p = (((p<<31)-var2)*3125)/var1;
+    var1 = (((int64_t)dig_P9) * (p>>13) * (p>>13))>>25;
+    var2 = (((int64_t)dig_P8) * p)>>19;
+    p = ((p + var1 + var2)>>8) + (((int64_t)dig_P7)<<4);    
+    press = ((float)p/256)/100.0f;    
+    if(press>300 && press<1100){    // return temperature if within device limits.
+        return press;
+        }
+        else return 9999;           // error value
+}
+ 
+float BME::getHumidity()
+{
+    if(!chipID()){init();}         // check if live sensor
+    
+    uint32_t humid_raw;
+    int32_t v_x1r;
+    float humid;
+    char cmd[4]; 
+    cmd[0] = 0xfd; // hum_msb
+    bme.write(address, cmd, 1);
+    bme.read(address, &cmd[1], 2);
+ 
+    humid_raw = (cmd[1] << 8) | cmd[2];
+ 
+    v_x1r = (t_fine - 76800);
+    v_x1r = (((((humid_raw << 14) -(((int32_t)dig_H4) << 20) - (((int32_t)dig_H5) *
+            v_x1r)) + ((int32_t)16384)) >> 15) * (((((((v_x1r *
+            (int32_t)dig_H6) >> 10) * (((v_x1r * ((int32_t)dig_H3)) >> 11) +
+            32768)) >> 10) + 2097152) * (int32_t)dig_H2 + 8192) >> 14));
+    v_x1r = (v_x1r - (((((v_x1r >> 15) * (v_x1r >> 15)) >> 7) *
+            (int32_t)dig_H1) >> 4));
+    v_x1r = (v_x1r < 0 ? 0 : v_x1r);
+    v_x1r = (v_x1r > 419430400 ? 419430400 : v_x1r);
+ 
+    humid = ((float)(v_x1r >> 12))/1024.0f;
+ 
+    return humid;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BME280.h	Sat Jan 02 10:32:48 2021 +0000
@@ -0,0 +1,99 @@
+#ifndef BME_H
+#define BME_H
+
+#include "mbed.h"
+
+#define _debug   1      // '1' to enable prinf BME's registers
+
+/*
+Bosch Sensortec BMP280 BME280 i2c example code
+using 64bit numeric calculations as recomended by Bosch.
+Some sensors supplied from Chinese suppliers may have 'suspect'
+quality sensor with different i2c address.
+My sensors were address 0xEC and all the ones I have
+differ quite a bit in tolerance :( so be aware if accuracy is paramount.
+*/
+
+/*
+#include "mbed.h"
+#include "BME280.h"
+
+BME sensor(D0,D1, 0xEC); // sda, clk, 8bit address (NUCLEO-L432)
+DigitalOut led(LED1);
+
+float temp, humidity, pressure, altitude;
+
+int main()
+{
+
+    int BMPE_id = sensor.init();    // initialise and get sensor id
+
+    if(!BMPE_id) {
+        printf("No sensor detected!!\n");
+        while(1){
+            led=!led;
+            ThisThread::sleep_for(200ms);
+        }
+    }
+     
+    if(_debug){ // set _debug to '1' to see BME's registers
+        ThisThread::sleep_for(2s);
+        }
+    
+    while(1) {
+        led=1;
+        printf("\033[0m\033[2J\033[H------- BME280-BMP280 Sensor example -------\r\n\n");
+        if(BMPE_id==0x60) {
+            printf("BME280 detected id: 0x%x\n\n",BMPE_id);
+        } else if(BMPE_id==0x58) {
+            printf("BMP280 detected id: 0x%x\n\n",BMPE_id);
+        }
+
+        temp = sensor.getTemperature();
+            
+        printf("Temperature: %3.2f %cc \n",temp,0xb0);
+
+        if(sensor.chip_id==0x60) {        // only BME has Humidity
+            humidity    = sensor.getHumidity();
+            printf("Humidity:    %2.2f %cRh \n", humidity,0x25);
+        }
+        pressure    = sensor.getPressure();
+        printf("Pressure:    %4.2f mbar's \n\n",pressure);
+
+        altitude = 44330.0f*( 1.0f - pow((pressure/1013.25f), (1.0f/5.255f)))+18;     // Calculate altitude in meters
+        printf("Altitude: %3.1f meters   %4.1f feet \r\n(Referenced to 1,013.25 millibars @ sea level) \r\n\n", altitude,altitude*3.2810f);
+        led=0;
+        ThisThread::sleep_for(1s);
+    }
+}
+*/
+
+class BME
+{
+public:
+
+    BME(PinName sda, PinName scl, char slave_adr);
+
+    int         init(void);
+    int         chipID(void);
+    float       getTemperature(void);
+    float       getPressure(void);
+    float       getHumidity(void);
+  
+    uint16_t    chip_id;
+
+private:
+
+    I2C         bme;
+    void        initialize(void);
+    char        address;
+    uint16_t    dig_T1;
+    int16_t     dig_T2, dig_T3;
+    uint16_t    dig_P1;
+    int16_t     dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9;
+    uint16_t    dig_H1, dig_H3;
+    int16_t     dig_H2, dig_H4, dig_H5, dig_H6;
+    int32_t     t_fine;
+    bool        dbg_on;
+};
+#endif // BME_H