yasuyuki onodera / BME280

Dependents:   mbed_BME280

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BME280.cpp Source File

BME280.cpp

00001 //**********************
00002 // BME280.cpp for mbed
00003 //
00004 // BME280 bme280(P0_5,P0_4);
00005 // or
00006 // I2C i2c(P0_5,P0_4);
00007 // BME280 bme280(i2c);
00008 //
00009 // (C)Copyright 2015 All rights reserved by Y.Onodera
00010 // http://einstlab.web.fc2.com
00011 //**********************
00012 
00013 #include "mbed.h"
00014 #include "BME280.h"
00015 
00016 BME280::BME280 (PinName sda, PinName scl) : _i2c(sda, scl) {
00017     init();
00018 }
00019 BME280::BME280 (I2C& p_i2c) : _i2c(p_i2c) {
00020     init();
00021 }
00022 
00023 
00024 unsigned char BME280::get(unsigned char a)
00025 {
00026     
00027     buf[0] = a;  // register
00028     _i2c.write(BME280_ADDR, buf, 1);   // with stop
00029     // get data
00030     _i2c.read( BME280_ADDR, buf, 1);
00031     return buf[0];
00032 
00033 }
00034 
00035 void BME280::set(unsigned char a, unsigned char b)
00036 {
00037     
00038     buf[0] = a;  // register
00039     buf[1] = b;
00040     _i2c.write(BME280_ADDR, buf, 2);   // with stop
00041 
00042 }
00043 
00044 
00045 void BME280::getALL()
00046 {
00047     // set ctrl_meas : forced mode
00048     set(ctrl_meas, 0x25);
00049 
00050     // wait 11.5ms for forced mode
00051     wait_ms(12);
00052     
00053     // wait status
00054     if(get(status) != 0)wait_ms(1);
00055 
00056     // get temp
00057     temp.XLSB = get(temp_xlsb);
00058     temp.LSB = get(temp_lsb);
00059     temp.MSB = get(temp_msb);
00060     temp.dummy = 0;
00061 
00062     // get press
00063     press.XLSB = get(press_xlsb);
00064     press.LSB = get(press_lsb);
00065     press.MSB = get(press_msb);
00066     press.dummy = 0;
00067 
00068     // get hum
00069     hum.LSB = get(hum_lsb);
00070     hum.MSB = get(hum_msb);
00071 
00072 
00073     // compensation
00074     t = BME280_compensate_T_int32(temp.s32>>12);
00075     p = BME280_compensate_P_int64(press.s32>>12);
00076     h = BME280_compensate_H_int32((signed int)hum.u16);
00077 }
00078 
00079 unsigned int BME280::humidity()
00080 {
00081 
00082     // get hum
00083     getALL();
00084     return h;
00085     
00086 }
00087 
00088 signed int BME280::temperature()
00089 {
00090 
00091     // get temp
00092     getALL();
00093     return t;
00094     
00095 }
00096 
00097 unsigned int BME280::pressure()
00098 {
00099 
00100     // get hum
00101     getALL();
00102     return p;
00103     
00104 }
00105 
00106 void BME280::init()
00107 {
00108     
00109     // get calibrations
00110     calib.LSB = get(calib00);
00111     calib.MSB = get(calib01);
00112     dig_T1 = calib.u16;
00113     calib.LSB = get(calib02);
00114     calib.MSB = get(calib03);
00115     dig_T2 = calib.s16;
00116     calib.LSB = get(calib04);
00117     calib.MSB = get(calib05);
00118     dig_T3 = calib.s16;
00119     calib.LSB = get(calib06);
00120     calib.MSB = get(calib07);
00121     dig_P1 = calib.u16;
00122     calib.LSB = get(calib08);
00123     calib.MSB = get(calib09);
00124     dig_P2 = calib.s16;
00125     calib.LSB = get(calib10);
00126     calib.MSB = get(calib11);
00127     dig_P3 = calib.s16;
00128     calib.LSB = get(calib12);
00129     calib.MSB = get(calib13);
00130     dig_P4 = calib.s16;
00131     calib.LSB = get(calib14);
00132     calib.MSB = get(calib15);
00133     dig_P5 = calib.s16;
00134     calib.LSB = get(calib16);
00135     calib.MSB = get(calib17);
00136     dig_P6 = calib.s16;
00137     calib.LSB = get(calib18);
00138     calib.MSB = get(calib19);
00139     dig_P7 = calib.s16;
00140     calib.LSB = get(calib20);
00141     calib.MSB = get(calib21);
00142     dig_P8 = calib.s16;
00143     calib.LSB = get(calib22);
00144     calib.MSB = get(calib23);
00145     dig_P9 = calib.s16;
00146     dig_H1 = get(calib25);
00147     calib.LSB = get(calib26);
00148     calib.MSB = get(calib27);
00149     dig_H2 = calib.s16;
00150     dig_H3 = get(calib28);
00151     calib.MSB = get(calib29);
00152     calib.LSB = get(calib30) << 4;
00153     dig_H4 = calib.s16>>4;
00154     calib.LSB = get(calib30);
00155     calib.MSB = get(calib31);
00156     dig_H5 = calib.s16>>4;
00157     dig_H6 = get(calib32);
00158 
00159     // Set configuration
00160     set(config, 0x00);
00161     set(ctrl_hum, 0x01);
00162 
00163 }
00164 
00165 // Returns temperature in DegC, resolution is 0.01 DegC. Output value of "5123" equals 51.23 DegC.
00166 // t_fine carries fine temperature as global value
00167 BME280_S32_t BME280::BME280_compensate_T_int32(BME280_S32_t adc_T)
00168 {
00169     BME280_S32_t var1, var2, T;
00170     var1  = ((((adc_T>>3) - ((BME280_S32_t)dig_T1<<1))) * ((BME280_S32_t)dig_T2)) >> 11;
00171     var2  = (((((adc_T>>4) - ((BME280_S32_t)dig_T1)) * ((adc_T>>4) - ((BME280_S32_t)dig_T1))) >> 12) *
00172         ((BME280_S32_t)dig_T3)) >> 14;
00173     t_fine = var1 + var2;
00174     T  = (t_fine * 5 + 128) >> 8;
00175     return T;
00176 }
00177 
00178 // Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
00179 // Output value of "24674867" represents 24674867/256 = 96386.2 Pa = 963.862 hPa
00180 BME280_U32_t BME280::BME280_compensate_P_int64(BME280_S32_t adc_P)
00181 {
00182     BME280_S64_t var1, var2, p;
00183     var1 = ((BME280_S64_t)t_fine) - 128000;
00184     var2 = var1 * var1 * (BME280_S64_t)dig_P6;
00185     var2 = var2 + ((var1*(BME280_S64_t)dig_P5)<<17);
00186     var2 = var2 + (((BME280_S64_t)dig_P4)<<35);
00187     var1 = ((var1 * var1 * (BME280_S64_t)dig_P3)>>8) + ((var1 * (BME280_S64_t)dig_P2)<<12);
00188     var1 = (((((BME280_S64_t)1)<<47)+var1))*((BME280_S64_t)dig_P1)>>33;
00189     if (var1 == 0)
00190     {
00191         return 0; // avoid exception caused by division by zero
00192     }
00193     p = 1048576-adc_P;
00194     p = (((p<<31)-var2)*3125)/var1;
00195     var1 = (((BME280_S64_t)dig_P9) * (p>>13) * (p>>13)) >> 25;
00196     var2 = (((BME280_S64_t)dig_P8) * p) >> 19;
00197     p = ((p + var1 + var2) >> 8) + (((BME280_S64_t)dig_P7)<<4);
00198     return (BME280_U32_t)p;
00199 }
00200 
00201 // Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits).
00202 // Output value of "47445" represents 47445/1024 = 46.333 %RH
00203 BME280_U32_t BME280::BME280_compensate_H_int32(BME280_S32_t adc_H)
00204 {
00205     BME280_S32_t v_x1_u32r;
00206     v_x1_u32r = (t_fine - ((BME280_S32_t)76800));
00207     v_x1_u32r = (((((adc_H << 14) - (((BME280_S32_t)dig_H4) << 20) - (((BME280_S32_t)dig_H5) * v_x1_u32r)) +
00208         ((BME280_S32_t)16384)) >> 15) * (((((((v_x1_u32r * ((BME280_S32_t)dig_H6)) >> 10) * (((v_x1_u32r *
00209         ((BME280_S32_t)dig_H3)) >> 11) + ((BME280_S32_t)32768))) >> 10) + ((BME280_S32_t)2097152)) *
00210         ((BME280_S32_t)dig_H2) + 8192) >> 14));
00211     v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((BME280_S32_t)dig_H1)) >> 4));
00212     v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
00213     v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
00214     return (BME280_U32_t)(v_x1_u32r>>12); 
00215 }
00216