A multifunctional and modular Firmware for Multitech's mDot based on ARM mBed provides a widerange of functionality for several Sensors such as MAX44009, BME280, MPU9250, SI1143 and uBlox. It allows you to quickly build a Sensornode that measures specific data with its sensors and sends it via LoRaWAN.

Dependencies:   mDot_LoRa_Sensornode_Flowmeter_impl mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BME280.cpp Source File

BME280.cpp

00001 /*
00002  * BME280.cpp
00003  *
00004  *  Created on: 18.05.2016
00005  *      Author: Adrian
00006  */
00007 
00008 #include "BME280.h"
00009 
00010 BME280::BME280(I2C_RT* i2c){
00011     setI2C(i2c);
00012     this->config = new BME280Config();
00013 }
00014 
00015 BME280::~BME280() {
00016     // TODO Auto-generated destructor stub
00017 }
00018 
00019 void BME280::init(BME280_MODE desiredMode){
00020 
00021     config->build(desiredMode);
00022 
00023     setOversamplingHumidity();
00024     setOversamplingTemperature();
00025     setOversamplingPressure();
00026     setMode();
00027 
00028     getTrimValuesHumidity();
00029     getTrimValuesPressure();
00030     getTrimValuesTemperature();
00031 }
00032 
00033 void BME280::setI2C(I2C_RT* i2c_rt){
00034     this->i2c = i2c_rt;
00035 }
00036 
00037 uint32_t BME280::getHumidity(){
00038 
00039     // Data Containers
00040     uint8_t msbRegisterData[1];
00041     uint8_t lsbRegisterData[1];
00042 
00043     i2c->read_RT(
00044             BME280_SENSOR_ADDRESS,BME280_SENSOR_HUM_MSB,false,msbRegisterData,1);
00045     i2c->read_RT(
00046             BME280_SENSOR_ADDRESS,BME280_SENSOR_HUM_LSB,false,lsbRegisterData,1);
00047 
00048     int32_t temp_fine = getTemperature();
00049 
00050     int32_t humRaw = (int32_t) (msbRegisterData[0]<<8|lsbRegisterData[0]);
00051     uint32_t hum_fine = this->compensateHumidity(humRaw,temp_fine);
00052 
00053     return hum_fine;
00054 
00055 }
00056 
00057 float BME280::getHumidityFloat(){
00058     return (float) getHumidity()/ 1024;
00059 }
00060 
00061 uint32_t BME280::getPressure(){
00062 
00063     // Data Containers
00064     uint8_t msbRegisterData[1];
00065     uint8_t lsbRegisterData[1];
00066     uint8_t xlsbRegisterData[1];
00067 
00068     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_PRESS_MSB,false,msbRegisterData,1);
00069     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_PRESS_LSB,false,lsbRegisterData,1);
00070     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_PRESS_XLSB,false,xlsbRegisterData, 1);
00071 
00072     int32_t temp_fine = getTemperature();
00073 
00074     int32_t pressRaw = (int32_t) (msbRegisterData[0]<<12|lsbRegisterData[0]<<4|lsbRegisterData[0]);
00075     uint32_t press_fine = compensatePressure(pressRaw,temp_fine);
00076 
00077     return press_fine;
00078 }
00079 
00080 float BME280::getPressureFloat(){
00081     return (float)getPressure()/256;
00082 }
00083 
00084 int32_t BME280::getTemperature(){
00085     uint8_t msbRegisterData[1];
00086     uint8_t lsbRegisterData[1];
00087     uint8_t xlsbRegisterData[1];
00088 
00089     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_TEMP_MSB,
00090             false,msbRegisterData,1);
00091     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_TEMP_LSB,
00092             false,lsbRegisterData,1);
00093     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_TEMP_XLSB,
00094             false,xlsbRegisterData,1);
00095 
00096     int32_t tempRaw = (int32_t) (msbRegisterData[0]<<12|lsbRegisterData[0]<<4|xlsbRegisterData[0]);
00097     int32_t tempFine = compensateTemperature(tempRaw);
00098 
00099     return tempFine;
00100 }
00101 
00102 float BME280::getTemperatureFloat(){
00103     int32_t temperature = this->getTemperature();
00104 
00105     return (float)(temperature)/100;
00106 }
00107 
00108 void BME280::getTrimValuesHumidity(){
00109     // Data Container for Trim Values Humidity
00110     uint8_t digH1Raw[1];
00111     uint8_t digH2Raw[2];
00112     uint8_t digH3Raw[1];
00113     uint8_t digH4Raw[2];
00114     uint8_t digH5Raw[2];
00115     uint8_t digH6Raw[1];
00116 
00117     // Get the Trim parameters for the exact calculation of the Humidity
00118     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH1_LSB,0,&digH1Raw[0],1);
00119     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH2_LSB,0,&digH2Raw[0],1);
00120     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH2_MSB,0,&digH2Raw[1],1);
00121     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH3_LSB,0,&digH3Raw[0],1);
00122     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH4_LSB,0,&digH4Raw[0],1);
00123     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH4_MSB,0,&digH4Raw[1],1);
00124     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH5_LSB,0,&digH5Raw[0],1);
00125     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH5_MSB,0,&digH5Raw[1],1);
00126     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH6_LSB,0,&digH6Raw[0],1);
00127 
00128     // Convert data into values
00129     digH1=digH1Raw[0];
00130     digH2=(digH2Raw[1]<<8)|digH2Raw[0];
00131     digH3=digH3Raw[0];
00132     digH4=(digH4Raw[1]<<4)|(digH4Raw[0] & 0x0F);
00133     digH5=(4>>(digH5Raw[1] & 0xF0))|(digH5Raw[0]<<4);
00134     digH6=digH6Raw[0];
00135 }
00136 
00137 void BME280::getTrimValuesPressure(){
00138     // Data Container for Trim Values Pressure
00139     uint8_t digP1Raw[2];
00140     uint8_t digP2Raw[2];
00141     uint8_t digP3Raw[2];
00142     uint8_t digP4Raw[2];
00143     uint8_t digP5Raw[2];
00144     uint8_t digP6Raw[2];
00145     uint8_t digP7Raw[2];
00146     uint8_t digP8Raw[2];
00147     uint8_t digP9Raw[2];
00148 
00149     // Get the Trim parameters for the exact calculation of the Pressure
00150     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP1_LSB,0,&digP1Raw[0],1);
00151     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP1_MSB,0,&digP1Raw[1],1);
00152     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP2_LSB,0,&digP2Raw[0],1);
00153     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP2_MSB,0,&digP2Raw[1],1);
00154     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP3_LSB,0,&digP3Raw[0],1);
00155     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP3_MSB,0,&digP3Raw[1],1);
00156     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP4_LSB,0,&digP4Raw[0],1);
00157     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP4_MSB,0,&digP4Raw[1],1);
00158     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP5_LSB,0,&digP5Raw[0],1);
00159     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP5_MSB,0,&digP5Raw[1],1);
00160     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP6_LSB,0,&digP6Raw[0],1);
00161     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP6_MSB,0,&digP6Raw[1],1);
00162     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP7_LSB,0,&digP7Raw[0],1);
00163     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP7_MSB,0,&digP7Raw[1],1);
00164     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP8_LSB,0,&digP8Raw[0],1);
00165     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP8_MSB,0,&digP8Raw[1],1);
00166     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP9_LSB,0,&digP9Raw[0],1);
00167     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP9_MSB,0,&digP9Raw[1],1);
00168 
00169     // Convert data into values
00170     digP1=(digP1Raw[1]<<8)|digP1Raw[0];
00171     digP2=(digP2Raw[1]<<8)|digP2Raw[0];
00172     digP3=(digP3Raw[1]<<8)|digP3Raw[0];
00173     digP4=(digP4Raw[1]<<8)|digP4Raw[0];
00174     digP5=(digP5Raw[1]<<8)|digP5Raw[0];
00175     digP6=(digP6Raw[1]<<8)|digP6Raw[0];
00176     digP7=(digP7Raw[1]<<8)|digP7Raw[0];
00177     digP8=(digP8Raw[1]<<8)|digP8Raw[0];
00178     digP9=(digP9Raw[1]<<8)|digP9Raw[0];
00179 }
00180 
00181 void BME280::getTrimValuesTemperature(){
00182     // Data Container for Trim Values Temperature
00183     uint8_t digT1Raw[2];
00184     uint8_t digT2Raw[2];
00185     uint8_t digT3Raw[2];
00186 
00187     // Get the Trim parameters for the exact calculation of the Temperature
00188     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT1_LSB,0,&digT1Raw[0],1);
00189     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT1_MSB,0,&digT1Raw[1],1);
00190     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT2_LSB,0,&digT2Raw[0],1);
00191     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT2_MSB,0,&digT2Raw[1],1);
00192     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT3_LSB,0,&digT3Raw[0],1);
00193     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT3_MSB,0,&digT3Raw[1],1);
00194 
00195     // Convert data into values
00196     digT1=(digT1Raw[1]<<8)|digT1Raw[0];
00197     digT2=(digT2Raw[1]<<8)|digT2Raw[0];
00198     digT3=(digT3Raw[1]<<8)|digT3Raw[0];
00199 
00200 }
00201 
00202 void BME280::setWeatherMonitoringMode(){
00203     uint8_t configuration_1 = BME280_WHEAT_OVRS_T_P;
00204     uint8_t configuration_2 = BME280_WHEAT_OVRS_H;
00205 
00206     i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_HUM,false,&configuration_2,1);
00207     i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,&configuration_1,1);
00208 
00209 }
00210 
00211 void BME280::setOversamplingTemperature(){
00212     uint8_t oldRegisterValue;
00213     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
00214             &oldRegisterValue,1);
00215 
00216     uint8_t oversamplingTemperature = config->getOversamplingTemperature();
00217     uint8_t registerValue = (oversamplingTemperature << 5) | oldRegisterValue;
00218     i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
00219             &registerValue,1);
00220 }
00221 
00222 void BME280::setOversamplingPressure(){
00223     uint8_t oldRegisterValue;
00224     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
00225             &oldRegisterValue,1);
00226 
00227     uint8_t oversamplingPressure = config->getOversamplingPressure();
00228     uint8_t registerValue = (oversamplingPressure << 2) | oldRegisterValue;
00229     i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
00230             &registerValue,1);
00231 }
00232 
00233 void BME280::setOversamplingHumidity(){
00234     uint8_t oldRegisterValue;
00235     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_HUM,false,
00236             &oldRegisterValue,1);
00237 
00238     uint8_t oversamplingHumidity = config->getOversamplingHumidity();
00239     uint8_t newRegisterValue = oversamplingHumidity|oldRegisterValue;
00240     i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_HUM,false,
00241             &newRegisterValue,1);
00242 }
00243 
00244 void BME280::setMode(){
00245     uint8_t oldRegisterValue;
00246     i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
00247             &oldRegisterValue,1);
00248 
00249     uint8_t mode = config->getMode();
00250     uint8_t registerValue = mode | oldRegisterValue;
00251     i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
00252                 &registerValue,1);
00253 }
00254 
00255 int32_t BME280::compensateHumidity(int32_t adc_H,int32_t temp_fine)
00256 {
00257     int32_t v_x1_u32r;
00258 
00259     v_x1_u32r =  temp_fine - ((int32_t)76800);
00260 
00261     v_x1_u32r = (((((adc_H << 14) - (((int32_t)digH4) << 20) - (((int32_t)digH5) * v_x1_u32r)) +
00262             ((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)digH6)) >> 10) * (((v_x1_u32r *
00263                     ((int32_t)digH3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
00264                     ((int32_t)digH2) + 8192) >> 14));
00265 
00266     v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)digH1)) >> 4));
00267     v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
00268     v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
00269 
00270     return (int32_t)(v_x1_u32r>>12);
00271 }
00272 
00273 int64_t BME280::compensatePressure(int32_t adc_P, int32_t temp_fine)
00274 {
00275     int64_t var1, var2, p;
00276     var1 = ((int64_t)temp_fine) - 128000;
00277     var2 = var1 * var1 * (int64_t)digP6;
00278     var2 = var2 + ((var1*(int64_t)digP5)<<17);
00279     var2 = var2 + (((int64_t)digP4)<<35);
00280     var1 = ((var1 * var1 * (int64_t)digP3)>>8) + ((var1 * (int64_t)digP2)<<12);
00281     var1 = (((((int64_t)1)<<47)+var1))*((int64_t)digP1)>>33;
00282     if (var1 == 0)
00283     {
00284         return 0; // avoid exception caused by division by zero
00285     }
00286     p = ((int64_t)1048576)-adc_P;
00287     p = (((p<<31)-var2)*((int64_t)3125))/var1;
00288     var1 = (((int64_t)digP9) * (p>>13) * (p>>13)) >> 25;
00289     var2 = (((int64_t)digP8) * p) >> 19;
00290     p = ((p + var1 + var2) >> 8) + (((int64_t)digP7)<<4);
00291     return (int32_t)p;
00292 }
00293 
00294 int32_t BME280::compensateTemperature(int32_t adc_T)
00295 {
00296     int32_t var1, var2, T;
00297     var1  = ((((adc_T>>3) - ((int32_t)digT1<<1))) * ((int32_t)digT2)) >> 11;
00298     var2  = (((((adc_T>>4) - ((int32_t)digT1)) * ((adc_T>>4) - ((int32_t)digT1))) >> 12) *
00299             ((int32_t)digT3)) >> 14;
00300     int32_t t_fine = var1 + var2;
00301     T  = (t_fine * 5 + 128) >> 8;
00302     return T;
00303 }