OS6. i2s BME280 library, also works with BMP280 without Humidity. See BME280.h for example code.
Revision 0:19fab6c64964, committed 2021-01-02
- 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 |
diff -r 000000000000 -r 19fab6c64964 BME280.cpp --- /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; +}
diff -r 000000000000 -r 19fab6c64964 BME280.h --- /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