![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
nRF51822, BME280, SSD1306_i2c, BLE400
Dependencies: mbed SSD1306_128x64_I2C
bme280.cpp@0:6e40dd247a04, 2019-11-28 (annotated)
- 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?
User | Revision | Line number | New 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(®,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(®,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(®,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 */ |