Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mDot_LoRa_Sensornode_Flowmeter_impl mbed-rtos mbed
app/BME280.cpp
- Committer:
- mitea1
- Date:
- 2018-11-02
- Revision:
- 10:4051c38bf73f
- Parent:
- 7:87cbeafdba06
File content as of revision 10:4051c38bf73f:
/*
* BME280.cpp
*
* Created on: 18.05.2016
* Author: Adrian
*/
#include "BME280.h"
BME280::BME280(I2C_RT* i2c){
setI2C(i2c);
this->config = new BME280Config();
}
BME280::~BME280() {
// TODO Auto-generated destructor stub
}
void BME280::init(BME280_MODE desiredMode){
config->build(desiredMode);
setOversamplingHumidity();
setOversamplingTemperature();
setOversamplingPressure();
setMode();
getTrimValuesHumidity();
getTrimValuesPressure();
getTrimValuesTemperature();
}
void BME280::setI2C(I2C_RT* i2c_rt){
this->i2c = i2c_rt;
}
uint32_t BME280::getHumidity(){
// Data Containers
uint8_t msbRegisterData[1];
uint8_t lsbRegisterData[1];
i2c->read_RT(
BME280_SENSOR_ADDRESS,BME280_SENSOR_HUM_MSB,false,msbRegisterData,1);
i2c->read_RT(
BME280_SENSOR_ADDRESS,BME280_SENSOR_HUM_LSB,false,lsbRegisterData,1);
int32_t temp_fine = getTemperature();
int32_t humRaw = (int32_t) (msbRegisterData[0]<<8|lsbRegisterData[0]);
uint32_t hum_fine = this->compensateHumidity(humRaw,temp_fine);
return hum_fine;
}
float BME280::getHumidityFloat(){
return (float) getHumidity()/ 1024;
}
uint32_t BME280::getPressure(){
// Data Containers
uint8_t msbRegisterData[1];
uint8_t lsbRegisterData[1];
uint8_t xlsbRegisterData[1];
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_PRESS_MSB,false,msbRegisterData,1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_PRESS_LSB,false,lsbRegisterData,1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_PRESS_XLSB,false,xlsbRegisterData, 1);
int32_t temp_fine = getTemperature();
int32_t pressRaw = (int32_t) (msbRegisterData[0]<<12|lsbRegisterData[0]<<4|lsbRegisterData[0]);
uint32_t press_fine = compensatePressure(pressRaw,temp_fine);
return press_fine;
}
float BME280::getPressureFloat(){
return (float)getPressure()/256;
}
int32_t BME280::getTemperature(){
uint8_t msbRegisterData[1];
uint8_t lsbRegisterData[1];
uint8_t xlsbRegisterData[1];
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_TEMP_MSB,
false,msbRegisterData,1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_TEMP_LSB,
false,lsbRegisterData,1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_TEMP_XLSB,
false,xlsbRegisterData,1);
int32_t tempRaw = (int32_t) (msbRegisterData[0]<<12|lsbRegisterData[0]<<4|xlsbRegisterData[0]);
int32_t tempFine = compensateTemperature(tempRaw);
return tempFine;
}
float BME280::getTemperatureFloat(){
int32_t temperature = this->getTemperature();
return (float)(temperature)/100;
}
void BME280::getTrimValuesHumidity(){
// Data Container for Trim Values Humidity
uint8_t digH1Raw[1];
uint8_t digH2Raw[2];
uint8_t digH3Raw[1];
uint8_t digH4Raw[2];
uint8_t digH5Raw[2];
uint8_t digH6Raw[1];
// Get the Trim parameters for the exact calculation of the Humidity
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH1_LSB,0,&digH1Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH2_LSB,0,&digH2Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH2_MSB,0,&digH2Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH3_LSB,0,&digH3Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH4_LSB,0,&digH4Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH4_MSB,0,&digH4Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH5_LSB,0,&digH5Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH5_MSB,0,&digH5Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digH6_LSB,0,&digH6Raw[0],1);
// Convert data into values
digH1=digH1Raw[0];
digH2=(digH2Raw[1]<<8)|digH2Raw[0];
digH3=digH3Raw[0];
digH4=(digH4Raw[1]<<4)|(digH4Raw[0] & 0x0F);
digH5=(4>>(digH5Raw[1] & 0xF0))|(digH5Raw[0]<<4);
digH6=digH6Raw[0];
}
void BME280::getTrimValuesPressure(){
// Data Container for Trim Values Pressure
uint8_t digP1Raw[2];
uint8_t digP2Raw[2];
uint8_t digP3Raw[2];
uint8_t digP4Raw[2];
uint8_t digP5Raw[2];
uint8_t digP6Raw[2];
uint8_t digP7Raw[2];
uint8_t digP8Raw[2];
uint8_t digP9Raw[2];
// Get the Trim parameters for the exact calculation of the Pressure
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP1_LSB,0,&digP1Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP1_MSB,0,&digP1Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP2_LSB,0,&digP2Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP2_MSB,0,&digP2Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP3_LSB,0,&digP3Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP3_MSB,0,&digP3Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP4_LSB,0,&digP4Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP4_MSB,0,&digP4Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP5_LSB,0,&digP5Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP5_MSB,0,&digP5Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP6_LSB,0,&digP6Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP6_MSB,0,&digP6Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP7_LSB,0,&digP7Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP7_MSB,0,&digP7Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP8_LSB,0,&digP8Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP8_MSB,0,&digP8Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP9_LSB,0,&digP9Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digP9_MSB,0,&digP9Raw[1],1);
// Convert data into values
digP1=(digP1Raw[1]<<8)|digP1Raw[0];
digP2=(digP2Raw[1]<<8)|digP2Raw[0];
digP3=(digP3Raw[1]<<8)|digP3Raw[0];
digP4=(digP4Raw[1]<<8)|digP4Raw[0];
digP5=(digP5Raw[1]<<8)|digP5Raw[0];
digP6=(digP6Raw[1]<<8)|digP6Raw[0];
digP7=(digP7Raw[1]<<8)|digP7Raw[0];
digP8=(digP8Raw[1]<<8)|digP8Raw[0];
digP9=(digP9Raw[1]<<8)|digP9Raw[0];
}
void BME280::getTrimValuesTemperature(){
// Data Container for Trim Values Temperature
uint8_t digT1Raw[2];
uint8_t digT2Raw[2];
uint8_t digT3Raw[2];
// Get the Trim parameters for the exact calculation of the Temperature
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT1_LSB,0,&digT1Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT1_MSB,0,&digT1Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT2_LSB,0,&digT2Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT2_MSB,0,&digT2Raw[1],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT3_LSB,0,&digT3Raw[0],1);
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_digT3_MSB,0,&digT3Raw[1],1);
// Convert data into values
digT1=(digT1Raw[1]<<8)|digT1Raw[0];
digT2=(digT2Raw[1]<<8)|digT2Raw[0];
digT3=(digT3Raw[1]<<8)|digT3Raw[0];
}
void BME280::setWeatherMonitoringMode(){
uint8_t configuration_1 = BME280_WHEAT_OVRS_T_P;
uint8_t configuration_2 = BME280_WHEAT_OVRS_H;
i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_HUM,false,&configuration_2,1);
i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,&configuration_1,1);
}
void BME280::setOversamplingTemperature(){
uint8_t oldRegisterValue;
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
&oldRegisterValue,1);
uint8_t oversamplingTemperature = config->getOversamplingTemperature();
uint8_t registerValue = (oversamplingTemperature << 5) | oldRegisterValue;
i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
®isterValue,1);
}
void BME280::setOversamplingPressure(){
uint8_t oldRegisterValue;
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
&oldRegisterValue,1);
uint8_t oversamplingPressure = config->getOversamplingPressure();
uint8_t registerValue = (oversamplingPressure << 2) | oldRegisterValue;
i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
®isterValue,1);
}
void BME280::setOversamplingHumidity(){
uint8_t oldRegisterValue;
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_HUM,false,
&oldRegisterValue,1);
uint8_t oversamplingHumidity = config->getOversamplingHumidity();
uint8_t newRegisterValue = oversamplingHumidity|oldRegisterValue;
i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_HUM,false,
&newRegisterValue,1);
}
void BME280::setMode(){
uint8_t oldRegisterValue;
i2c->read_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
&oldRegisterValue,1);
uint8_t mode = config->getMode();
uint8_t registerValue = mode | oldRegisterValue;
i2c->write_RT(BME280_SENSOR_ADDRESS,BME280_SENSOR_CTRL_MEAS,false,
®isterValue,1);
}
int32_t BME280::compensateHumidity(int32_t adc_H,int32_t temp_fine)
{
int32_t v_x1_u32r;
v_x1_u32r = temp_fine - ((int32_t)76800);
v_x1_u32r = (((((adc_H << 14) - (((int32_t)digH4) << 20) - (((int32_t)digH5) * v_x1_u32r)) +
((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)digH6)) >> 10) * (((v_x1_u32r *
((int32_t)digH3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
((int32_t)digH2) + 8192) >> 14));
v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)digH1)) >> 4));
v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
return (int32_t)(v_x1_u32r>>12);
}
int64_t BME280::compensatePressure(int32_t adc_P, int32_t temp_fine)
{
int64_t var1, var2, p;
var1 = ((int64_t)temp_fine) - 128000;
var2 = var1 * var1 * (int64_t)digP6;
var2 = var2 + ((var1*(int64_t)digP5)<<17);
var2 = var2 + (((int64_t)digP4)<<35);
var1 = ((var1 * var1 * (int64_t)digP3)>>8) + ((var1 * (int64_t)digP2)<<12);
var1 = (((((int64_t)1)<<47)+var1))*((int64_t)digP1)>>33;
if (var1 == 0)
{
return 0; // avoid exception caused by division by zero
}
p = ((int64_t)1048576)-adc_P;
p = (((p<<31)-var2)*((int64_t)3125))/var1;
var1 = (((int64_t)digP9) * (p>>13) * (p>>13)) >> 25;
var2 = (((int64_t)digP8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)digP7)<<4);
return (int32_t)p;
}
int32_t BME280::compensateTemperature(int32_t adc_T)
{
int32_t var1, var2, T;
var1 = ((((adc_T>>3) - ((int32_t)digT1<<1))) * ((int32_t)digT2)) >> 11;
var2 = (((((adc_T>>4) - ((int32_t)digT1)) * ((adc_T>>4) - ((int32_t)digT1))) >> 12) *
((int32_t)digT3)) >> 14;
int32_t t_fine = var1 + var2;
T = (t_fine * 5 + 128) >> 8;
return T;
}