BMP180 and BLE

Dependencies:   BLE_API mbed nRF51822

Fork of WeatherStation by Weather man

Committer:
phivari
Date:
Wed Jan 10 16:42:44 2018 +0000
Revision:
6:25ed8e2df02e
Parent:
3:b6d2c5195055
WeatherStation_BLE_BMP180

Who changed what in which revision?

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