Added mag calibration and interrupt-based data ready

Dependencies:   BLE_API mbed-src nRF51822

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?

UserRevisionLine numberNew 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