nRF51822, BME280, SSD1306_i2c, BLE400

Dependencies:   mbed SSD1306_128x64_I2C

Committer:
mamont090671
Date:
Thu Nov 28 11:43:48 2019 +0000
Revision:
0:6e40dd247a04
BME280, nRF51822, SSD1306_i2c, BLE400;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mamont090671 0:6e40dd247a04 1 /*
mamont090671 0:6e40dd247a04 2 bme280.cpp - driver for Bosch Sensortec BME280 combined humidity and pressure sensor.
mamont090671 0:6e40dd247a04 3
mamont090671 0:6e40dd247a04 4 Copyright (c) 2015 Elektor
mamont090671 0:6e40dd247a04 5
mamont090671 0:6e40dd247a04 6 26/11/2015 - CPV, Initial release.
mamont090671 0:6e40dd247a04 7
mamont090671 0:6e40dd247a04 8 This library is free software; you can redistribute it and/or
mamont090671 0:6e40dd247a04 9 modify it under the terms of the GNU Lesser General Public
mamont090671 0:6e40dd247a04 10 License as published by the Free Software Foundation; either
mamont090671 0:6e40dd247a04 11 version 2.1 of the License, or (at your option) any later version.
mamont090671 0:6e40dd247a04 12
mamont090671 0:6e40dd247a04 13 This library is distributed in the hope that it will be useful,
mamont090671 0:6e40dd247a04 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
mamont090671 0:6e40dd247a04 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
mamont090671 0:6e40dd247a04 16 Lesser General Public License for more details.
mamont090671 0:6e40dd247a04 17
mamont090671 0:6e40dd247a04 18 You should have received a copy of the GNU Lesser General
mamont090671 0:6e40dd247a04 19 Public License along with this library; if not, write to the
mamont090671 0:6e40dd247a04 20 Free Software Foundation, Inc., 59 Temple Place, Suite 330,
mamont090671 0:6e40dd247a04 21 Boston, MA 02111-1307 USA
mamont090671 0:6e40dd247a04 22
mamont090671 0:6e40dd247a04 23 */
mamont090671 0:6e40dd247a04 24
mamont090671 0:6e40dd247a04 25 #include "bme280.h"
mamont090671 0:6e40dd247a04 26
mamont090671 0:6e40dd247a04 27
mamont090671 0:6e40dd247a04 28 BME280::BME280(void)
mamont090671 0:6e40dd247a04 29 {
mamont090671 0:6e40dd247a04 30 _i2c_address = 0;
mamont090671 0:6e40dd247a04 31 _t_fine = 0;
mamont090671 0:6e40dd247a04 32 _temperature = 0;
mamont090671 0:6e40dd247a04 33 _pressure = 0;
mamont090671 0:6e40dd247a04 34 _humidity = 0;
mamont090671 0:6e40dd247a04 35 clearCalibrationData();
mamont090671 0:6e40dd247a04 36 }
mamont090671 0:6e40dd247a04 37
mamont090671 0:6e40dd247a04 38
mamont090671 0:6e40dd247a04 39 void BME280::clearCalibrationData(void)
mamont090671 0:6e40dd247a04 40 {
mamont090671 0:6e40dd247a04 41 _dig_T1 = 0;
mamont090671 0:6e40dd247a04 42 _dig_T2 = 0;
mamont090671 0:6e40dd247a04 43 _dig_T3 = 0;
mamont090671 0:6e40dd247a04 44 _dig_P1 = 0;
mamont090671 0:6e40dd247a04 45 _dig_P2 = 0;
mamont090671 0:6e40dd247a04 46 _dig_P3 = 0;
mamont090671 0:6e40dd247a04 47 _dig_P4 = 0;
mamont090671 0:6e40dd247a04 48 _dig_P5 = 0;
mamont090671 0:6e40dd247a04 49 _dig_P6 = 0;
mamont090671 0:6e40dd247a04 50 _dig_P7 = 0;
mamont090671 0:6e40dd247a04 51 _dig_P8 = 0;
mamont090671 0:6e40dd247a04 52 _dig_P9 = 0;
mamont090671 0:6e40dd247a04 53 _dig_H1 = 0;
mamont090671 0:6e40dd247a04 54 _dig_H2 = 0;
mamont090671 0:6e40dd247a04 55 _dig_H3 = 0;
mamont090671 0:6e40dd247a04 56 _dig_H4 = 0;
mamont090671 0:6e40dd247a04 57 _dig_H5 = 0;
mamont090671 0:6e40dd247a04 58 _dig_H6 = 0;
mamont090671 0:6e40dd247a04 59 }
mamont090671 0:6e40dd247a04 60
mamont090671 0:6e40dd247a04 61
mamont090671 0:6e40dd247a04 62 uint8_t BME280::begin(uint8_t i2cAddress)
mamont090671 0:6e40dd247a04 63 {
mamont090671 0:6e40dd247a04 64 _i2c_address = i2cAddress;
mamont090671 0:6e40dd247a04 65 if (readId()==BME280_ID)
mamont090671 0:6e40dd247a04 66 {
mamont090671 0:6e40dd247a04 67 clearCalibrationData();
mamont090671 0:6e40dd247a04 68 readCalibrationData();
mamont090671 0:6e40dd247a04 69 return 0;
mamont090671 0:6e40dd247a04 70 }
mamont090671 0:6e40dd247a04 71 return (uint8_t)-1;
mamont090671 0:6e40dd247a04 72 }
mamont090671 0:6e40dd247a04 73
mamont090671 0:6e40dd247a04 74
mamont090671 0:6e40dd247a04 75 void BME280::busWrite(uint8_t *p_data, uint8_t data_size, uint8_t repeated_start)
mamont090671 0:6e40dd247a04 76 {
mamont090671 0:6e40dd247a04 77 if (_i2c_address==BME280_I2C_ADDRESS1 || _i2c_address==BME280_I2C_ADDRESS2)
mamont090671 0:6e40dd247a04 78 {
mamont090671 0:6e40dd247a04 79 // Assume I2C bus.
mamont090671 0:6e40dd247a04 80 i2cWrite(_i2c_address,p_data,data_size,repeated_start);
mamont090671 0:6e40dd247a04 81 }
mamont090671 0:6e40dd247a04 82 /* else
mamont090671 0:6e40dd247a04 83 {
mamont090671 0:6e40dd247a04 84 // Assume SPI bus.
mamont090671 0:6e40dd247a04 85 // First byte is supposed to be the address of the register to write to, set R/~W bit to 0.
mamont090671 0:6e40dd247a04 86 p_data[0] &= 0x7f;
mamont090671 0:6e40dd247a04 87 spiWrite(p_data,data_size);
mamont090671 0:6e40dd247a04 88 }*/
mamont090671 0:6e40dd247a04 89 }
mamont090671 0:6e40dd247a04 90
mamont090671 0:6e40dd247a04 91
mamont090671 0:6e40dd247a04 92 void BME280::busRead(uint8_t *p_data, uint8_t data_size)
mamont090671 0:6e40dd247a04 93 {
mamont090671 0:6e40dd247a04 94 if (_i2c_address==BME280_I2C_ADDRESS1 || _i2c_address==BME280_I2C_ADDRESS2)
mamont090671 0:6e40dd247a04 95 {
mamont090671 0:6e40dd247a04 96 // Assume I2C bus.
mamont090671 0:6e40dd247a04 97 i2cRead(_i2c_address,p_data,data_size);
mamont090671 0:6e40dd247a04 98 }
mamont090671 0:6e40dd247a04 99 /** else
mamont090671 0:6e40dd247a04 100 {
mamont090671 0:6e40dd247a04 101 // Assume SPI bus.
mamont090671 0:6e40dd247a04 102 // First byte is supposed to be the address of the register to write to, set R/~W bit to 1.
mamont090671 0:6e40dd247a04 103 p_data[0] |= 0x80;
mamont090671 0:6e40dd247a04 104 spiRead(p_data,data_size);
mamont090671 0:6e40dd247a04 105 }**/
mamont090671 0:6e40dd247a04 106 }
mamont090671 0:6e40dd247a04 107
mamont090671 0:6e40dd247a04 108
mamont090671 0:6e40dd247a04 109 uint8_t BME280::readUint8(uint8_t reg)
mamont090671 0:6e40dd247a04 110 {
mamont090671 0:6e40dd247a04 111 uint8_t data;
mamont090671 0:6e40dd247a04 112 busWrite(&reg,1,1); // Use repeated start.
mamont090671 0:6e40dd247a04 113 busRead(&data,1); // Read one byte.
mamont090671 0:6e40dd247a04 114 return data;
mamont090671 0:6e40dd247a04 115 }
mamont090671 0:6e40dd247a04 116
mamont090671 0:6e40dd247a04 117
mamont090671 0:6e40dd247a04 118 uint16_t BME280::readUint16(uint8_t reg)
mamont090671 0:6e40dd247a04 119 {
mamont090671 0:6e40dd247a04 120 uint8_t data[2];
mamont090671 0:6e40dd247a04 121 uint16_t value;
mamont090671 0:6e40dd247a04 122 busWrite(&reg,1,1); // Use repeated start.
mamont090671 0:6e40dd247a04 123 busRead(data,2); // Read two bytes.
mamont090671 0:6e40dd247a04 124 // Process as little endian, which is the case for calibration data.
mamont090671 0:6e40dd247a04 125 value = data[1];
mamont090671 0:6e40dd247a04 126 value = (value<<8) | data[0];
mamont090671 0:6e40dd247a04 127 return value;
mamont090671 0:6e40dd247a04 128 }
mamont090671 0:6e40dd247a04 129
mamont090671 0:6e40dd247a04 130
mamont090671 0:6e40dd247a04 131 void BME280::readCalibrationData(void)
mamont090671 0:6e40dd247a04 132 {
mamont090671 0:6e40dd247a04 133 _dig_T1 = readUint16(BME280_CAL_T1);
mamont090671 0:6e40dd247a04 134 _dig_T2 = (int16_t) readUint16(BME280_CAL_T2);
mamont090671 0:6e40dd247a04 135 _dig_T3 = (int16_t) readUint16(BME280_CAL_T3);
mamont090671 0:6e40dd247a04 136 _dig_P1 = readUint16(BME280_CAL_P1);
mamont090671 0:6e40dd247a04 137 _dig_P2 = (int16_t) readUint16(BME280_CAL_P2);
mamont090671 0:6e40dd247a04 138 _dig_P3 = (int16_t) readUint16(BME280_CAL_P3);
mamont090671 0:6e40dd247a04 139 _dig_P4 = (int16_t) readUint16(BME280_CAL_P4);
mamont090671 0:6e40dd247a04 140 _dig_P5 = (int16_t) readUint16(BME280_CAL_P5);
mamont090671 0:6e40dd247a04 141 _dig_P6 = (int16_t) readUint16(BME280_CAL_P6);
mamont090671 0:6e40dd247a04 142 _dig_P7 = (int16_t) readUint16(BME280_CAL_P7);
mamont090671 0:6e40dd247a04 143 _dig_P8 = (int16_t) readUint16(BME280_CAL_P8);
mamont090671 0:6e40dd247a04 144 _dig_P9 = (int16_t) readUint16(BME280_CAL_P9);
mamont090671 0:6e40dd247a04 145 _dig_H1 = readUint8(BME280_CAL_H1);
mamont090671 0:6e40dd247a04 146 _dig_H2 = (int16_t) readUint16(BME280_CAL_H2);
mamont090671 0:6e40dd247a04 147 _dig_H3 = readUint8(BME280_CAL_H3);
mamont090671 0:6e40dd247a04 148 // H4 & H5 share a byte.
mamont090671 0:6e40dd247a04 149 uint8_t temp1 = readUint8(BME280_CAL_H4);
mamont090671 0:6e40dd247a04 150 uint8_t temp2 = readUint8(BME280_CAL_H45);
mamont090671 0:6e40dd247a04 151 uint8_t temp3 = readUint8(BME280_CAL_H5);
mamont090671 0:6e40dd247a04 152 _dig_H4 = (temp1<<4) | (temp2&0x0f);
mamont090671 0:6e40dd247a04 153 _dig_H5 = (temp3<<4) | (temp2>>4);
mamont090671 0:6e40dd247a04 154 _dig_H6 = (int8_t) readUint8(BME280_CAL_H6);
mamont090671 0:6e40dd247a04 155 }
mamont090671 0:6e40dd247a04 156
mamont090671 0:6e40dd247a04 157
mamont090671 0:6e40dd247a04 158 uint8_t BME280::readFrom(uint8_t reg, uint8_t data_size, uint8_t *p_data)
mamont090671 0:6e40dd247a04 159 {
mamont090671 0:6e40dd247a04 160 // Set start address to read from.
mamont090671 0:6e40dd247a04 161 busWrite(&reg,1,1); // Use repeated start.
mamont090671 0:6e40dd247a04 162 // Now read the requested number of bytes.
mamont090671 0:6e40dd247a04 163 busRead(p_data,data_size);
mamont090671 0:6e40dd247a04 164 return data_size;
mamont090671 0:6e40dd247a04 165 }
mamont090671 0:6e40dd247a04 166
mamont090671 0:6e40dd247a04 167
mamont090671 0:6e40dd247a04 168 void BME280::read(void)
mamont090671 0:6e40dd247a04 169 {
mamont090671 0:6e40dd247a04 170 // Get all the measurements in one burst (recommended).
mamont090671 0:6e40dd247a04 171 uint8_t data[BME280_MEASUREMENT_SIZE];
mamont090671 0:6e40dd247a04 172 readFrom(BME280_MEASUREMENT_REGISTER,BME280_MEASUREMENT_SIZE,data);
mamont090671 0:6e40dd247a04 173 // We assume Normal mode, so it is not necessary to reissue a Forced mode command here.
mamont090671 0:6e40dd247a04 174
mamont090671 0:6e40dd247a04 175 // Process data.
mamont090671 0:6e40dd247a04 176 int32_t p = assembleRawValue(&data[0],1);
mamont090671 0:6e40dd247a04 177 int32_t t = assembleRawValue(&data[3],1);
mamont090671 0:6e40dd247a04 178 int32_t h = assembleRawValue(&data[6],0);
mamont090671 0:6e40dd247a04 179
mamont090671 0:6e40dd247a04 180 _temperature = compensateTemperature(t); // First call this before calling the other compensate functions.
mamont090671 0:6e40dd247a04 181 _pressure = compensatePressure(p); // Uses value calculated by compensateTemperature.
mamont090671 0:6e40dd247a04 182 _humidity = compensateHumidity(h); // Uses value calculated by compensateTemperature.
mamont090671 0:6e40dd247a04 183 }
mamont090671 0:6e40dd247a04 184
mamont090671 0:6e40dd247a04 185
mamont090671 0:6e40dd247a04 186 int32_t BME280::assembleRawValue(uint8_t *p_data, uint8_t has_xlsb)
mamont090671 0:6e40dd247a04 187 {
mamont090671 0:6e40dd247a04 188 // Needed to decode sensor data.
mamont090671 0:6e40dd247a04 189 uint32_t value = p_data[0];
mamont090671 0:6e40dd247a04 190 value <<= 8;
mamont090671 0:6e40dd247a04 191 value |= p_data[1];
mamont090671 0:6e40dd247a04 192 if (has_xlsb!=0)
mamont090671 0:6e40dd247a04 193 {
mamont090671 0:6e40dd247a04 194 value <<= 4;
mamont090671 0:6e40dd247a04 195 value |= (p_data[2]>>4);
mamont090671 0:6e40dd247a04 196 }
mamont090671 0:6e40dd247a04 197 return (int32_t) value;
mamont090671 0:6e40dd247a04 198 }
mamont090671 0:6e40dd247a04 199
mamont090671 0:6e40dd247a04 200
mamont090671 0:6e40dd247a04 201 void BME280::writeControlRegisters(uint8_t osrs_t, uint8_t osrs_p, uint8_t osrs_h, uint8_t mode)
mamont090671 0:6e40dd247a04 202 {
mamont090671 0:6e40dd247a04 203 uint8_t data[2];
mamont090671 0:6e40dd247a04 204 data[0] = BME280_CTRL_HUM_REGISTER;
mamont090671 0:6e40dd247a04 205 data[1] = (osrs_h&0x07);
mamont090671 0:6e40dd247a04 206 busWrite(data,2,0);
mamont090671 0:6e40dd247a04 207 // Writing CTRL_MEAS validates previous write to CTRL_HUM.
mamont090671 0:6e40dd247a04 208 data[0] = BME280_CTRL_MEAS_REGISTER;
mamont090671 0:6e40dd247a04 209 data[1] = ((osrs_t&0x07)<<5) | ((osrs_p&0x07)<<2) | (mode&0x03);
mamont090671 0:6e40dd247a04 210 busWrite(data,2,0);
mamont090671 0:6e40dd247a04 211 }
mamont090671 0:6e40dd247a04 212
mamont090671 0:6e40dd247a04 213
mamont090671 0:6e40dd247a04 214 void BME280::writeConfigRegister(uint8_t t_sb, uint8_t filter, uint8_t spi)
mamont090671 0:6e40dd247a04 215 {
mamont090671 0:6e40dd247a04 216 uint8_t data[2];
mamont090671 0:6e40dd247a04 217 data[0] = BME280_CONFIG_REGISTER;
mamont090671 0:6e40dd247a04 218 data[1] = ((t_sb&0x07)<<5) | ((filter&0x07)<<2) | (spi&0x01);
mamont090671 0:6e40dd247a04 219 busWrite(data,2,0);
mamont090671 0:6e40dd247a04 220 }
mamont090671 0:6e40dd247a04 221
mamont090671 0:6e40dd247a04 222
mamont090671 0:6e40dd247a04 223 void BME280::reset(void)
mamont090671 0:6e40dd247a04 224 {
mamont090671 0:6e40dd247a04 225 uint8_t data[2] = { BME280_RESET_REGISTER, BME280_RESET };
mamont090671 0:6e40dd247a04 226 busWrite(data,2,0);
mamont090671 0:6e40dd247a04 227 }
mamont090671 0:6e40dd247a04 228
mamont090671 0:6e40dd247a04 229
mamont090671 0:6e40dd247a04 230 uint8_t BME280::readId(void)
mamont090671 0:6e40dd247a04 231 {
mamont090671 0:6e40dd247a04 232 return readUint8(BME280_ID_REGISTER);
mamont090671 0:6e40dd247a04 233 }
mamont090671 0:6e40dd247a04 234
mamont090671 0:6e40dd247a04 235
mamont090671 0:6e40dd247a04 236 #if BME280_ALLOW_FLOAT!=0
mamont090671 0:6e40dd247a04 237
mamont090671 0:6e40dd247a04 238 // From the driver by Bosch Sensortec
mamont090671 0:6e40dd247a04 239
mamont090671 0:6e40dd247a04 240 //!
mamont090671 0:6e40dd247a04 241 // @brief Reads actual temperature from uncompensated temperature
mamont090671 0:6e40dd247a04 242 // @note returns the value in Degree centigrade
mamont090671 0:6e40dd247a04 243 // @note Output value of "51.23" equals 51.23 DegC.
mamont090671 0:6e40dd247a04 244 //
mamont090671 0:6e40dd247a04 245 // @param adc_T : value of uncompensated temperature
mamont090671 0:6e40dd247a04 246 //
mamont090671 0:6e40dd247a04 247 // @return Return the actual temperature in floating point
mamont090671 0:6e40dd247a04 248 //
mamont090671 0:6e40dd247a04 249 temperature_t BME280::compensateTemperature(int32_t adc_T)
mamont090671 0:6e40dd247a04 250 {
mamont090671 0:6e40dd247a04 251 double v_x1_u32;
mamont090671 0:6e40dd247a04 252 double v_x2_u32;
mamont090671 0:6e40dd247a04 253 double temperature;
mamont090671 0:6e40dd247a04 254
mamont090671 0:6e40dd247a04 255 v_x1_u32 = (((double)adc_T) / 16384.0 - ((double)_dig_T1) / 1024.0) * ((double)_dig_T2);
mamont090671 0:6e40dd247a04 256 v_x2_u32 = ((((double)adc_T) / 131072.0 - ((double)_dig_T1) / 8192.0) * (((double)adc_T) / 131072.0 - ((double)_dig_T1) / 8192.0)) * ((double)_dig_T3);
mamont090671 0:6e40dd247a04 257 _t_fine = (int32_t)(v_x1_u32 + v_x2_u32);
mamont090671 0:6e40dd247a04 258 temperature = (v_x1_u32 + v_x2_u32) / 5120.0;
mamont090671 0:6e40dd247a04 259 return temperature;
mamont090671 0:6e40dd247a04 260 }
mamont090671 0:6e40dd247a04 261
mamont090671 0:6e40dd247a04 262
mamont090671 0:6e40dd247a04 263 //!
mamont090671 0:6e40dd247a04 264 // @brief Reads actual pressure from uncompensated pressure
mamont090671 0:6e40dd247a04 265 // @note Returns pressure in Pa as double.
mamont090671 0:6e40dd247a04 266 // @note Output value of "96386.2"
mamont090671 0:6e40dd247a04 267 // equals 96386.2 Pa = 963.862 hPa.
mamont090671 0:6e40dd247a04 268 //
mamont090671 0:6e40dd247a04 269 // @param adc_P : value of uncompensated pressure
mamont090671 0:6e40dd247a04 270 //
mamont090671 0:6e40dd247a04 271 // @return Return the actual pressure in floating point
mamont090671 0:6e40dd247a04 272 //
mamont090671 0:6e40dd247a04 273 pressure_t BME280::compensatePressure(int32_t adc_P)
mamont090671 0:6e40dd247a04 274 {
mamont090671 0:6e40dd247a04 275 double v_x1_u32;
mamont090671 0:6e40dd247a04 276 double v_x2_u32;
mamont090671 0:6e40dd247a04 277 double pressure;
mamont090671 0:6e40dd247a04 278
mamont090671 0:6e40dd247a04 279 v_x1_u32 = ((double)_t_fine / 2.0) - 64000.0;
mamont090671 0:6e40dd247a04 280 v_x2_u32 = v_x1_u32 * v_x1_u32 * ((double)_dig_P6) / 32768.0;
mamont090671 0:6e40dd247a04 281 v_x2_u32 = v_x2_u32 + v_x1_u32 * ((double)_dig_P5) * 2.0;
mamont090671 0:6e40dd247a04 282 v_x2_u32 = (v_x2_u32 / 4.0) + (((double)_dig_P4) * 65536.0);
mamont090671 0:6e40dd247a04 283 v_x1_u32 = (((double)_dig_P3) * v_x1_u32 * v_x1_u32 / 524288.0 + ((double)_dig_P2) * v_x1_u32) / 524288.0;
mamont090671 0:6e40dd247a04 284 v_x1_u32 = (1.0 + v_x1_u32 / 32768.0) * ((double)_dig_P1);
mamont090671 0:6e40dd247a04 285 pressure = 1048576.0 - (double)adc_P;
mamont090671 0:6e40dd247a04 286 // Avoid exception caused by division by zero.
mamont090671 0:6e40dd247a04 287 if (v_x1_u32 != 0) pressure = (pressure - (v_x2_u32 / 4096.0)) * 6250.0 / v_x1_u32;
mamont090671 0:6e40dd247a04 288 else return 0;
mamont090671 0:6e40dd247a04 289 v_x1_u32 = ((double)_dig_P9) * pressure * pressure / 2147483648.0;
mamont090671 0:6e40dd247a04 290 v_x2_u32 = pressure * ((double)_dig_P8) / 32768.0;
mamont090671 0:6e40dd247a04 291 pressure = pressure + (v_x1_u32 + v_x2_u32 + ((double)_dig_P7)) / 16.0;
mamont090671 0:6e40dd247a04 292
mamont090671 0:6e40dd247a04 293 return pressure;
mamont090671 0:6e40dd247a04 294 }
mamont090671 0:6e40dd247a04 295
mamont090671 0:6e40dd247a04 296
mamont090671 0:6e40dd247a04 297 //!
mamont090671 0:6e40dd247a04 298 // @brief Reads actual humidity from uncompensated humidity
mamont090671 0:6e40dd247a04 299 // @note returns the value in relative humidity (%rH)
mamont090671 0:6e40dd247a04 300 // @note Output value of "42.12" equals 42.12 %rH
mamont090671 0:6e40dd247a04 301 //
mamont090671 0:6e40dd247a04 302 // @param adc_H : value of uncompensated humidity
mamont090671 0:6e40dd247a04 303 //
mamont090671 0:6e40dd247a04 304 // @return Return the actual humidity in floating point
mamont090671 0:6e40dd247a04 305 //
mamont090671 0:6e40dd247a04 306 humidity_t BME280::compensateHumidity(int32_t adc_H)
mamont090671 0:6e40dd247a04 307 {
mamont090671 0:6e40dd247a04 308 double var_h;
mamont090671 0:6e40dd247a04 309
mamont090671 0:6e40dd247a04 310 var_h = (((double)_t_fine) - 76800.0);
mamont090671 0:6e40dd247a04 311 if (var_h != 0)
mamont090671 0:6e40dd247a04 312 {
mamont090671 0:6e40dd247a04 313 var_h = (adc_H - (((double)_dig_H4) * 64.0 + ((double)_dig_H5) / 16384.0 * var_h)) *
mamont090671 0:6e40dd247a04 314 (((double)_dig_H2) / 65536.0 * (1.0 + ((double) _dig_H6) / 67108864.0 *
mamont090671 0:6e40dd247a04 315 var_h * (1.0 + ((double)_dig_H3) / 67108864.0 * var_h)));
mamont090671 0:6e40dd247a04 316 }
mamont090671 0:6e40dd247a04 317 else return 0;
mamont090671 0:6e40dd247a04 318 var_h = var_h * (1.0 - ((double)_dig_H1)*var_h / 524288.0);
mamont090671 0:6e40dd247a04 319 if (var_h > 100.0) var_h = 100.0;
mamont090671 0:6e40dd247a04 320 else if (var_h < 0.0) var_h = 0.0;
mamont090671 0:6e40dd247a04 321 return var_h;
mamont090671 0:6e40dd247a04 322 }
mamont090671 0:6e40dd247a04 323
mamont090671 0:6e40dd247a04 324 #else /* BME280_ALLOW_FLOAT */
mamont090671 0:6e40dd247a04 325
mamont090671 0:6e40dd247a04 326 // From the datasheet.
mamont090671 0:6e40dd247a04 327 // Returns temperature in DegC, resolution is 0.01 DegC. Output value of 5123 equals 51.23 DegC.
mamont090671 0:6e40dd247a04 328 // _t_fine carries fine temperature as "global" value.
mamont090671 0:6e40dd247a04 329 temperature_t BME280::compensateTemperature(int32_t adc_T)
mamont090671 0:6e40dd247a04 330 {
mamont090671 0:6e40dd247a04 331 int32_t var1, var2, T;
mamont090671 0:6e40dd247a04 332 var1 = ((((adc_T>>3) - ((int32_t)_dig_T1<<1))) * ((int32_t)_dig_T2)) >> 11;
mamont090671 0:6e40dd247a04 333 var2 = (((((adc_T>>4) - ((int32_t)_dig_T1)) * ((adc_T>>4) - ((int32_t)_dig_T1))) >> 12) * ((int32_t)_dig_T3)) >> 14;
mamont090671 0:6e40dd247a04 334 _t_fine = var1 + var2;
mamont090671 0:6e40dd247a04 335 T = (_t_fine * 5 + 128) >> 8;
mamont090671 0:6e40dd247a04 336 return T;
mamont090671 0:6e40dd247a04 337 }
mamont090671 0:6e40dd247a04 338
mamont090671 0:6e40dd247a04 339
mamont090671 0:6e40dd247a04 340 // From the datasheet.
mamont090671 0:6e40dd247a04 341 // Returns pressure in Pa as unsigned 32 bit integer. Output value of 96386 equals 96386 Pa = 963.86 hPa
mamont090671 0:6e40dd247a04 342 pressure_t BME280::compensatePressure(int32_t adc_P)
mamont090671 0:6e40dd247a04 343 {
mamont090671 0:6e40dd247a04 344 int32_t var1, var2;
mamont090671 0:6e40dd247a04 345 uint32_t p;
mamont090671 0:6e40dd247a04 346 var1 = (((int32_t)_t_fine)>>1) - (int32_t)64000;
mamont090671 0:6e40dd247a04 347 var2 = (((var1>>2) * (var1>>2)) >> 11 ) * ((int32_t)_dig_P6);
mamont090671 0:6e40dd247a04 348 var2 = var2 + ((var1*((int32_t)_dig_P5))<<1);
mamont090671 0:6e40dd247a04 349 var2 = (var2>>2)+(((int32_t)_dig_P4)<<16);
mamont090671 0:6e40dd247a04 350 var1 = (((_dig_P3 * (((var1>>2) * (var1>>2)) >> 13 )) >> 3) + ((((int32_t)_dig_P2) * var1)>>1))>>18;
mamont090671 0:6e40dd247a04 351 var1 =((((32768+var1))*((int32_t)_dig_P1))>>15);
mamont090671 0:6e40dd247a04 352 if (var1 == 0)
mamont090671 0:6e40dd247a04 353 {
mamont090671 0:6e40dd247a04 354 return 0; // avoid exception caused by division by zero
mamont090671 0:6e40dd247a04 355 }
mamont090671 0:6e40dd247a04 356 p = (((uint32_t)(((int32_t)1048576)-adc_P)-(var2>>12)))*3125;
mamont090671 0:6e40dd247a04 357 if (p < 0x80000000)
mamont090671 0:6e40dd247a04 358 {
mamont090671 0:6e40dd247a04 359 p = (p << 1) / ((uint32_t)var1);
mamont090671 0:6e40dd247a04 360 }
mamont090671 0:6e40dd247a04 361 else
mamont090671 0:6e40dd247a04 362 {
mamont090671 0:6e40dd247a04 363 p = (p / (uint32_t)var1) * 2;
mamont090671 0:6e40dd247a04 364 }
mamont090671 0:6e40dd247a04 365 var1 = (((int32_t)_dig_P9) * ((int32_t)(((p>>3) * (p>>3))>>13)))>>12;
mamont090671 0:6e40dd247a04 366 var2 = (((int32_t)(p>>2)) * ((int32_t)_dig_P8))>>13;
mamont090671 0:6e40dd247a04 367 p = (uint32_t)((int32_t)p + ((var1 + var2 + _dig_P7) >> 4));
mamont090671 0:6e40dd247a04 368 return p;
mamont090671 0:6e40dd247a04 369 }
mamont090671 0:6e40dd247a04 370
mamont090671 0:6e40dd247a04 371
mamont090671 0:6e40dd247a04 372 // From the datasheet.
mamont090671 0:6e40dd247a04 373 // Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits).
mamont090671 0:6e40dd247a04 374 // Output value of 47445 represents 47445/1024 = 46.333 %RH
mamont090671 0:6e40dd247a04 375 humidity_t BME280::compensateHumidity(int32_t adc_H)
mamont090671 0:6e40dd247a04 376 {
mamont090671 0:6e40dd247a04 377 int32_t v_x1_u32r;
mamont090671 0:6e40dd247a04 378 v_x1_u32r = (_t_fine - ((int32_t)76800));
mamont090671 0:6e40dd247a04 379 v_x1_u32r = (((((adc_H << 14) - (((int32_t)_dig_H4) << 20) - (((int32_t)_dig_H5) * v_x1_u32r)) +
mamont090671 0:6e40dd247a04 380 ((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)_dig_H6)) >> 10) * (((v_x1_u32r *
mamont090671 0:6e40dd247a04 381 ((int32_t)_dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) *
mamont090671 0:6e40dd247a04 382 ((int32_t)_dig_H2) + 8192) >> 14));
mamont090671 0:6e40dd247a04 383 v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)_dig_H1)) >> 4));
mamont090671 0:6e40dd247a04 384 v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
mamont090671 0:6e40dd247a04 385 v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
mamont090671 0:6e40dd247a04 386 return (uint32_t)(v_x1_u32r>>12);
mamont090671 0:6e40dd247a04 387 }
mamont090671 0:6e40dd247a04 388
mamont090671 0:6e40dd247a04 389 #endif /* BME280_ALLOW_FLOAT */