Multi environmental sensor

My version of the bme280 pressure, humidity and temperature sensor

Committer:
loopsva
Date:
Fri Apr 22 14:25:55 2016 +0000
Revision:
3:96075bee19f0
Parent:
0:40b4ebf843c6
Trying again to delete VEML60xx remenants

Who changed what in which revision?

UserRevisionLine numberNew contents of line
loopsva 0:40b4ebf843c6 1 // Borch BME280 Barometer, Humidity and Temperature sensor IC
loopsva 0:40b4ebf843c6 2
loopsva 0:40b4ebf843c6 3 #include "bme280.h"
loopsva 0:40b4ebf843c6 4
loopsva 0:40b4ebf843c6 5 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 6 // Constructor, to allow for user to select i2c address based on CSB pin
loopsva 0:40b4ebf843c6 7
loopsva 0:40b4ebf843c6 8 bme280::bme280(PinName sda, PinName scl, CSBpolarity CSBpin) : _i2c(sda, scl) {
loopsva 0:40b4ebf843c6 9 _i2c.frequency(400000);
loopsva 0:40b4ebf843c6 10 i2cWAddr = BME280_WADDR;
loopsva 0:40b4ebf843c6 11 i2cRAddr = BME280_RADDR;
loopsva 0:40b4ebf843c6 12 if(CSBpin == CSBpin_1) {
loopsva 0:40b4ebf843c6 13 i2cWAddr++;
loopsva 0:40b4ebf843c6 14 i2cWAddr++;
loopsva 0:40b4ebf843c6 15 i2cRAddr++;
loopsva 0:40b4ebf843c6 16 i2cRAddr++;
loopsva 0:40b4ebf843c6 17 }
loopsva 0:40b4ebf843c6 18 }
loopsva 0:40b4ebf843c6 19
loopsva 0:40b4ebf843c6 20 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 21 // deconstructor
loopsva 0:40b4ebf843c6 22
loopsva 0:40b4ebf843c6 23 bme280::~bme280() {
loopsva 0:40b4ebf843c6 24 }
loopsva 0:40b4ebf843c6 25
loopsva 0:40b4ebf843c6 26 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 27 // I2C start. Returns "ack" from slave
loopsva 0:40b4ebf843c6 28
loopsva 0:40b4ebf843c6 29 int bme280::_i2c_start(uint8_t i2c_addr) {
loopsva 0:40b4ebf843c6 30 int ack;
loopsva 0:40b4ebf843c6 31 _i2c.start();
loopsva 0:40b4ebf843c6 32 ack = _i2c_write(i2c_addr);
loopsva 0:40b4ebf843c6 33 return(ack);
loopsva 0:40b4ebf843c6 34 }
loopsva 0:40b4ebf843c6 35
loopsva 0:40b4ebf843c6 36 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 37 // I2C stop
loopsva 0:40b4ebf843c6 38
loopsva 0:40b4ebf843c6 39 void bme280::_i2c_stop() {
loopsva 0:40b4ebf843c6 40 _i2c.stop();
loopsva 0:40b4ebf843c6 41 }
loopsva 0:40b4ebf843c6 42
loopsva 0:40b4ebf843c6 43 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 44 // I2C write a byte. Returns "ack" from slave
loopsva 0:40b4ebf843c6 45
loopsva 0:40b4ebf843c6 46 uint8_t bme280::_i2c_write(uint8_t data) {
loopsva 0:40b4ebf843c6 47 int ack = _i2c.write(data);
loopsva 0:40b4ebf843c6 48 return(ack);
loopsva 0:40b4ebf843c6 49 }
loopsva 0:40b4ebf843c6 50
loopsva 0:40b4ebf843c6 51 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 52 // I2C read byte and sending ACK. Returns data byte.
loopsva 0:40b4ebf843c6 53
loopsva 0:40b4ebf843c6 54 uint8_t bme280::_i2c_readACK() {
loopsva 0:40b4ebf843c6 55 uint8_t rdata = _i2c.read(1);
loopsva 0:40b4ebf843c6 56 return(rdata);
loopsva 0:40b4ebf843c6 57 }
loopsva 0:40b4ebf843c6 58
loopsva 0:40b4ebf843c6 59 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 60 // I2C read byte and sending NACK. Returns data byte.
loopsva 0:40b4ebf843c6 61
loopsva 0:40b4ebf843c6 62 uint8_t bme280::_i2c_readNACK() {
loopsva 0:40b4ebf843c6 63 uint8_t rdata = _i2c.read(0);
loopsva 0:40b4ebf843c6 64 return(rdata);
loopsva 0:40b4ebf843c6 65 }
loopsva 0:40b4ebf843c6 66
loopsva 0:40b4ebf843c6 67 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 68 // Get BME280 ID register
loopsva 0:40b4ebf843c6 69
loopsva 0:40b4ebf843c6 70 uint8_t bme280::getBmeID() {
loopsva 0:40b4ebf843c6 71 #if defined BMEi2cLOWLEVEL
loopsva 0:40b4ebf843c6 72 _i2c_start(i2cWAddr);
loopsva 0:40b4ebf843c6 73 _i2c_write(BME280_CHIP_ID_REG);
loopsva 0:40b4ebf843c6 74 _i2c_start(i2cRAddr);
loopsva 0:40b4ebf843c6 75 uint8_t rdata = _i2c_readNACK();
loopsva 0:40b4ebf843c6 76 _i2c_stop();
loopsva 0:40b4ebf843c6 77 return(rdata);
loopsva 0:40b4ebf843c6 78 #else
loopsva 0:40b4ebf843c6 79 bme280Buffer[0] = BME280_CHIP_ID_REG;
loopsva 0:40b4ebf843c6 80 _i2c.write(i2cWAddr, bme280Buffer, 1, true);
loopsva 0:40b4ebf843c6 81 _i2c.read(i2cRAddr, bme280Buffer, 1, false);
loopsva 0:40b4ebf843c6 82 uint8_t rdata = bme280Buffer[0];
loopsva 0:40b4ebf843c6 83 return(bme280Buffer[0]);
loopsva 0:40b4ebf843c6 84 #endif
loopsva 0:40b4ebf843c6 85 }
loopsva 0:40b4ebf843c6 86
loopsva 0:40b4ebf843c6 87 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 88 // Soft reset the chip
loopsva 0:40b4ebf843c6 89
loopsva 0:40b4ebf843c6 90 uint8_t bme280::resetBme() {
loopsva 0:40b4ebf843c6 91 #if defined BMEi2cLOWLEVEL
loopsva 0:40b4ebf843c6 92 uint8_t rdata = _i2c_start(i2cWAddr);
loopsva 0:40b4ebf843c6 93 if(rdata) return(rdata);
loopsva 0:40b4ebf843c6 94 _i2c_write(BME280_RST_REG);
loopsva 0:40b4ebf843c6 95 _i2c_write(BME280_RESET_VALUE);
loopsva 0:40b4ebf843c6 96 _i2c_stop();
loopsva 0:40b4ebf843c6 97 #else
loopsva 0:40b4ebf843c6 98 bme280Buffer[0] = BME280_RST_REG;
loopsva 0:40b4ebf843c6 99 bme280Buffer[1] = BME280_RESET_VALUE;
loopsva 0:40b4ebf843c6 100 uint8_t rdata = _i2c.write(i2cWAddr, bme280Buffer, 2, false);
loopsva 0:40b4ebf843c6 101 #endif
loopsva 0:40b4ebf843c6 102 return(rdata);
loopsva 0:40b4ebf843c6 103 }
loopsva 0:40b4ebf843c6 104
loopsva 0:40b4ebf843c6 105 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 106 // Get BME280 status register. Returns register value
loopsva 0:40b4ebf843c6 107
loopsva 0:40b4ebf843c6 108 uint8_t bme280::getBmeStatus() {
loopsva 0:40b4ebf843c6 109 #if defined BMEi2cLOWLEVEL
loopsva 0:40b4ebf843c6 110 _i2c_start(i2cWAddr);
loopsva 0:40b4ebf843c6 111 _i2c_write(BME280_STAT_REG);
loopsva 0:40b4ebf843c6 112 _i2c_start(i2cRAddr);
loopsva 0:40b4ebf843c6 113 uint8_t rdata = _i2c_readNACK();
loopsva 0:40b4ebf843c6 114 _i2c_stop();
loopsva 0:40b4ebf843c6 115 return(rdata);
loopsva 0:40b4ebf843c6 116 #else
loopsva 0:40b4ebf843c6 117 bme280Buffer[0] = BME280_STAT_REG;
loopsva 0:40b4ebf843c6 118 _i2c.write(i2cWAddr, bme280Buffer, 1, true);
loopsva 0:40b4ebf843c6 119 _i2c.read(i2cRAddr, bme280Buffer, 1, false);
loopsva 0:40b4ebf843c6 120 return(bme280Buffer[0]);
loopsva 0:40b4ebf843c6 121 #endif
loopsva 0:40b4ebf843c6 122 }
loopsva 0:40b4ebf843c6 123
loopsva 0:40b4ebf843c6 124 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 125 // Get BME280 PTH values. Saves raw data is data structure. Returns 0 if successful, !0 if status was busy - pass thru from getBmeStatus();
loopsva 0:40b4ebf843c6 126
loopsva 0:40b4ebf843c6 127 uint8_t bme280::getBmeRawData(bme_data& bmed) {
loopsva 0:40b4ebf843c6 128 uint8_t rdata = getBmeStatus();
loopsva 0:40b4ebf843c6 129 if(rdata) return(rdata);
loopsva 0:40b4ebf843c6 130 bmed.raw_hum = 0;
loopsva 0:40b4ebf843c6 131 #if defined BMEi2cLOWLEVEL
loopsva 0:40b4ebf843c6 132 _i2c_start(i2cWAddr);
loopsva 0:40b4ebf843c6 133 _i2c_write(BME280_PRESSURE_MSB_REG);
loopsva 0:40b4ebf843c6 134 _i2c_start(i2cRAddr);
loopsva 0:40b4ebf843c6 135
loopsva 0:40b4ebf843c6 136 // MSB first LSB second XLSB third
loopsva 0:40b4ebf843c6 137 bmed.raw_baro = ((_i2c_readACK() << 12) | (_i2c_readACK() << 4) | (_i2c_readACK()));
loopsva 0:40b4ebf843c6 138 bmed.raw_temp = ((_i2c_readACK() << 12) | (_i2c_readACK() << 4) | (_i2c_readACK()));
loopsva 0:40b4ebf843c6 139 bmed.raw_hum = ((_i2c_readACK() << 8) | (_i2c_readNACK()));
loopsva 0:40b4ebf843c6 140 _i2c_stop();
loopsva 0:40b4ebf843c6 141 #else
loopsva 0:40b4ebf843c6 142 bme280Buffer[0] = BME280_PRESSURE_MSB_REG;
loopsva 0:40b4ebf843c6 143 _i2c.write(i2cWAddr, bme280Buffer, 1, true);
loopsva 0:40b4ebf843c6 144 _i2c.read(i2cRAddr, bme280Buffer, 8, false);
loopsva 0:40b4ebf843c6 145 // MSB first LSB second XLSB third
loopsva 0:40b4ebf843c6 146 bmed.raw_baro = ((bme280Buffer[0] << 12) | (bme280Buffer[1] << 4) | (bme280Buffer[2]));
loopsva 0:40b4ebf843c6 147 bmed.raw_temp = ((bme280Buffer[3] << 12) | (bme280Buffer[4] << 4) | (bme280Buffer[5]));
loopsva 0:40b4ebf843c6 148 bmed.raw_hum = ((bme280Buffer[6] << 8) | (bme280Buffer[7]));
loopsva 0:40b4ebf843c6 149 #endif
loopsva 0:40b4ebf843c6 150 return(0);
loopsva 0:40b4ebf843c6 151 }
loopsva 0:40b4ebf843c6 152
loopsva 0:40b4ebf843c6 153 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 154 //Convert BME280 PTH values. Takes raw data from data structure and applies calibration values to it.
loopsva 0:40b4ebf843c6 155
loopsva 0:40b4ebf843c6 156 void bme280::convertBmeRawData(bme_data& bmed, bme_cal& bmec) {
loopsva 0:40b4ebf843c6 157
loopsva 0:40b4ebf843c6 158 //Returns temperature in DegC, resolution is 0.01 DegC. Output value of “5123” equals 51.23 DegC.
loopsva 0:40b4ebf843c6 159 //t_fine carries fine temperature as global value
loopsva 0:40b4ebf843c6 160 int var1t = ((((bmed.raw_temp >> 3) - ((int)bmec.dig_T1 << 1))) * ((int)bmec.dig_T2)) >> 11;
loopsva 0:40b4ebf843c6 161 int var2t = (((((bmed.raw_temp >> 4) - ((int)bmec.dig_T1)) * ((bmed.raw_temp >> 4) - ((int)bmec.dig_T1))) >> 12) *
loopsva 0:40b4ebf843c6 162 ((int)bmec.dig_T3)) >> 14;
loopsva 0:40b4ebf843c6 163 bmec.t_fine = var1t + var2t;
loopsva 0:40b4ebf843c6 164 bmed.corr_temp = (bmec.t_fine * 5 + 128) >> 8;
loopsva 0:40b4ebf843c6 165 bmed.bme_temp = (double)bmed.corr_temp / 100.0;
loopsva 0:40b4ebf843c6 166
loopsva 0:40b4ebf843c6 167 //Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 fractional bits).
loopsva 0:40b4ebf843c6 168 //Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa
loopsva 0:40b4ebf843c6 169 int64_t var1p, var2p, p;
loopsva 0:40b4ebf843c6 170 var1p = ((int64_t)bmec.t_fine) - 128000;
loopsva 0:40b4ebf843c6 171 var2p = var1p * var1p * (int64_t)bmec.dig_P6;
loopsva 0:40b4ebf843c6 172 var2p = var2p + ((var1p * (int64_t)bmec.dig_P5) << 17);
loopsva 0:40b4ebf843c6 173 var2p = var2p + (((int64_t)bmec.dig_P4) << 35);
loopsva 0:40b4ebf843c6 174 var1p = ((var1p * var1p * (int64_t)bmec.dig_P3 )>> 8) + ((var1p * (int64_t)bmec.dig_P2) << 12);
loopsva 0:40b4ebf843c6 175 var1p = (((((int64_t)1) << 47) + var1p)) * ((int64_t)bmec.dig_P1) >> 33;
loopsva 0:40b4ebf843c6 176 if (var1p == 0) return; // avoid exception caused by division by zero
loopsva 0:40b4ebf843c6 177 p = 1048576 - bmed.raw_baro;
loopsva 0:40b4ebf843c6 178 p = (((p << 31) - var2p) * 3125)/var1p;
loopsva 0:40b4ebf843c6 179 var1p = (((int64_t)bmec.dig_P9) * (p >> 13) * (p >> 13)) >> 25;
loopsva 0:40b4ebf843c6 180 var2p = (((int64_t)bmec.dig_P8) * p) >> 19;
loopsva 0:40b4ebf843c6 181 p = ((p + var1p + var2p) >> 8) + (((int64_t)bmec.dig_P7) << 4);
loopsva 0:40b4ebf843c6 182 bmed.corr_baro = p >> 8;
loopsva 0:40b4ebf843c6 183 bmed.bme_baro = (double)bmed.corr_baro / 100.0;
loopsva 0:40b4ebf843c6 184
loopsva 0:40b4ebf843c6 185 //Returns humidity in %RH as unsigned 32 bit integer in Q22.10 format (22 integer and 10 fractional bits).
loopsva 0:40b4ebf843c6 186 //Output value of “47445” represents 47445/1024 = 46.333 %RH
loopsva 0:40b4ebf843c6 187 int v_x1_u32r = (bmec.t_fine - ((int)76800));
loopsva 0:40b4ebf843c6 188 v_x1_u32r = (((((bmed.raw_hum << 14) - (((int)bmec.dig_H4) << 20) - (((int)bmec.dig_H5) * v_x1_u32r)) +
loopsva 0:40b4ebf843c6 189 ((int)16384)) >> 15) * (((((((v_x1_u32r * ((int)bmec.dig_H6)) >> 10) * (((v_x1_u32r *
loopsva 0:40b4ebf843c6 190 ((int)bmec.dig_H3)) >> 11) + ((int)32768))) >> 10) + ((int)2097152)) *
loopsva 0:40b4ebf843c6 191 ((int)bmec.dig_H2) + 8192) >> 14));
loopsva 0:40b4ebf843c6 192 v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * ((int)bmec.dig_H1)) >> 4));
loopsva 0:40b4ebf843c6 193 v_x1_u32r = (v_x1_u32r < 0 ? 0 : v_x1_u32r);
loopsva 0:40b4ebf843c6 194 v_x1_u32r = (v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r);
loopsva 0:40b4ebf843c6 195 bmed.corr_hum = (uint32_t)(v_x1_u32r >> 12);
loopsva 0:40b4ebf843c6 196 bmed.bme_hum = (double)bmed.corr_hum / 1024.0; //was: / 1000.0
loopsva 0:40b4ebf843c6 197 }
loopsva 0:40b4ebf843c6 198
loopsva 0:40b4ebf843c6 199 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 200 //Convert BME280 PTH values. Takes raw data from data structure and applies calibration values to it.
loopsva 0:40b4ebf843c6 201 //Note: This is the floating point version.
loopsva 0:40b4ebf843c6 202
loopsva 0:40b4ebf843c6 203 void bme280::convertBmeRawDataFloat(bme_data& bmed, bme_cal& bmec) {
loopsva 0:40b4ebf843c6 204
loopsva 0:40b4ebf843c6 205 //Returns temperature in DegC, double precision. Output value of “51.23” equals 51.23 DegC.
loopsva 0:40b4ebf843c6 206 //t_fine carries fine temperature as global value
loopsva 0:40b4ebf843c6 207 double var1, var2;
loopsva 0:40b4ebf843c6 208 var1 = (((double)bmed.raw_temp) / 16384.0 - ((double)bmec.dig_T1) / 1024.0) * ((double)bmec.dig_T2);
loopsva 0:40b4ebf843c6 209 var2 = ((((double)bmed.raw_temp) / 131072.0 - ((double)bmec.dig_T1) / 8192.0) *
loopsva 0:40b4ebf843c6 210 (((double)bmed.raw_temp) / 131072.0 - ((double)bmec.dig_T1) / 8192.0)) * ((double)bmec.dig_T3);
loopsva 0:40b4ebf843c6 211 bmec.t_fine = (int)(var1 + var2);
loopsva 0:40b4ebf843c6 212 bmed.corr_temp = 0;
loopsva 0:40b4ebf843c6 213 bmed.bme_temp = (var1 + var2) / 5120.0;
loopsva 0:40b4ebf843c6 214
loopsva 0:40b4ebf843c6 215 //Returns pressure in Pa as double. Output value of “96386.2” equals 96386.2 Pa = 963.862 hPa
loopsva 0:40b4ebf843c6 216 double p;
loopsva 0:40b4ebf843c6 217 var1 = ((double)bmec.t_fine / 2.0) - 64000.0;
loopsva 0:40b4ebf843c6 218 var2 = var1 * var1 * ((double)bmec.dig_P6) / 32768.0;
loopsva 0:40b4ebf843c6 219 var2 = var2 + var1 * ((double)bmec.dig_P5) * 2.0;
loopsva 0:40b4ebf843c6 220 var2 = (var2 / 4.0)+(((double)bmec.dig_P4) * 65536.0);
loopsva 0:40b4ebf843c6 221 var1 = (((double)bmec.dig_P3) * var1 * var1 / 524288.0 + ((double)bmec.dig_P2) * var1) / 524288.0;
loopsva 0:40b4ebf843c6 222 var1 = (1.0 + var1 / 32768.0)*((double)bmec.dig_P1);
loopsva 0:40b4ebf843c6 223 if (var1 == 0.0) {
loopsva 0:40b4ebf843c6 224 bmed.corr_baro = 0;
loopsva 0:40b4ebf843c6 225 bmed.bme_baro = 0.0;
loopsva 0:40b4ebf843c6 226 return; //avoid exception caused by division by zero
loopsva 0:40b4ebf843c6 227 }
loopsva 0:40b4ebf843c6 228 p = 1048576.0 - (double)bmed.raw_baro;
loopsva 0:40b4ebf843c6 229 p = (p - (var2 / 4096.0)) * 6250.0 / var1;
loopsva 0:40b4ebf843c6 230 var1 = ((double)bmec.dig_P9) * p * p / 2147483648.0;
loopsva 0:40b4ebf843c6 231 var2 = p * ((double)bmec.dig_P8) / 32768.0;
loopsva 0:40b4ebf843c6 232 p = p + (var1 + var2 + ((double)bmec.dig_P7)) / 16.0;
loopsva 0:40b4ebf843c6 233 bmed.corr_baro = 0;
loopsva 0:40b4ebf843c6 234 bmed.bme_baro = p / 100.0;
loopsva 0:40b4ebf843c6 235
loopsva 0:40b4ebf843c6 236 //Returns humidity in %rH as as double. Output value of “46.332” represents 46.332 %rH
loopsva 0:40b4ebf843c6 237 double var_H;
loopsva 0:40b4ebf843c6 238 var_H = (((double)bmec.t_fine) - 76800.0);
loopsva 0:40b4ebf843c6 239 var_H = (bmed.raw_hum - (((double)bmec.dig_H4) * 64.0 + ((double)bmec.dig_H5) / 16384.0 * var_H)) *
loopsva 0:40b4ebf843c6 240 (((double)bmec.dig_H2) / 65536.0 * (1.0 + ((double)bmec.dig_H6) / 67108864.0 * var_H *
loopsva 0:40b4ebf843c6 241 (1.0 + ((double)bmec.dig_H3) / 67108864.0 * var_H)));
loopsva 0:40b4ebf843c6 242 var_H = var_H * (1.0 - ((double)bmec.dig_H1) * var_H / 524288.0);
loopsva 0:40b4ebf843c6 243 if (var_H > 100.0) {
loopsva 0:40b4ebf843c6 244 var_H = 100.0;
loopsva 0:40b4ebf843c6 245 } else if (var_H < 0.0) {
loopsva 0:40b4ebf843c6 246 var_H = 0.0;
loopsva 0:40b4ebf843c6 247 }
loopsva 0:40b4ebf843c6 248 bmed.corr_hum = 0;
loopsva 0:40b4ebf843c6 249 bmed.bme_hum = var_H;
loopsva 0:40b4ebf843c6 250 }
loopsva 0:40b4ebf843c6 251
loopsva 0:40b4ebf843c6 252 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 253 // Initialize the chip
loopsva 0:40b4ebf843c6 254
loopsva 0:40b4ebf843c6 255 uint8_t bme280::initBme(bme_cal& bmec) {
loopsva 0:40b4ebf843c6 256 #if defined BMEi2cLOWLEVEL
loopsva 0:40b4ebf843c6 257 //initialize the chip
loopsva 0:40b4ebf843c6 258 _i2c_start(i2cWAddr);
loopsva 0:40b4ebf843c6 259 _i2c_write(BME280_CTRL_HUMIDITY_REG);
loopsva 0:40b4ebf843c6 260 _i2c_write(BME280_CTRL_HUMIDITY_REG_DATA);
loopsva 0:40b4ebf843c6 261 _i2c_stop();
loopsva 0:40b4ebf843c6 262
loopsva 0:40b4ebf843c6 263 _i2c_start(i2cWAddr);
loopsva 0:40b4ebf843c6 264 _i2c_write(BME280_CTRL_MEAS_REG);
loopsva 0:40b4ebf843c6 265 _i2c_write(BME280_CTRL_MEAS_REG_DATA);
loopsva 0:40b4ebf843c6 266 _i2c_stop();
loopsva 0:40b4ebf843c6 267
loopsva 0:40b4ebf843c6 268 _i2c_start(i2cWAddr);
loopsva 0:40b4ebf843c6 269 _i2c_write(BME280_CONFIG_REG);
loopsva 0:40b4ebf843c6 270 _i2c_write(BME280_CONFIG_REG_DATA);
loopsva 0:40b4ebf843c6 271 _i2c_stop();
loopsva 0:40b4ebf843c6 272
loopsva 0:40b4ebf843c6 273 //read back config registers
loopsva 0:40b4ebf843c6 274 _i2c_start(i2cWAddr);
loopsva 0:40b4ebf843c6 275 _i2c_write(BME280_CTRL_HUMIDITY_REG);
loopsva 0:40b4ebf843c6 276 _i2c_start(i2cRAddr);
loopsva 0:40b4ebf843c6 277 bmec.ctrl_hum_reg = _i2c_readACK();
loopsva 0:40b4ebf843c6 278 uint8_t status = _i2c_readACK();
loopsva 0:40b4ebf843c6 279 bmec.ctrl_meas_reg = _i2c_readACK();
loopsva 0:40b4ebf843c6 280 bmec.config_reg = _i2c_readNACK();
loopsva 0:40b4ebf843c6 281 _i2c_stop();
loopsva 0:40b4ebf843c6 282
loopsva 0:40b4ebf843c6 283 //now get the calibration registers
loopsva 0:40b4ebf843c6 284 _i2c_start(i2cWAddr);
loopsva 0:40b4ebf843c6 285 _i2c_write(BME280_CAL_DATA_START_1);
loopsva 0:40b4ebf843c6 286 _i2c_start(i2cRAddr);
loopsva 0:40b4ebf843c6 287 // LSB first MSB second
loopsva 0:40b4ebf843c6 288 bmec.dig_T1 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 289 bmec.dig_T2 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 290 bmec.dig_T3 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 291 bmec.dig_P1 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 292 bmec.dig_P2 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 293 bmec.dig_P3 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 294 bmec.dig_P4 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 295 bmec.dig_P5 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 296 bmec.dig_P6 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 297 bmec.dig_P7 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 298 bmec.dig_P8 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 299 bmec.dig_P9 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 300 uint8_t rdata = (_i2c_readACK()); //dummy read of address 0xa0
loopsva 0:40b4ebf843c6 301 bmec.dig_H1 = (_i2c_readNACK());
loopsva 0:40b4ebf843c6 302 _i2c_stop();
loopsva 0:40b4ebf843c6 303
loopsva 0:40b4ebf843c6 304 //finally, get the Humid calibration registers
loopsva 0:40b4ebf843c6 305 _i2c_start(i2cWAddr);
loopsva 0:40b4ebf843c6 306 _i2c_write(BME280_CAL_DATA_START_2);
loopsva 0:40b4ebf843c6 307 _i2c_start(i2cRAddr);
loopsva 0:40b4ebf843c6 308 bmec.dig_H2 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 309 bmec.dig_H3 = (_i2c_readACK());
loopsva 0:40b4ebf843c6 310 bmec.dig_H4 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 311 bmec.dig_H5 = (_i2c_readACK() + (_i2c_readACK() << 8));
loopsva 0:40b4ebf843c6 312 bmec.dig_H6 = (_i2c_readNACK());
loopsva 0:40b4ebf843c6 313 _i2c_stop();
loopsva 0:40b4ebf843c6 314
loopsva 0:40b4ebf843c6 315 #else
loopsva 0:40b4ebf843c6 316 //initialize the chip
loopsva 0:40b4ebf843c6 317 bme280Buffer[0] = BME280_CTRL_HUMIDITY_REG;
loopsva 0:40b4ebf843c6 318 bme280Buffer[1] = BME280_CTRL_HUMIDITY_REG_DATA;
loopsva 0:40b4ebf843c6 319 _i2c.write(i2cWAddr, bme280Buffer, 2, false);
loopsva 0:40b4ebf843c6 320
loopsva 0:40b4ebf843c6 321 bme280Buffer[0] = BME280_CTRL_MEAS_REG;
loopsva 0:40b4ebf843c6 322 bme280Buffer[1] = BME280_CTRL_MEAS_REG_DATA;
loopsva 0:40b4ebf843c6 323 _i2c.write(i2cWAddr, bme280Buffer, 2, false);
loopsva 0:40b4ebf843c6 324
loopsva 0:40b4ebf843c6 325 bme280Buffer[0] = BME280_CONFIG_REG;
loopsva 0:40b4ebf843c6 326 bme280Buffer[1] = BME280_CONFIG_REG_DATA;
loopsva 0:40b4ebf843c6 327 _i2c.write(i2cWAddr, bme280Buffer, 2, false);
loopsva 0:40b4ebf843c6 328
loopsva 0:40b4ebf843c6 329 //read back config registers
loopsva 0:40b4ebf843c6 330 bme280Buffer[0] = BME280_CTRL_HUMIDITY_REG;
loopsva 0:40b4ebf843c6 331 _i2c.write(i2cWAddr, bme280Buffer, 1, true);
loopsva 0:40b4ebf843c6 332 _i2c.read(i2cRAddr, bme280Buffer, 4, false);
loopsva 0:40b4ebf843c6 333 bmec.ctrl_hum_reg = bme280Buffer[0];
loopsva 0:40b4ebf843c6 334 // uint8_t status = bme280Buffer[1];
loopsva 0:40b4ebf843c6 335 bmec.ctrl_meas_reg = bme280Buffer[2];
loopsva 0:40b4ebf843c6 336 bmec.config_reg = bme280Buffer[3];
loopsva 0:40b4ebf843c6 337
loopsva 0:40b4ebf843c6 338 //now get the calibration registers, Temp and Press first
loopsva 0:40b4ebf843c6 339 bme280Buffer[0] = BME280_CAL_DATA_START_1;
loopsva 0:40b4ebf843c6 340 _i2c.write(i2cWAddr, bme280Buffer, 1, true);
loopsva 0:40b4ebf843c6 341 _i2c.read(i2cRAddr, bme280Buffer, 26, false);
loopsva 0:40b4ebf843c6 342 // LSB first MSB second
loopsva 0:40b4ebf843c6 343 bmec.dig_T1 = (bme280Buffer[0] | (bme280Buffer[1] << 8));
loopsva 0:40b4ebf843c6 344 bmec.dig_T2 = (bme280Buffer[2] | (bme280Buffer[3] << 8));
loopsva 0:40b4ebf843c6 345 bmec.dig_T3 = (bme280Buffer[4] | (bme280Buffer[5] << 8));
loopsva 0:40b4ebf843c6 346 bmec.dig_P1 = (bme280Buffer[6] | (bme280Buffer[7] << 8));
loopsva 0:40b4ebf843c6 347 bmec.dig_P2 = (bme280Buffer[8] | (bme280Buffer[9] << 8));
loopsva 0:40b4ebf843c6 348 bmec.dig_P3 = (bme280Buffer[10] | (bme280Buffer[11] << 8));
loopsva 0:40b4ebf843c6 349 bmec.dig_P4 = (bme280Buffer[12] | (bme280Buffer[13] << 8));
loopsva 0:40b4ebf843c6 350 bmec.dig_P5 = (bme280Buffer[14] | (bme280Buffer[15] << 8));
loopsva 0:40b4ebf843c6 351 bmec.dig_P6 = (bme280Buffer[16] | (bme280Buffer[17] << 8));
loopsva 0:40b4ebf843c6 352 bmec.dig_P7 = (bme280Buffer[18] | (bme280Buffer[19] << 8));
loopsva 0:40b4ebf843c6 353 bmec.dig_P8 = (bme280Buffer[20] | (bme280Buffer[21] << 8));
loopsva 0:40b4ebf843c6 354 bmec.dig_P9 = (bme280Buffer[22] | (bme280Buffer[23] << 8));
loopsva 0:40b4ebf843c6 355 // uint8_t rdata = (bme280Buffer[24]); //dummy read of address 0xa0
loopsva 0:40b4ebf843c6 356 bmec.dig_H1 = (bme280Buffer[25]);
loopsva 0:40b4ebf843c6 357
loopsva 0:40b4ebf843c6 358 //finally, get the Humid calibration registers
loopsva 0:40b4ebf843c6 359 bme280Buffer[0] = BME280_CAL_DATA_START_2;
loopsva 0:40b4ebf843c6 360 _i2c.write(i2cWAddr, bme280Buffer, 1, true);
loopsva 0:40b4ebf843c6 361 _i2c.read(i2cRAddr, bme280Buffer, 8, false);
loopsva 0:40b4ebf843c6 362 bmec.dig_H2 = (bme280Buffer[0] | (bme280Buffer[1] << 8));
loopsva 0:40b4ebf843c6 363 bmec.dig_H3 = (bme280Buffer[2]);
loopsva 0:40b4ebf843c6 364 bmec.dig_H4 = ((bme280Buffer[4] & 15) | (bme280Buffer[3] << 4));
loopsva 0:40b4ebf843c6 365 bmec.dig_H5 = (((bme280Buffer[4] >> 4) & 15) | (bme280Buffer[5] << 4));
loopsva 0:40b4ebf843c6 366 bmec.dig_H6 = (bme280Buffer[6]);
loopsva 0:40b4ebf843c6 367
loopsva 0:40b4ebf843c6 368 #endif
loopsva 0:40b4ebf843c6 369 return(0);
loopsva 0:40b4ebf843c6 370 }
loopsva 0:40b4ebf843c6 371
loopsva 0:40b4ebf843c6 372 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 373 // Return corrected altitude (in feet) from barometer at sea level (in mB)
loopsva 0:40b4ebf843c6 374
loopsva 0:40b4ebf843c6 375 float bme280::getAltitudeFT(bme_data& bmed, float sea_pressure) {
loopsva 0:40b4ebf843c6 376 return(float)((1 - (pow((bmed.bme_baro / (double)sea_pressure), 0.190284))) * 145366.45);
loopsva 0:40b4ebf843c6 377 }
loopsva 0:40b4ebf843c6 378
loopsva 0:40b4ebf843c6 379 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 380 // Return corrected barometer, based on altitude (in feet)
loopsva 0:40b4ebf843c6 381
loopsva 0:40b4ebf843c6 382 float bme280::getSeaLevelBaroFT(bme_data& bmed, float known_alt) {
loopsva 0:40b4ebf843c6 383 return(pow(pow((bmed.bme_baro * MB_INHG_DOUBLE), 0.190284) + 0.00001313 * (double)known_alt , 5.2553026) * INHG_MB_DOUBLE);
loopsva 0:40b4ebf843c6 384 }
loopsva 0:40b4ebf843c6 385
loopsva 0:40b4ebf843c6 386 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 387 // Return corrected barometer, based on altitude (in meters)
loopsva 0:40b4ebf843c6 388
loopsva 0:40b4ebf843c6 389 float bme280::getSeaLevelBaroM(bme_data& bmed, float known_alt) {
loopsva 0:40b4ebf843c6 390 return(pow(pow((bmed.bme_baro * MB_INHG_DOUBLE), 0.190284) + 0.00001313 * (double)known_alt * FEET_METERS , 5.2553026) * INHG_MB_DOUBLE);
loopsva 0:40b4ebf843c6 391 }
loopsva 0:40b4ebf843c6 392
loopsva 0:40b4ebf843c6 393 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 394 // Return dew point. More accurate, slower
loopsva 0:40b4ebf843c6 395
loopsva 0:40b4ebf843c6 396 float bme280::getDewPt(bme_data& bmed) {
loopsva 0:40b4ebf843c6 397 // dewPoint function NOAA
loopsva 0:40b4ebf843c6 398 // reference: http://wahiduddin.net/calc/density_algorithms.htm
loopsva 0:40b4ebf843c6 399 double A0= 373.15 / (273.15 + (double)bmed.bme_temp);
loopsva 0:40b4ebf843c6 400 double SUM = -7.90298 * (A0 -1);
loopsva 0:40b4ebf843c6 401 SUM += 5.02808 * log10(A0);
loopsva 0:40b4ebf843c6 402 SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/A0))) -1) ;
loopsva 0:40b4ebf843c6 403 SUM += 8.1328e-3 * (pow(10,(-3.49149 * (A0 -1))) -1) ;
loopsva 0:40b4ebf843c6 404 SUM += log10(1013.246);
loopsva 0:40b4ebf843c6 405 double VP = pow(10, SUM -3) * bmed.bme_hum;
loopsva 0:40b4ebf843c6 406 double T = log(VP / 0.61078); // temp var
loopsva 0:40b4ebf843c6 407 return (241.88 * T) / (17.558 - T);
loopsva 0:40b4ebf843c6 408 }
loopsva 0:40b4ebf843c6 409
loopsva 0:40b4ebf843c6 410 //--------------------------------------------------------------------------------------------------------------------------------------//
loopsva 0:40b4ebf843c6 411 // Return dew point. Less accurate, faster
loopsva 0:40b4ebf843c6 412
loopsva 0:40b4ebf843c6 413 float bme280::getDewPtFast(bme_data& bmed) {
loopsva 0:40b4ebf843c6 414 // delta max = 0.6544 wrt dewPoint()
loopsva 0:40b4ebf843c6 415 // 5x faster than dewPoint()
loopsva 0:40b4ebf843c6 416 // reference: http://en.wikipedia.org/wiki/Dew_point
loopsva 0:40b4ebf843c6 417 double bmeDtzA = 17.271;
loopsva 0:40b4ebf843c6 418 double bmeDtzB = 237.7;
loopsva 0:40b4ebf843c6 419 double bmeDtzC = (bmeDtzA * bmed.bme_temp) / (bmeDtzB + bmed.bme_temp) + log(bmed.bme_hum / 100.0);
loopsva 0:40b4ebf843c6 420 double bmeDtzD = (bmeDtzB * bmeDtzC) / (bmeDtzA - bmeDtzC);
loopsva 0:40b4ebf843c6 421 return (bmeDtzD);
loopsva 0:40b4ebf843c6 422 }
loopsva 0:40b4ebf843c6 423
loopsva 0:40b4ebf843c6 424
loopsva 0:40b4ebf843c6 425