Bosch BME280 Temperature Pressure Humidity Sensor I2C driver
BME280.cpp@7:9a1b27d03c97, 2017-04-24 (annotated)
- Committer:
- jenschn
- Date:
- Mon Apr 24 13:08:32 2017 +0000
- Revision:
- 7:9a1b27d03c97
- Parent:
- 6:c5a78f81ddda
small bug fixed
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jenschn | 0:6b0de3ad5900 | 1 | /***************************************************************************** |
jenschn | 0:6b0de3ad5900 | 2 | * * |
jenschn | 1:d766e0ac711f | 3 | * BOSCH BME208 Temperature Pressure Humidity Sensor Driver / I2C * |
jenschn | 0:6b0de3ad5900 | 4 | * * |
jenschn | 0:6b0de3ad5900 | 5 | * (c) 2015 Jens Schneider * |
jenschn | 0:6b0de3ad5900 | 6 | * mailto:jens.schneider@kaust.edu.sa * |
jenschn | 0:6b0de3ad5900 | 7 | * Visual Computing Center (VCC) * |
jenschn | 0:6b0de3ad5900 | 8 | * King Abdullah University of Science and Technology (KAUST) * |
jenschn | 0:6b0de3ad5900 | 9 | * 4700 Thuwal, Kingdom of Saudi Arabia * |
jenschn | 0:6b0de3ad5900 | 10 | * * |
jenschn | 0:6b0de3ad5900 | 11 | * PERMISSION GRANTED TO USE IN NON-COMMERCIAL AND EDUCATIONAL PROJECTS * |
jenschn | 0:6b0de3ad5900 | 12 | * NO RESPONSIBILITY ASSUMED FOR DAMAGE OR LOSS OF ANY HARDWARE OR SOFTWARE * |
jenschn | 0:6b0de3ad5900 | 13 | * * |
jenschn | 0:6b0de3ad5900 | 14 | * version 0.1 * |
jenschn | 0:6b0de3ad5900 | 15 | * last change 07.Nov.2015 * |
jenschn | 0:6b0de3ad5900 | 16 | * * |
jenschn | 0:6b0de3ad5900 | 17 | *****************************************************************************/ |
jenschn | 0:6b0de3ad5900 | 18 | #include"BME280.h" |
jenschn | 0:6b0de3ad5900 | 19 | |
jenschn | 0:6b0de3ad5900 | 20 | const uint8_t BME280::REG_HUM_LSB = 0xFE; |
jenschn | 0:6b0de3ad5900 | 21 | const uint8_t BME280::REG_HUM_MSB = 0xFD; |
jenschn | 0:6b0de3ad5900 | 22 | const uint8_t BME280::REG_TEMP_XLSB = 0xFC; |
jenschn | 0:6b0de3ad5900 | 23 | const uint8_t BME280::REG_TEMP_LSB = 0xFB; |
jenschn | 0:6b0de3ad5900 | 24 | const uint8_t BME280::REG_TEMP_MSB = 0xFA; |
jenschn | 0:6b0de3ad5900 | 25 | const uint8_t BME280::REG_PRESS_XLSB = 0xF9; |
jenschn | 0:6b0de3ad5900 | 26 | const uint8_t BME280::REG_PRESS_LSB = 0xF8; |
jenschn | 0:6b0de3ad5900 | 27 | const uint8_t BME280::REG_PRESS_MSB = 0xF7; |
jenschn | 0:6b0de3ad5900 | 28 | |
jenschn | 0:6b0de3ad5900 | 29 | const uint8_t BME280::REG_CONFIG = 0xF5; |
jenschn | 0:6b0de3ad5900 | 30 | const uint8_t BME280::REG_CTRL_MEAS = 0xF4; |
jenschn | 7:9a1b27d03c97 | 31 | const uint8_t BME280::REG_STATUS = 0xF3; |
jenschn | 7:9a1b27d03c97 | 32 | const uint8_t BME280::REG_CTRL_HUM = 0xF2; |
jenschn | 0:6b0de3ad5900 | 33 | const uint8_t BME280::REG_CALIB26_41_BASE = 0xE1; |
jenschn | 0:6b0de3ad5900 | 34 | const uint8_t BME280::REG_RESET = 0xE0; |
jenschn | 0:6b0de3ad5900 | 35 | const uint8_t BME280::REG_ID = 0xD0; |
jenschn | 0:6b0de3ad5900 | 36 | const uint8_t BME280::REG_CALIB00_25_BASE = 0x88; |
jenschn | 0:6b0de3ad5900 | 37 | |
jenschn | 0:6b0de3ad5900 | 38 | const uint8_t BME280::VAL_CALIB26_41_SIZE = 0x10; |
jenschn | 0:6b0de3ad5900 | 39 | const uint8_t BME280::VAL_CALIB00_25_SIZE = 0x1A; |
jenschn | 0:6b0de3ad5900 | 40 | const uint8_t BME280::VAL_CHIP_ID = 0x60; |
jenschn | 0:6b0de3ad5900 | 41 | const uint8_t BME280::VAL_RESET = 0xB6; |
jenschn | 0:6b0de3ad5900 | 42 | |
jenschn | 0:6b0de3ad5900 | 43 | const uint8_t BME280::STATUS_IDLE = 0x00; |
jenschn | 0:6b0de3ad5900 | 44 | const uint8_t BME280::STATUS_MEASURING = 0x08; |
jenschn | 0:6b0de3ad5900 | 45 | const uint8_t BME280::STATUS_UPDATING = 0x01; |
jenschn | 0:6b0de3ad5900 | 46 | const uint8_t BME280::STATUS_ERROR = 0xFF; |
jenschn | 0:6b0de3ad5900 | 47 | |
jenschn | 3:b3835216cc88 | 48 | const std::string BME280::m_name = std::string("Bosch BME280"); |
jenschn | 0:6b0de3ad5900 | 49 | |
jenschn | 2:4ed2f08d0eff | 50 | BME280::BME280(void) : m_pI2C(NULL), m_address(0x00), m_fine_temp(0x1F3E6), m_mode(MODE_SLEEP),m_bOk(false) { |
jenschn | 0:6b0de3ad5900 | 51 | // initialized m_fine_temp to 25C |
jenschn | 0:6b0de3ad5900 | 52 | } |
jenschn | 0:6b0de3ad5900 | 53 | |
jenschn | 0:6b0de3ad5900 | 54 | BME280::~BME280(void) { |
jenschn | 0:6b0de3ad5900 | 55 | done(); |
jenschn | 0:6b0de3ad5900 | 56 | } |
jenschn | 0:6b0de3ad5900 | 57 | |
jenschn | 0:6b0de3ad5900 | 58 | bool BME280::init(I2C& i2c, uint8_t address) { |
jenschn | 2:4ed2f08d0eff | 59 | m_bOk = false; |
jenschn | 0:6b0de3ad5900 | 60 | m_pI2C = &i2c; |
jenschn | 0:6b0de3ad5900 | 61 | m_address = address<<1; |
jenschn | 0:6b0de3ad5900 | 62 | m_fine_temp = 0x1F3E6; |
jenschn | 5:8346aef10686 | 63 | if (!reset()) return false; |
jenschn | 5:8346aef10686 | 64 | if (read_chip_id()!=0x60) return false; |
jenschn | 5:8346aef10686 | 65 | if (!read_calibration()) return false; |
jenschn | 2:4ed2f08d0eff | 66 | m_bOk = true; |
jenschn | 0:6b0de3ad5900 | 67 | return true; |
jenschn | 0:6b0de3ad5900 | 68 | } |
jenschn | 0:6b0de3ad5900 | 69 | |
jenschn | 3:b3835216cc88 | 70 | const bool& BME280::is_ok(void) const { |
jenschn | 3:b3835216cc88 | 71 | return m_bOk; |
jenschn | 3:b3835216cc88 | 72 | } |
jenschn | 3:b3835216cc88 | 73 | |
jenschn | 0:6b0de3ad5900 | 74 | bool BME280::done(void) { |
jenschn | 0:6b0de3ad5900 | 75 | stop(); |
jenschn | 0:6b0de3ad5900 | 76 | m_pI2C = NULL; |
jenschn | 0:6b0de3ad5900 | 77 | m_address = 0x00; |
jenschn | 0:6b0de3ad5900 | 78 | m_mode = MODE_SLEEP; |
jenschn | 0:6b0de3ad5900 | 79 | return true; |
jenschn | 0:6b0de3ad5900 | 80 | } |
jenschn | 0:6b0de3ad5900 | 81 | |
jenschn | 0:6b0de3ad5900 | 82 | |
jenschn | 0:6b0de3ad5900 | 83 | bool BME280::start( BME280::sampling_t hum, |
jenschn | 0:6b0de3ad5900 | 84 | BME280::sampling_t temp, |
jenschn | 0:6b0de3ad5900 | 85 | BME280::sampling_t press, |
jenschn | 0:6b0de3ad5900 | 86 | BME280::standby_t standby, |
jenschn | 0:6b0de3ad5900 | 87 | BME280::filter_t filter, |
jenschn | 0:6b0de3ad5900 | 88 | BME280::mode_t mode) { |
jenschn | 0:6b0de3ad5900 | 89 | // 1. Reset |
jenschn | 0:6b0de3ad5900 | 90 | if (!reset()) return false; |
jenschn | 0:6b0de3ad5900 | 91 | |
jenschn | 0:6b0de3ad5900 | 92 | // 2. Write CONFIG |
jenschn | 0:6b0de3ad5900 | 93 | uint8_t val_cfg = uint8_t(standby)<<5; |
jenschn | 0:6b0de3ad5900 | 94 | val_cfg|=uint8_t(filter)<<2; |
jenschn | 0:6b0de3ad5900 | 95 | if (!write8(REG_CONFIG,val_cfg)) return false; |
jenschn | 0:6b0de3ad5900 | 96 | |
jenschn | 0:6b0de3ad5900 | 97 | // 3. Write CTRL_HUM |
jenschn | 0:6b0de3ad5900 | 98 | if (!write8(REG_CTRL_HUM,uint8_t(hum))) return false; |
jenschn | 0:6b0de3ad5900 | 99 | |
jenschn | 0:6b0de3ad5900 | 100 | // 4. Write CTRL_MEAS |
jenschn | 0:6b0de3ad5900 | 101 | uint8_t val_meas = uint8_t(temp)<<5; |
jenschn | 0:6b0de3ad5900 | 102 | val_meas |= uint8_t(press)<<2; |
jenschn | 0:6b0de3ad5900 | 103 | val_meas |= uint8_t(mode); |
jenschn | 0:6b0de3ad5900 | 104 | if (!write8(REG_CTRL_MEAS,val_meas)) return false; |
jenschn | 0:6b0de3ad5900 | 105 | |
jenschn | 0:6b0de3ad5900 | 106 | m_mode = mode; |
jenschn | 4:db58c1198a04 | 107 | m_bOk = true; |
jenschn | 0:6b0de3ad5900 | 108 | |
jenschn | 0:6b0de3ad5900 | 109 | return true; |
jenschn | 0:6b0de3ad5900 | 110 | } |
jenschn | 0:6b0de3ad5900 | 111 | |
jenschn | 0:6b0de3ad5900 | 112 | bool BME280::stop(void) { |
jenschn | 0:6b0de3ad5900 | 113 | return reset(); |
jenschn | 0:6b0de3ad5900 | 114 | } |
jenschn | 0:6b0de3ad5900 | 115 | |
jenschn | 0:6b0de3ad5900 | 116 | bool BME280::get(float& temperature, float& pressure, float& humidity) { |
jenschn | 0:6b0de3ad5900 | 117 | int32_t T; |
jenschn | 0:6b0de3ad5900 | 118 | uint32_t P, H; |
jenschn | 0:6b0de3ad5900 | 119 | if (!get(T,P,H)) return false; |
jenschn | 0:6b0de3ad5900 | 120 | temperature = float(T)*0.01f; // in degree C |
jenschn | 0:6b0de3ad5900 | 121 | pressure = 0.01f*(float(P)/256.0f); // in hPa / mbar |
jenschn | 0:6b0de3ad5900 | 122 | humidity = float(H)/1024.0f; // in % |
jenschn | 0:6b0de3ad5900 | 123 | return true; |
jenschn | 0:6b0de3ad5900 | 124 | } |
jenschn | 0:6b0de3ad5900 | 125 | |
jenschn | 0:6b0de3ad5900 | 126 | bool BME280::get(int32_t& temperature, uint32_t& pressure, uint32_t& humidity) { |
jenschn | 0:6b0de3ad5900 | 127 | if (m_mode!=MODE_AUTO) { |
jenschn | 0:6b0de3ad5900 | 128 | // Trigger forced conversion by updating CTRL_MEAS register |
jenschn | 0:6b0de3ad5900 | 129 | uint8_t val = 0x00; |
jenschn | 0:6b0de3ad5900 | 130 | if (!read8(REG_CTRL_MEAS,val)) return false; |
jenschn | 0:6b0de3ad5900 | 131 | val = (val&0xFC)|uint8_t(MODE_FORCED); |
jenschn | 0:6b0de3ad5900 | 132 | if (!write8(REG_CTRL_MEAS,val)) return false; |
jenschn | 0:6b0de3ad5900 | 133 | // Wait for measurement to finish |
jenschn | 0:6b0de3ad5900 | 134 | do { |
jenschn | 0:6b0de3ad5900 | 135 | val = read_status(); |
jenschn | 0:6b0de3ad5900 | 136 | if ((val&STATUS_MEASURING)!=0) wait_ms(1); |
jenschn | 0:6b0de3ad5900 | 137 | } while(val&STATUS_MEASURING); |
jenschn | 0:6b0de3ad5900 | 138 | } |
jenschn | 0:6b0de3ad5900 | 139 | int32_t rawT, rawP, rawH; |
jenschn | 0:6b0de3ad5900 | 140 | if (!raw_data(rawT,rawP,rawH)) return false; |
jenschn | 0:6b0de3ad5900 | 141 | temperature = compensate_T(rawT); |
jenschn | 0:6b0de3ad5900 | 142 | pressure = compensate_P(rawP); |
jenschn | 0:6b0de3ad5900 | 143 | humidity = compensate_H(rawH); |
jenschn | 0:6b0de3ad5900 | 144 | return true; |
jenschn | 0:6b0de3ad5900 | 145 | } |
jenschn | 0:6b0de3ad5900 | 146 | |
jenschn | 3:b3835216cc88 | 147 | const std::string& BME280::name(void) const { |
jenschn | 3:b3835216cc88 | 148 | return m_name; |
jenschn | 3:b3835216cc88 | 149 | } |
jenschn | 3:b3835216cc88 | 150 | |
jenschn | 0:6b0de3ad5900 | 151 | bool BME280::raw_data(int32_t& rawT, int32_t& rawP, int32_t& rawH) { |
jenschn | 0:6b0de3ad5900 | 152 | if (m_pI2C==NULL) return false; |
jenschn | 0:6b0de3ad5900 | 153 | uint8_t data[8]; |
jenschn | 2:4ed2f08d0eff | 154 | if (!burst_read(data,8,REG_PRESS_MSB)) { |
jenschn | 2:4ed2f08d0eff | 155 | rawT = rawP = rawH = 0; |
jenschn | 0:6b0de3ad5900 | 156 | return false; |
jenschn | 2:4ed2f08d0eff | 157 | } |
jenschn | 0:6b0de3ad5900 | 158 | rawP = (int32_t(data[0])<<12)|(int32_t(data[1])<<4)|(int32_t(data[2])>>4); |
jenschn | 0:6b0de3ad5900 | 159 | rawT = (int32_t(data[3])<<12)|(int32_t(data[4])<<4)|(int32_t(data[5])>>4); |
jenschn | 0:6b0de3ad5900 | 160 | rawH = (int32_t(data[6])<<8)|int32_t(data[7]); |
jenschn | 0:6b0de3ad5900 | 161 | return true; |
jenschn | 0:6b0de3ad5900 | 162 | } |
jenschn | 0:6b0de3ad5900 | 163 | |
jenschn | 0:6b0de3ad5900 | 164 | |
jenschn | 0:6b0de3ad5900 | 165 | int16_t BME280::conv_s16(const uint8_t* data, int lo, int hi) const { |
jenschn | 0:6b0de3ad5900 | 166 | return int16_t(uint16_t(data[lo])|(uint16_t(data[hi])<<8)); |
jenschn | 0:6b0de3ad5900 | 167 | } |
jenschn | 0:6b0de3ad5900 | 168 | |
jenschn | 0:6b0de3ad5900 | 169 | uint16_t BME280::conv_u16(const uint8_t* data, int lo, int hi) const { |
jenschn | 0:6b0de3ad5900 | 170 | return uint16_t(data[lo])|(uint16_t(data[hi])<<8); |
jenschn | 0:6b0de3ad5900 | 171 | } |
jenschn | 0:6b0de3ad5900 | 172 | |
jenschn | 0:6b0de3ad5900 | 173 | bool BME280::read_calibration(void) { |
jenschn | 0:6b0de3ad5900 | 174 | if (m_pI2C==NULL) return false; |
jenschn | 0:6b0de3ad5900 | 175 | return read_calibration_lo() && read_calibration_hi(); |
jenschn | 0:6b0de3ad5900 | 176 | } |
jenschn | 0:6b0de3ad5900 | 177 | |
jenschn | 0:6b0de3ad5900 | 178 | bool BME280::read_calibration_lo(void) { |
jenschn | 2:4ed2f08d0eff | 179 | if (m_pI2C==NULL) return false; |
jenschn | 0:6b0de3ad5900 | 180 | uint8_t data[VAL_CALIB00_25_SIZE]; |
jenschn | 2:4ed2f08d0eff | 181 | if (!burst_read(data,VAL_CALIB00_25_SIZE,REG_CALIB00_25_BASE)) return false; |
jenschn | 0:6b0de3ad5900 | 182 | m_calib.dig_T1 = conv_u16(data,0,1); // 0x88:89 |
jenschn | 0:6b0de3ad5900 | 183 | m_calib.dig_T2 = conv_s16(data,2,3); // 0x8A:8B |
jenschn | 0:6b0de3ad5900 | 184 | m_calib.dig_T3 = conv_s16(data,4,5); // 0x8C:8D |
jenschn | 0:6b0de3ad5900 | 185 | m_calib.dig_P1 = conv_u16(data,6,7); // 0x8E:8F |
jenschn | 0:6b0de3ad5900 | 186 | m_calib.dig_P2 = conv_s16(data,8,9); // 0x90:91 |
jenschn | 0:6b0de3ad5900 | 187 | m_calib.dig_P3 = conv_s16(data,10,11); // 0x92:93 |
jenschn | 0:6b0de3ad5900 | 188 | m_calib.dig_P4 = conv_s16(data,12,13); // 0x94:95 |
jenschn | 0:6b0de3ad5900 | 189 | m_calib.dig_P5 = conv_s16(data,14,15); // 0x96:97 |
jenschn | 0:6b0de3ad5900 | 190 | m_calib.dig_P6 = conv_s16(data,16,17); // 0x98:99 |
jenschn | 0:6b0de3ad5900 | 191 | m_calib.dig_P7 = conv_s16(data,18,19); // 0x9A:9B |
jenschn | 0:6b0de3ad5900 | 192 | m_calib.dig_P8 = conv_s16(data,20,21); // 0x9C:9D |
jenschn | 0:6b0de3ad5900 | 193 | m_calib.dig_P9 = conv_s16(data,22,23); // 0x9E:9F |
jenschn | 0:6b0de3ad5900 | 194 | // 0xA0 |
jenschn | 0:6b0de3ad5900 | 195 | m_calib.dig_H1 = data[25]; // 0xA1 |
jenschn | 0:6b0de3ad5900 | 196 | return true; |
jenschn | 0:6b0de3ad5900 | 197 | } |
jenschn | 0:6b0de3ad5900 | 198 | |
jenschn | 0:6b0de3ad5900 | 199 | bool BME280::read_calibration_hi(void) { |
jenschn | 2:4ed2f08d0eff | 200 | if (m_pI2C==NULL) return false; |
jenschn | 0:6b0de3ad5900 | 201 | uint8_t data[VAL_CALIB26_41_SIZE]; |
jenschn | 2:4ed2f08d0eff | 202 | if (!burst_read(data,VAL_CALIB26_41_SIZE,REG_CALIB26_41_BASE)) return false; |
jenschn | 0:6b0de3ad5900 | 203 | m_calib.dig_H2 = conv_s16(data,0,1); // 0xE1:E2 |
jenschn | 0:6b0de3ad5900 | 204 | m_calib.dig_H3 = data[2]; // 0xE3 |
jenschn | 0:6b0de3ad5900 | 205 | m_calib.dig_H4 = int16_t((uint16_t(data[3])<<8)|uint16_t((data[4]&0xF)<<4))>>4; // 0xE4:E5[3:0] |
jenschn | 0:6b0de3ad5900 | 206 | m_calib.dig_H5 = int16_t((uint16_t(data[5])<<8)|uint16_t((data[4]&0xF0))>>4); // 0xE5[7:4]:E6 |
jenschn | 0:6b0de3ad5900 | 207 | m_calib.dig_H6 = int8_t(data[6]); // 0xE7 |
jenschn | 0:6b0de3ad5900 | 208 | return true; |
jenschn | 0:6b0de3ad5900 | 209 | } |
jenschn | 0:6b0de3ad5900 | 210 | |
jenschn | 0:6b0de3ad5900 | 211 | int32_t BME280::compensate_T(int32_t raw_T) { |
jenschn | 0:6b0de3ad5900 | 212 | int32_t var1, var2, T; |
jenschn | 0:6b0de3ad5900 | 213 | var1 = ((((raw_T>>3) - ((int32_t)m_calib.dig_T1<<1))) * ((int32_t)m_calib.dig_T2)) >> 11; |
jenschn | 0:6b0de3ad5900 | 214 | var2 = (((((raw_T>>4) - ((int32_t)m_calib.dig_T1)) * ((raw_T>>4) - ((int32_t)m_calib.dig_T1))) >> 12) * ((int32_t)m_calib.dig_T3)) >> 14; |
jenschn | 0:6b0de3ad5900 | 215 | m_fine_temp = var1 + var2; |
jenschn | 0:6b0de3ad5900 | 216 | T = (m_fine_temp * 5 + 128) >> 8; |
jenschn | 0:6b0de3ad5900 | 217 | return T; |
jenschn | 0:6b0de3ad5900 | 218 | } |
jenschn | 0:6b0de3ad5900 | 219 | |
jenschn | 0:6b0de3ad5900 | 220 | uint32_t BME280::compensate_P(int32_t raw_P) { |
jenschn | 0:6b0de3ad5900 | 221 | int64_t var1, var2, p; |
jenschn | 0:6b0de3ad5900 | 222 | var1 = ((int64_t)m_fine_temp) - 128000; |
jenschn | 0:6b0de3ad5900 | 223 | var2 = var1 * var1 * (int64_t)m_calib.dig_P6; |
jenschn | 0:6b0de3ad5900 | 224 | var2 = var2 + ((var1*(int64_t)m_calib.dig_P5)<<17); |
jenschn | 0:6b0de3ad5900 | 225 | var2 = var2 + (((int64_t)m_calib.dig_P4)<<35); |
jenschn | 0:6b0de3ad5900 | 226 | var1 = ((var1 * var1 * (int64_t)m_calib.dig_P3)>>8) + ((var1 * (int64_t)m_calib.dig_P2)<<12); |
jenschn | 0:6b0de3ad5900 | 227 | var1 = (((((int64_t)1)<<47)+var1))*((int64_t)m_calib.dig_P1)>>33; |
jenschn | 0:6b0de3ad5900 | 228 | if (var1 == 0) return false; // avoid division by zero |
jenschn | 0:6b0de3ad5900 | 229 | p = 1048576-raw_P; |
jenschn | 0:6b0de3ad5900 | 230 | p = (((p<<31)-var2)*3125)/var1; |
jenschn | 0:6b0de3ad5900 | 231 | var1 = (((int64_t)m_calib.dig_P9) * (p>>13) * (p>>13)) >> 25; |
jenschn | 0:6b0de3ad5900 | 232 | var2 = (((int64_t)m_calib.dig_P8) * p) >> 19; |
jenschn | 0:6b0de3ad5900 | 233 | p = ((p + var1 + var2) >> 8) + (((int64_t)m_calib.dig_P7)<<4); |
jenschn | 0:6b0de3ad5900 | 234 | return (uint32_t)p; |
jenschn | 0:6b0de3ad5900 | 235 | } |
jenschn | 0:6b0de3ad5900 | 236 | |
jenschn | 0:6b0de3ad5900 | 237 | uint32_t BME280::compensate_H(int32_t raw_H) { |
jenschn | 0:6b0de3ad5900 | 238 | int32_t v_x1_u32r; |
jenschn | 0:6b0de3ad5900 | 239 | v_x1_u32r = (m_fine_temp - ((int32_t)76800)); |
jenschn | 0:6b0de3ad5900 | 240 | v_x1_u32r = (((((raw_H << 14) - (((int32_t)m_calib.dig_H4) << 20) - (((int32_t)m_calib.dig_H5) * v_x1_u32r)) + |
jenschn | 0:6b0de3ad5900 | 241 | ((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)m_calib.dig_H6)) >> 10) * (((v_x1_u32r * |
jenschn | 0:6b0de3ad5900 | 242 | ((int32_t)m_calib.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + ((int32_t)2097152)) * |
jenschn | 0:6b0de3ad5900 | 243 | ((int32_t)m_calib.dig_H2) + 8192) >> 14)); |
jenschn | 0:6b0de3ad5900 | 244 | v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int32_t)m_calib.dig_H1)) >> 4)); |
jenschn | 0:6b0de3ad5900 | 245 | v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r); |
jenschn | 0:6b0de3ad5900 | 246 | v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r); |
jenschn | 0:6b0de3ad5900 | 247 | return (uint32_t)(v_x1_u32r>>12); |
jenschn | 0:6b0de3ad5900 | 248 | } |
jenschn | 0:6b0de3ad5900 | 249 | |
jenschn | 0:6b0de3ad5900 | 250 | // ======================================== LOW LEVEL API ======================================== |
jenschn | 0:6b0de3ad5900 | 251 | bool BME280::reset(void) { |
jenschn | 2:4ed2f08d0eff | 252 | m_bOk = false; |
jenschn | 0:6b0de3ad5900 | 253 | if (write8(REG_RESET,VAL_RESET)) { |
jenschn | 0:6b0de3ad5900 | 254 | wait_ms(2); |
jenschn | 0:6b0de3ad5900 | 255 | m_mode = MODE_SLEEP; |
jenschn | 0:6b0de3ad5900 | 256 | return true; |
jenschn | 0:6b0de3ad5900 | 257 | } |
jenschn | 0:6b0de3ad5900 | 258 | return false; |
jenschn | 0:6b0de3ad5900 | 259 | } |
jenschn | 0:6b0de3ad5900 | 260 | |
jenschn | 0:6b0de3ad5900 | 261 | uint8_t BME280::read_chip_id(void) { |
jenschn | 0:6b0de3ad5900 | 262 | uint8_t result; |
jenschn | 0:6b0de3ad5900 | 263 | if (read8(REG_ID,result)) return result; |
jenschn | 0:6b0de3ad5900 | 264 | else return 0x00; |
jenschn | 0:6b0de3ad5900 | 265 | } |
jenschn | 0:6b0de3ad5900 | 266 | |
jenschn | 0:6b0de3ad5900 | 267 | uint8_t BME280::read_status(void) { |
jenschn | 0:6b0de3ad5900 | 268 | uint8_t result; |
jenschn | 0:6b0de3ad5900 | 269 | if (read8(REG_STATUS,result)) return result&0x9; |
jenschn | 0:6b0de3ad5900 | 270 | else return STATUS_ERROR; |
jenschn | 0:6b0de3ad5900 | 271 | } |
jenschn | 0:6b0de3ad5900 | 272 | |
jenschn | 0:6b0de3ad5900 | 273 | bool BME280::read8(uint8_t reg, uint8_t& val) { |
jenschn | 0:6b0de3ad5900 | 274 | if (m_pI2C==NULL) return false; |
jenschn | 0:6b0de3ad5900 | 275 | uint8_t ok = 0x00; |
jenschn | 0:6b0de3ad5900 | 276 | val = 0x00; |
jenschn | 0:6b0de3ad5900 | 277 | m_pI2C->start(); |
jenschn | 0:6b0de3ad5900 | 278 | ok = (ok<<1)|m_pI2C->write(m_address); |
jenschn | 0:6b0de3ad5900 | 279 | ok = (ok<<1)|m_pI2C->write(reg); |
jenschn | 0:6b0de3ad5900 | 280 | m_pI2C->start(); |
jenschn | 0:6b0de3ad5900 | 281 | ok = (ok<<1)|m_pI2C->write(m_address|1); |
jenschn | 0:6b0de3ad5900 | 282 | val = m_pI2C->read(0); |
jenschn | 0:6b0de3ad5900 | 283 | m_pI2C->stop(); |
jenschn | 0:6b0de3ad5900 | 284 | return ok==0x7; |
jenschn | 0:6b0de3ad5900 | 285 | } |
jenschn | 0:6b0de3ad5900 | 286 | |
jenschn | 0:6b0de3ad5900 | 287 | bool BME280::write8(uint8_t reg, uint8_t val) { |
jenschn | 0:6b0de3ad5900 | 288 | if (m_pI2C==NULL) return false; |
jenschn | 0:6b0de3ad5900 | 289 | uint8_t ok = 0x00; |
jenschn | 0:6b0de3ad5900 | 290 | m_pI2C->start(); |
jenschn | 0:6b0de3ad5900 | 291 | ok = (ok<<1)|m_pI2C->write(m_address); |
jenschn | 0:6b0de3ad5900 | 292 | ok = (ok<<1)|m_pI2C->write(reg); |
jenschn | 0:6b0de3ad5900 | 293 | ok = (ok<<1)|m_pI2C->write(val); |
jenschn | 0:6b0de3ad5900 | 294 | m_pI2C->stop(); |
jenschn | 0:6b0de3ad5900 | 295 | return ok==0x7; |
jenschn | 0:6b0de3ad5900 | 296 | } |
jenschn | 0:6b0de3ad5900 | 297 | |
jenschn | 0:6b0de3ad5900 | 298 | const BME280::calib_t& BME280::calib(void) const { |
jenschn | 0:6b0de3ad5900 | 299 | return m_calib; |
jenschn | 2:4ed2f08d0eff | 300 | } |
jenschn | 2:4ed2f08d0eff | 301 | |
jenschn | 2:4ed2f08d0eff | 302 | bool BME280::burst_read(uint8_t* data, uint8_t nBytes, uint8_t reg) { |
jenschn | 2:4ed2f08d0eff | 303 | if (m_pI2C==NULL) return false; |
jenschn | 2:4ed2f08d0eff | 304 | if (nBytes==0) return false; |
jenschn | 2:4ed2f08d0eff | 305 | if (data==NULL) return false; |
jenschn | 2:4ed2f08d0eff | 306 | uint8_t ok = 0x00; |
jenschn | 2:4ed2f08d0eff | 307 | m_pI2C->start(); |
jenschn | 2:4ed2f08d0eff | 308 | ok = (ok<<1)|m_pI2C->write(m_address); |
jenschn | 2:4ed2f08d0eff | 309 | ok = (ok<<1)|m_pI2C->write(reg); |
jenschn | 2:4ed2f08d0eff | 310 | m_pI2C->start(); |
jenschn | 2:4ed2f08d0eff | 311 | ok = (ok<<1)|m_pI2C->write(m_address|1); |
jenschn | 2:4ed2f08d0eff | 312 | for (int i=0; i<nBytes-1; i++) data[i] = m_pI2C->read(1); |
jenschn | 2:4ed2f08d0eff | 313 | data[nBytes-1] = m_pI2C->read(0); |
jenschn | 2:4ed2f08d0eff | 314 | m_pI2C->stop(); |
jenschn | 2:4ed2f08d0eff | 315 | if (ok!=0x7) { |
jenschn | 2:4ed2f08d0eff | 316 | memset(data,0,nBytes); |
jenschn | 2:4ed2f08d0eff | 317 | return false; |
jenschn | 2:4ed2f08d0eff | 318 | } |
jenschn | 2:4ed2f08d0eff | 319 | return true; |
jenschn | 0:6b0de3ad5900 | 320 | } |