This is mandatory
Dependencies: BLE_API mbed nRF51822 SHT21_ncleee
BMP180.h@5:fe4888cc60cc, 2015-12-21 (annotated)
- Committer:
- PostaL
- Date:
- Mon Dec 21 00:25:08 2015 +0000
- Revision:
- 5:fe4888cc60cc
- Parent:
- 3:b6d2c5195055
Added humidity reading + temp. avg. via SHT21
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
PostaL | 3:b6d2c5195055 | 1 | #ifndef BMP180_H |
PostaL | 3:b6d2c5195055 | 2 | #define BMP180_H |
PostaL | 3:b6d2c5195055 | 3 | |
PostaL | 3:b6d2c5195055 | 4 | #include "mbed.h" |
PostaL | 3:b6d2c5195055 | 5 | |
PostaL | 3:b6d2c5195055 | 6 | #define BMP180_ADDRESS 0x77<<1 // I2C address of BMP180, eight bit address on mbed |
PostaL | 3:b6d2c5195055 | 7 | #define BMP180_WHO_AM_I 0xD0 // WHO_AM_I id of BMP180, should return 0x55 |
PostaL | 3:b6d2c5195055 | 8 | #define BMP180_RESET 0xE0 |
PostaL | 3:b6d2c5195055 | 9 | #define BMP180_CONTROL 0xF4 |
PostaL | 3:b6d2c5195055 | 10 | #define BMP180_OUT_MSB 0xF6 |
PostaL | 3:b6d2c5195055 | 11 | #define BMP180_OUT_LSB 0xF7 |
PostaL | 3:b6d2c5195055 | 12 | #define BMP180_OUT_XLSB 0xF8 |
PostaL | 3:b6d2c5195055 | 13 | |
PostaL | 3:b6d2c5195055 | 14 | // Set initial input parameters |
PostaL | 3:b6d2c5195055 | 15 | |
PostaL | 3:b6d2c5195055 | 16 | enum OSS { // BMP-085 sampling rate |
PostaL | 3:b6d2c5195055 | 17 | OSS_0 = 0, // 4.5 ms conversion time |
PostaL | 3:b6d2c5195055 | 18 | OSS_1, // 7.5 |
PostaL | 3:b6d2c5195055 | 19 | OSS_2, // 13.5 |
PostaL | 3:b6d2c5195055 | 20 | OSS_3 // 25.5 |
PostaL | 3:b6d2c5195055 | 21 | }; |
PostaL | 3:b6d2c5195055 | 22 | |
PostaL | 3:b6d2c5195055 | 23 | uint8_t OSS = OSS_3; // maximum pressure resolution |
PostaL | 3:b6d2c5195055 | 24 | |
PostaL | 3:b6d2c5195055 | 25 | //Set up I2C, (SDA,SCL) |
PostaL | 3:b6d2c5195055 | 26 | I2C i2c(I2C_SDA, I2C_SCL); |
PostaL | 3:b6d2c5195055 | 27 | |
PostaL | 3:b6d2c5195055 | 28 | // These are constants used to calculate the temperature and pressure from the BMP-180 sensor |
PostaL | 3:b6d2c5195055 | 29 | int16_t ac1, ac2, ac3, b1, b2, mb, mc, md, b5; |
PostaL | 3:b6d2c5195055 | 30 | uint16_t ac4, ac5, ac6; |
PostaL | 3:b6d2c5195055 | 31 | |
PostaL | 3:b6d2c5195055 | 32 | class BMP180 { |
PostaL | 3:b6d2c5195055 | 33 | |
PostaL | 3:b6d2c5195055 | 34 | protected: |
PostaL | 3:b6d2c5195055 | 35 | |
PostaL | 3:b6d2c5195055 | 36 | public: |
PostaL | 3:b6d2c5195055 | 37 | //=================================================================================================================== |
PostaL | 3:b6d2c5195055 | 38 | //====== Set of useful function to access pressure and temperature data |
PostaL | 3:b6d2c5195055 | 39 | //=================================================================================================================== |
PostaL | 3:b6d2c5195055 | 40 | |
PostaL | 3:b6d2c5195055 | 41 | void writeByte(uint8_t address, uint8_t subAddress, uint8_t data) |
PostaL | 3:b6d2c5195055 | 42 | { |
PostaL | 3:b6d2c5195055 | 43 | char data_write[2]; |
PostaL | 3:b6d2c5195055 | 44 | data_write[0] = subAddress; |
PostaL | 3:b6d2c5195055 | 45 | data_write[1] = data; |
PostaL | 3:b6d2c5195055 | 46 | i2c.write(address, data_write, 2, 0); |
PostaL | 3:b6d2c5195055 | 47 | } |
PostaL | 3:b6d2c5195055 | 48 | |
PostaL | 3:b6d2c5195055 | 49 | char readByte(uint8_t address, uint8_t subAddress) |
PostaL | 3:b6d2c5195055 | 50 | { |
PostaL | 3:b6d2c5195055 | 51 | char data[1]; // `data` will store the register data |
PostaL | 3:b6d2c5195055 | 52 | char data_write[1]; |
PostaL | 3:b6d2c5195055 | 53 | data_write[0] = subAddress; |
PostaL | 3:b6d2c5195055 | 54 | i2c.write(address, data_write, 1, 1); // no stop |
PostaL | 3:b6d2c5195055 | 55 | i2c.read(address, data, 1, 0); |
PostaL | 3:b6d2c5195055 | 56 | return data[0]; |
PostaL | 3:b6d2c5195055 | 57 | } |
PostaL | 3:b6d2c5195055 | 58 | |
PostaL | 3:b6d2c5195055 | 59 | void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest) |
PostaL | 3:b6d2c5195055 | 60 | { |
PostaL | 3:b6d2c5195055 | 61 | char data[14]; |
PostaL | 3:b6d2c5195055 | 62 | char data_write[1]; |
PostaL | 3:b6d2c5195055 | 63 | data_write[0] = subAddress; |
PostaL | 3:b6d2c5195055 | 64 | i2c.write(address, data_write, 1, 1); // no stop |
PostaL | 3:b6d2c5195055 | 65 | i2c.read(address, data, count, 0); |
PostaL | 3:b6d2c5195055 | 66 | for(int ii = 0; ii < count; ii++) { |
PostaL | 3:b6d2c5195055 | 67 | dest[ii] = data[ii]; |
PostaL | 3:b6d2c5195055 | 68 | } |
PostaL | 3:b6d2c5195055 | 69 | } |
PostaL | 3:b6d2c5195055 | 70 | |
PostaL | 3:b6d2c5195055 | 71 | |
PostaL | 3:b6d2c5195055 | 72 | // Stores all of the BMP180's calibration values into global variables |
PostaL | 3:b6d2c5195055 | 73 | // Calibration values are required to calculate temp and pressure |
PostaL | 3:b6d2c5195055 | 74 | // This function should be called at the beginning of the program |
PostaL | 3:b6d2c5195055 | 75 | // These BMP-180 functions were adapted from Jim Lindblom of SparkFun Electronics |
PostaL | 3:b6d2c5195055 | 76 | void BMP180Calibration() |
PostaL | 3:b6d2c5195055 | 77 | { |
PostaL | 3:b6d2c5195055 | 78 | ac1 = readByte(BMP180_ADDRESS, 0xAA) << 8 | readByte(BMP180_ADDRESS, 0xAB); |
PostaL | 3:b6d2c5195055 | 79 | ac2 = readByte(BMP180_ADDRESS, 0xAC) << 8 | readByte(BMP180_ADDRESS, 0xAD); |
PostaL | 3:b6d2c5195055 | 80 | ac3 = readByte(BMP180_ADDRESS, 0xAE) << 8 | readByte(BMP180_ADDRESS, 0xAF); |
PostaL | 3:b6d2c5195055 | 81 | ac4 = readByte(BMP180_ADDRESS, 0xB0) << 8 | readByte(BMP180_ADDRESS, 0xB1); |
PostaL | 3:b6d2c5195055 | 82 | ac5 = readByte(BMP180_ADDRESS, 0xB2) << 8 | readByte(BMP180_ADDRESS, 0xB3); |
PostaL | 3:b6d2c5195055 | 83 | ac6 = readByte(BMP180_ADDRESS, 0xB4) << 8 | readByte(BMP180_ADDRESS, 0xB5); |
PostaL | 3:b6d2c5195055 | 84 | b1 = readByte(BMP180_ADDRESS, 0xB6) << 8 | readByte(BMP180_ADDRESS, 0xB7); |
PostaL | 3:b6d2c5195055 | 85 | b2 = readByte(BMP180_ADDRESS, 0xB8) << 8 | readByte(BMP180_ADDRESS, 0xB9); |
PostaL | 3:b6d2c5195055 | 86 | mb = readByte(BMP180_ADDRESS, 0xBA) << 8 | readByte(BMP180_ADDRESS, 0xBB); |
PostaL | 3:b6d2c5195055 | 87 | mc = readByte(BMP180_ADDRESS, 0xBC) << 8 | readByte(BMP180_ADDRESS, 0xBD); |
PostaL | 3:b6d2c5195055 | 88 | md = readByte(BMP180_ADDRESS, 0xBE) << 8 | readByte(BMP180_ADDRESS, 0xBF); |
PostaL | 3:b6d2c5195055 | 89 | } |
PostaL | 3:b6d2c5195055 | 90 | |
PostaL | 3:b6d2c5195055 | 91 | // Temperature returned will be in units of 0.1 deg C |
PostaL | 3:b6d2c5195055 | 92 | int16_t BMP180GetTemperature() |
PostaL | 3:b6d2c5195055 | 93 | { |
PostaL | 3:b6d2c5195055 | 94 | int16_t ut = 0; |
PostaL | 3:b6d2c5195055 | 95 | writeByte(BMP180_ADDRESS, 0xF4, 0x2E); // start temperature measurement |
PostaL | 3:b6d2c5195055 | 96 | wait(0.005); |
PostaL | 3:b6d2c5195055 | 97 | uint8_t rawData[2] = {0, 0}; |
PostaL | 3:b6d2c5195055 | 98 | readBytes(BMP180_ADDRESS, 0xF6, 2, &rawData[0]); // read raw temperature measurement |
PostaL | 3:b6d2c5195055 | 99 | ut = (((int16_t) rawData[0] << 8) | rawData[1]); |
PostaL | 3:b6d2c5195055 | 100 | |
PostaL | 3:b6d2c5195055 | 101 | long x1, x2; |
PostaL | 3:b6d2c5195055 | 102 | |
PostaL | 3:b6d2c5195055 | 103 | x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15; |
PostaL | 3:b6d2c5195055 | 104 | x2 = ((long)mc << 11)/(x1 + md); |
PostaL | 3:b6d2c5195055 | 105 | b5 = x1 + x2; |
PostaL | 3:b6d2c5195055 | 106 | |
PostaL | 3:b6d2c5195055 | 107 | return ((b5 + 8)>>4); |
PostaL | 3:b6d2c5195055 | 108 | } |
PostaL | 3:b6d2c5195055 | 109 | |
PostaL | 3:b6d2c5195055 | 110 | // Calculate pressure read calibration values |
PostaL | 3:b6d2c5195055 | 111 | // b5 is also required so BMP180GetTemperature() must be called first. |
PostaL | 3:b6d2c5195055 | 112 | // Value returned will be pressure in units of Pa. |
PostaL | 3:b6d2c5195055 | 113 | long BMP180GetPressure() |
PostaL | 3:b6d2c5195055 | 114 | { |
PostaL | 3:b6d2c5195055 | 115 | long up = 0; |
PostaL | 3:b6d2c5195055 | 116 | writeByte(BMP180_ADDRESS, 0xF4, 0x34 | OSS << 6); // Configure pressure measurement for highest resolution |
PostaL | 3:b6d2c5195055 | 117 | wait((5.0f + 8.0f*3.0f)/1000.0f); // delay 5 ms at lowest resolution, 29 ms at highest |
PostaL | 3:b6d2c5195055 | 118 | uint8_t rawData[3] = {0, 0, 0}; |
PostaL | 3:b6d2c5195055 | 119 | readBytes(BMP180_ADDRESS, 0xF6, 3, &rawData[0]); // read raw pressure measurement of 19 bits |
PostaL | 3:b6d2c5195055 | 120 | up = (((long) rawData[0] << 16) | ((long)rawData[1] << 8) | rawData[2]) >> (8 - OSS); |
PostaL | 3:b6d2c5195055 | 121 | |
PostaL | 3:b6d2c5195055 | 122 | long x1, x2, x3, b3, b6, p; |
PostaL | 3:b6d2c5195055 | 123 | unsigned long b4, b7; |
PostaL | 3:b6d2c5195055 | 124 | |
PostaL | 3:b6d2c5195055 | 125 | b6 = b5 - 4000; |
PostaL | 3:b6d2c5195055 | 126 | // Calculate B3 |
PostaL | 3:b6d2c5195055 | 127 | x1 = (b2 * (b6 * b6)>>12)>>11; |
PostaL | 3:b6d2c5195055 | 128 | x2 = (ac2 * b6)>>11; |
PostaL | 3:b6d2c5195055 | 129 | x3 = x1 + x2; |
PostaL | 3:b6d2c5195055 | 130 | b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2; |
PostaL | 3:b6d2c5195055 | 131 | |
PostaL | 3:b6d2c5195055 | 132 | // Calculate B4 |
PostaL | 3:b6d2c5195055 | 133 | x1 = (ac3 * b6)>>13; |
PostaL | 3:b6d2c5195055 | 134 | x2 = (b1 * ((b6 * b6)>>12))>>16; |
PostaL | 3:b6d2c5195055 | 135 | x3 = ((x1 + x2) + 2)>>2; |
PostaL | 3:b6d2c5195055 | 136 | b4 = (ac4 * (unsigned long)(x3 + 32768))>>15; |
PostaL | 3:b6d2c5195055 | 137 | |
PostaL | 3:b6d2c5195055 | 138 | b7 = ((unsigned long)(up - b3) * (50000>>OSS)); |
PostaL | 3:b6d2c5195055 | 139 | if (b7 < 0x80000000) |
PostaL | 3:b6d2c5195055 | 140 | p = (b7<<1)/b4; |
PostaL | 3:b6d2c5195055 | 141 | else |
PostaL | 3:b6d2c5195055 | 142 | p = (b7/b4)<<1; |
PostaL | 3:b6d2c5195055 | 143 | |
PostaL | 3:b6d2c5195055 | 144 | x1 = (p>>8) * (p>>8); |
PostaL | 3:b6d2c5195055 | 145 | x1 = (x1 * 3038)>>16; |
PostaL | 3:b6d2c5195055 | 146 | x2 = (-7357 * p)>>16; |
PostaL | 3:b6d2c5195055 | 147 | p += (x1 + x2 + 3791)>>4; |
PostaL | 3:b6d2c5195055 | 148 | |
PostaL | 3:b6d2c5195055 | 149 | return p; |
PostaL | 3:b6d2c5195055 | 150 | } |
PostaL | 3:b6d2c5195055 | 151 | |
PostaL | 3:b6d2c5195055 | 152 | |
PostaL | 3:b6d2c5195055 | 153 | |
PostaL | 3:b6d2c5195055 | 154 | }; |
PostaL | 3:b6d2c5195055 | 155 | #endif |