Added mag calibration and interrupt-based data ready
Dependencies: BLE_API mbed-src nRF51822
BMP280.h@4:8d11bfc7cac0, 2016-09-22 (annotated)
- Committer:
- onehorse
- Date:
- Thu Sep 22 01:21:24 2016 +0000
- Revision:
- 4:8d11bfc7cac0
Added mag calibration and interrupt-based data ready
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
onehorse | 4:8d11bfc7cac0 | 1 | #ifndef BMP280_H |
onehorse | 4:8d11bfc7cac0 | 2 | #define BMP280_H |
onehorse | 4:8d11bfc7cac0 | 3 | |
onehorse | 4:8d11bfc7cac0 | 4 | //#include "mbed.h" |
onehorse | 4:8d11bfc7cac0 | 5 | |
onehorse | 4:8d11bfc7cac0 | 6 | // BMP280 registers |
onehorse | 4:8d11bfc7cac0 | 7 | #define BMP280_TEMP_XLSB 0xFC |
onehorse | 4:8d11bfc7cac0 | 8 | #define BMP280_TEMP_LSB 0xFB |
onehorse | 4:8d11bfc7cac0 | 9 | #define BMP280_TEMP_MSB 0xFA |
onehorse | 4:8d11bfc7cac0 | 10 | #define BMP280_PRESS_XLSB 0xF9 |
onehorse | 4:8d11bfc7cac0 | 11 | #define BMP280_PRESS_LSB 0xF8 |
onehorse | 4:8d11bfc7cac0 | 12 | #define BMP280_PRESS_MSB 0xF7 |
onehorse | 4:8d11bfc7cac0 | 13 | #define BMP280_CONFIG 0xF5 |
onehorse | 4:8d11bfc7cac0 | 14 | #define BMP280_CTRL_MEAS 0xF4 |
onehorse | 4:8d11bfc7cac0 | 15 | #define BMP280_STATUS 0xF3 |
onehorse | 4:8d11bfc7cac0 | 16 | #define BMP280_RESET 0xE0 |
onehorse | 4:8d11bfc7cac0 | 17 | #define BMP280_ID 0xD0 // should be 0x58 |
onehorse | 4:8d11bfc7cac0 | 18 | #define BMP280_CALIB00 0x88 |
onehorse | 4:8d11bfc7cac0 | 19 | #define BMP280_ADDRESS 0x77<<1 |
onehorse | 4:8d11bfc7cac0 | 20 | |
onehorse | 4:8d11bfc7cac0 | 21 | // Set initial input parameters |
onehorse | 4:8d11bfc7cac0 | 22 | |
onehorse | 4:8d11bfc7cac0 | 23 | enum Posr { |
onehorse | 4:8d11bfc7cac0 | 24 | P_OSR_00 = 0, // no op |
onehorse | 4:8d11bfc7cac0 | 25 | P_OSR_01, |
onehorse | 4:8d11bfc7cac0 | 26 | P_OSR_02, |
onehorse | 4:8d11bfc7cac0 | 27 | P_OSR_04, |
onehorse | 4:8d11bfc7cac0 | 28 | P_OSR_08, |
onehorse | 4:8d11bfc7cac0 | 29 | P_OSR_16 |
onehorse | 4:8d11bfc7cac0 | 30 | }; |
onehorse | 4:8d11bfc7cac0 | 31 | |
onehorse | 4:8d11bfc7cac0 | 32 | enum Tosr { |
onehorse | 4:8d11bfc7cac0 | 33 | T_OSR_00 = 0, // no op |
onehorse | 4:8d11bfc7cac0 | 34 | T_OSR_01, |
onehorse | 4:8d11bfc7cac0 | 35 | T_OSR_02, |
onehorse | 4:8d11bfc7cac0 | 36 | T_OSR_04, |
onehorse | 4:8d11bfc7cac0 | 37 | T_OSR_08, |
onehorse | 4:8d11bfc7cac0 | 38 | T_OSR_16 |
onehorse | 4:8d11bfc7cac0 | 39 | }; |
onehorse | 4:8d11bfc7cac0 | 40 | |
onehorse | 4:8d11bfc7cac0 | 41 | enum IIRFilter { |
onehorse | 4:8d11bfc7cac0 | 42 | full = 0, // bandwidth at full sample rate |
onehorse | 4:8d11bfc7cac0 | 43 | BW0_223ODR, |
onehorse | 4:8d11bfc7cac0 | 44 | BW0_092ODR, |
onehorse | 4:8d11bfc7cac0 | 45 | BW0_042ODR, |
onehorse | 4:8d11bfc7cac0 | 46 | BW0_021ODR // bandwidth at 0.021 x sample rate |
onehorse | 4:8d11bfc7cac0 | 47 | }; |
onehorse | 4:8d11bfc7cac0 | 48 | |
onehorse | 4:8d11bfc7cac0 | 49 | enum Mode { |
onehorse | 4:8d11bfc7cac0 | 50 | BMP280Sleep = 0, |
onehorse | 4:8d11bfc7cac0 | 51 | forced, |
onehorse | 4:8d11bfc7cac0 | 52 | forced2, |
onehorse | 4:8d11bfc7cac0 | 53 | normal |
onehorse | 4:8d11bfc7cac0 | 54 | }; |
onehorse | 4:8d11bfc7cac0 | 55 | |
onehorse | 4:8d11bfc7cac0 | 56 | enum SBy { |
onehorse | 4:8d11bfc7cac0 | 57 | t_00_5ms = 0, |
onehorse | 4:8d11bfc7cac0 | 58 | t_62_5ms, |
onehorse | 4:8d11bfc7cac0 | 59 | t_125ms, |
onehorse | 4:8d11bfc7cac0 | 60 | t_250ms, |
onehorse | 4:8d11bfc7cac0 | 61 | t_500ms, |
onehorse | 4:8d11bfc7cac0 | 62 | t_1000ms, |
onehorse | 4:8d11bfc7cac0 | 63 | t_2000ms, |
onehorse | 4:8d11bfc7cac0 | 64 | t_4000ms, |
onehorse | 4:8d11bfc7cac0 | 65 | }; |
onehorse | 4:8d11bfc7cac0 | 66 | |
onehorse | 4:8d11bfc7cac0 | 67 | // Specify BMP280 configuration |
onehorse | 4:8d11bfc7cac0 | 68 | uint8_t Posr = P_OSR_16, Tosr = T_OSR_02, Mode = normal, IIRFilter = BW0_042ODR, SBy = t_62_5ms; // set pressure amd temperature output data rate |
onehorse | 4:8d11bfc7cac0 | 69 | // t_fine carries fine temperature as global value for BMP280 |
onehorse | 4:8d11bfc7cac0 | 70 | int32_t t_fine; |
onehorse | 4:8d11bfc7cac0 | 71 | |
onehorse | 4:8d11bfc7cac0 | 72 | //Set up I2C, (SDA,SCL) |
onehorse | 4:8d11bfc7cac0 | 73 | //I2C i2c(P0_0, P0_1); |
onehorse | 4:8d11bfc7cac0 | 74 | |
onehorse | 4:8d11bfc7cac0 | 75 | // BMP280 compensation parameters |
onehorse | 4:8d11bfc7cac0 | 76 | uint16_t dig_T1, dig_P1; |
onehorse | 4:8d11bfc7cac0 | 77 | int16_t dig_T2, dig_T3, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9; |
onehorse | 4:8d11bfc7cac0 | 78 | |
onehorse | 4:8d11bfc7cac0 | 79 | class BMP280 { |
onehorse | 4:8d11bfc7cac0 | 80 | |
onehorse | 4:8d11bfc7cac0 | 81 | protected: |
onehorse | 4:8d11bfc7cac0 | 82 | |
onehorse | 4:8d11bfc7cac0 | 83 | public: |
onehorse | 4:8d11bfc7cac0 | 84 | //=================================================================================================================== |
onehorse | 4:8d11bfc7cac0 | 85 | //====== Set of useful function to access pressure and temperature data |
onehorse | 4:8d11bfc7cac0 | 86 | //=================================================================================================================== |
onehorse | 4:8d11bfc7cac0 | 87 | |
onehorse | 4:8d11bfc7cac0 | 88 | |
onehorse | 4:8d11bfc7cac0 | 89 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data) |
onehorse | 4:8d11bfc7cac0 | 90 | { |
onehorse | 4:8d11bfc7cac0 | 91 | char data_write[2]; |
onehorse | 4:8d11bfc7cac0 | 92 | data_write[0] = subAddress; |
onehorse | 4:8d11bfc7cac0 | 93 | data_write[1] = data; |
onehorse | 4:8d11bfc7cac0 | 94 | i2c.write(address, data_write, 2, 0); |
onehorse | 4:8d11bfc7cac0 | 95 | } |
onehorse | 4:8d11bfc7cac0 | 96 | |
onehorse | 4:8d11bfc7cac0 | 97 | char readByte(uint8_t address, uint8_t subAddress) |
onehorse | 4:8d11bfc7cac0 | 98 | { |
onehorse | 4:8d11bfc7cac0 | 99 | char data[1]; // `data` will store the register data |
onehorse | 4:8d11bfc7cac0 | 100 | char data_write[1]; |
onehorse | 4:8d11bfc7cac0 | 101 | data_write[0] = subAddress; |
onehorse | 4:8d11bfc7cac0 | 102 | i2c.write(address, data_write, 1, 1); // no stop |
onehorse | 4:8d11bfc7cac0 | 103 | i2c.read(address, data, 1, 0); |
onehorse | 4:8d11bfc7cac0 | 104 | return data[0]; |
onehorse | 4:8d11bfc7cac0 | 105 | } |
onehorse | 4:8d11bfc7cac0 | 106 | |
onehorse | 4:8d11bfc7cac0 | 107 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest) |
onehorse | 4:8d11bfc7cac0 | 108 | { |
onehorse | 4:8d11bfc7cac0 | 109 | char data[24]; |
onehorse | 4:8d11bfc7cac0 | 110 | char data_write[1]; |
onehorse | 4:8d11bfc7cac0 | 111 | data_write[0] = subAddress; |
onehorse | 4:8d11bfc7cac0 | 112 | i2c.write(address, data_write, 1, 1); // no stop |
onehorse | 4:8d11bfc7cac0 | 113 | i2c.read(address, data, count, 0); |
onehorse | 4:8d11bfc7cac0 | 114 | for(int ii = 0; ii < count; ii++) { |
onehorse | 4:8d11bfc7cac0 | 115 | dest[ii] = data[ii]; |
onehorse | 4:8d11bfc7cac0 | 116 | } |
onehorse | 4:8d11bfc7cac0 | 117 | } |
onehorse | 4:8d11bfc7cac0 | 118 | |
onehorse | 4:8d11bfc7cac0 | 119 | |
onehorse | 4:8d11bfc7cac0 | 120 | int32_t readBMP280Temperature() |
onehorse | 4:8d11bfc7cac0 | 121 | { |
onehorse | 4:8d11bfc7cac0 | 122 | uint8_t rawData[3]; // 20-bit pressure register data stored here |
onehorse | 4:8d11bfc7cac0 | 123 | readBytes(BMP280_ADDRESS, BMP280_TEMP_MSB, 3, &rawData[0]); |
onehorse | 4:8d11bfc7cac0 | 124 | return (int32_t) (((int32_t) rawData[0] << 16 | (int32_t) rawData[1] << 8 | rawData[2]) >> 4); |
onehorse | 4:8d11bfc7cac0 | 125 | } |
onehorse | 4:8d11bfc7cac0 | 126 | |
onehorse | 4:8d11bfc7cac0 | 127 | int32_t readBMP280Pressure() |
onehorse | 4:8d11bfc7cac0 | 128 | { |
onehorse | 4:8d11bfc7cac0 | 129 | uint8_t rawData[3]; // 20-bit pressure register data stored here |
onehorse | 4:8d11bfc7cac0 | 130 | readBytes(BMP280_ADDRESS, BMP280_PRESS_MSB, 3, &rawData[0]); |
onehorse | 4:8d11bfc7cac0 | 131 | return (int32_t) (((int32_t) rawData[0] << 16 | (int32_t) rawData[1] << 8 | rawData[2]) >> 4); |
onehorse | 4:8d11bfc7cac0 | 132 | } |
onehorse | 4:8d11bfc7cac0 | 133 | |
onehorse | 4:8d11bfc7cac0 | 134 | void BMP280Init() |
onehorse | 4:8d11bfc7cac0 | 135 | { |
onehorse | 4:8d11bfc7cac0 | 136 | // Configure the BMP280 |
onehorse | 4:8d11bfc7cac0 | 137 | // Set T and P oversampling rates and sensor mode |
onehorse | 4:8d11bfc7cac0 | 138 | writeByte(BMP280_ADDRESS, BMP280_CTRL_MEAS, Tosr << 5 | Posr << 2 | Mode); |
onehorse | 4:8d11bfc7cac0 | 139 | // Set standby time interval in normal mode and bandwidth |
onehorse | 4:8d11bfc7cac0 | 140 | writeByte(BMP280_ADDRESS, BMP280_CONFIG, SBy << 5 | IIRFilter << 2); |
onehorse | 4:8d11bfc7cac0 | 141 | // Read and store calibration data |
onehorse | 4:8d11bfc7cac0 | 142 | uint8_t calib[24]; |
onehorse | 4:8d11bfc7cac0 | 143 | readBytes(BMP280_ADDRESS, BMP280_CALIB00, 24, &calib[0]); |
onehorse | 4:8d11bfc7cac0 | 144 | dig_T1 = (uint16_t)(((uint16_t) calib[1] << 8) | calib[0]); |
onehorse | 4:8d11bfc7cac0 | 145 | dig_T2 = ( int16_t)((( int16_t) calib[3] << 8) | calib[2]); |
onehorse | 4:8d11bfc7cac0 | 146 | dig_T3 = ( int16_t)((( int16_t) calib[5] << 8) | calib[4]); |
onehorse | 4:8d11bfc7cac0 | 147 | dig_P1 = (uint16_t)(((uint16_t) calib[7] << 8) | calib[6]); |
onehorse | 4:8d11bfc7cac0 | 148 | dig_P2 = ( int16_t)((( int16_t) calib[9] << 8) | calib[8]); |
onehorse | 4:8d11bfc7cac0 | 149 | dig_P3 = ( int16_t)((( int16_t) calib[11] << 8) | calib[10]); |
onehorse | 4:8d11bfc7cac0 | 150 | dig_P4 = ( int16_t)((( int16_t) calib[13] << 8) | calib[12]); |
onehorse | 4:8d11bfc7cac0 | 151 | dig_P5 = ( int16_t)((( int16_t) calib[15] << 8) | calib[14]); |
onehorse | 4:8d11bfc7cac0 | 152 | dig_P6 = ( int16_t)((( int16_t) calib[17] << 8) | calib[16]); |
onehorse | 4:8d11bfc7cac0 | 153 | dig_P7 = ( int16_t)((( int16_t) calib[19] << 8) | calib[18]); |
onehorse | 4:8d11bfc7cac0 | 154 | dig_P8 = ( int16_t)((( int16_t) calib[21] << 8) | calib[20]); |
onehorse | 4:8d11bfc7cac0 | 155 | dig_P9 = ( int16_t)((( int16_t) calib[23] << 8) | calib[22]); |
onehorse | 4:8d11bfc7cac0 | 156 | } |
onehorse | 4:8d11bfc7cac0 | 157 | |
onehorse | 4:8d11bfc7cac0 | 158 | // Returns temperature in DegC, resolution is 0.01 DegC. Output value of |
onehorse | 4:8d11bfc7cac0 | 159 | // “5123” equals 51.23 DegC. |
onehorse | 4:8d11bfc7cac0 | 160 | int32_t bmp280_compensate_T(int32_t adc_T) |
onehorse | 4:8d11bfc7cac0 | 161 | { |
onehorse | 4:8d11bfc7cac0 | 162 | int32_t var1, var2, T; |
onehorse | 4:8d11bfc7cac0 | 163 | var1 = ((((adc_T >> 3) - ((int32_t)dig_T1 << 1))) * ((int32_t)dig_T2)) >> 11; |
onehorse | 4:8d11bfc7cac0 | 164 | var2 = (((((adc_T >> 4) - ((int32_t)dig_T1)) * ((adc_T >> 4) - ((int32_t)dig_T1))) >> 12) * ((int32_t)dig_T3)) >> 14; |
onehorse | 4:8d11bfc7cac0 | 165 | t_fine = var1 + var2; |
onehorse | 4:8d11bfc7cac0 | 166 | T = (t_fine * 5 + 128) >> 8; |
onehorse | 4:8d11bfc7cac0 | 167 | return T; |
onehorse | 4:8d11bfc7cac0 | 168 | } |
onehorse | 4:8d11bfc7cac0 | 169 | |
onehorse | 4:8d11bfc7cac0 | 170 | // Returns pressure in Pa as unsigned 32 bit integer in Q24.8 format (24 integer bits and 8 |
onehorse | 4:8d11bfc7cac0 | 171 | //fractional bits). |
onehorse | 4:8d11bfc7cac0 | 172 | //Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa |
onehorse | 4:8d11bfc7cac0 | 173 | uint32_t bmp280_compensate_P(int32_t adc_P) |
onehorse | 4:8d11bfc7cac0 | 174 | { |
onehorse | 4:8d11bfc7cac0 | 175 | long long var1, var2, p; |
onehorse | 4:8d11bfc7cac0 | 176 | var1 = ((long long)t_fine) - 128000; |
onehorse | 4:8d11bfc7cac0 | 177 | var2 = var1 * var1 * (long long)dig_P6; |
onehorse | 4:8d11bfc7cac0 | 178 | var2 = var2 + ((var1*(long long)dig_P5)<<17); |
onehorse | 4:8d11bfc7cac0 | 179 | var2 = var2 + (((long long)dig_P4)<<35); |
onehorse | 4:8d11bfc7cac0 | 180 | var1 = ((var1 * var1 * (long long)dig_P3)>>8) + ((var1 * (long long)dig_P2)<<12); |
onehorse | 4:8d11bfc7cac0 | 181 | var1 = (((((long long)1)<<47)+var1))*((long long)dig_P1)>>33; |
onehorse | 4:8d11bfc7cac0 | 182 | if(var1 == 0) |
onehorse | 4:8d11bfc7cac0 | 183 | { |
onehorse | 4:8d11bfc7cac0 | 184 | return 0; |
onehorse | 4:8d11bfc7cac0 | 185 | // avoid exception caused by division by zero |
onehorse | 4:8d11bfc7cac0 | 186 | } |
onehorse | 4:8d11bfc7cac0 | 187 | p = 1048576 - adc_P; |
onehorse | 4:8d11bfc7cac0 | 188 | p = (((p<<31) - var2)*3125)/var1; |
onehorse | 4:8d11bfc7cac0 | 189 | var1 = (((long long)dig_P9) * (p>>13) * (p>>13)) >> 25; |
onehorse | 4:8d11bfc7cac0 | 190 | var2 = (((long long)dig_P8) * p)>> 19; |
onehorse | 4:8d11bfc7cac0 | 191 | p = ((p + var1 + var2) >> 8) + (((long long)dig_P7)<<4); |
onehorse | 4:8d11bfc7cac0 | 192 | return (uint32_t)p; |
onehorse | 4:8d11bfc7cac0 | 193 | } |
onehorse | 4:8d11bfc7cac0 | 194 | |
onehorse | 4:8d11bfc7cac0 | 195 | |
onehorse | 4:8d11bfc7cac0 | 196 | |
onehorse | 4:8d11bfc7cac0 | 197 | |
onehorse | 4:8d11bfc7cac0 | 198 | }; |
onehorse | 4:8d11bfc7cac0 | 199 | #endif |