Bosch BMP085 Barometric Pressure Sensor
Revision 0:e8f53e502a4c, committed 2015-03-19
- Comitter:
- timm
- Date:
- Thu Mar 19 03:46:13 2015 +0000
- Commit message:
- Bosch BMP085 I2C Driver
Changed in this revision
bmp085.cpp | Show annotated file Show diff for this revision Revisions of this file |
bmp085.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bmp085.cpp Thu Mar 19 03:46:13 2015 +0000 @@ -0,0 +1,146 @@ +#include "mbed.h" +#include "bmp085.h" + +BMP085::BMP085(PinName sclPin, PinName sdaPin) +{ + i2c = new I2C(sdaPin, sclPin); + i2c->frequency(1000); // run at 1KHz +} + +long BMP085::getUT() { return UT; } +long BMP085::getUP() { return UP; } +void BMP085::init() { readCalData(); } + +void BMP085::readCalData() +{ + char dataWrite[2]; + char dataRead[2]; + + dataWrite[0] = CAL_DATA_AC1; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + AC1 = ((dataRead[0] << 8) | (dataRead[1])); + + dataWrite[0] = CAL_DATA_AC2; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + AC2 = ((dataRead[0] << 8) | (dataRead[1])); + + dataWrite[0] = CAL_DATA_AC3; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + AC3 = ((dataRead[0] << 8) | (dataRead[1])); + + dataWrite[0] = CAL_DATA_AC4; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + AC4 = ((dataRead[0] << 8) | (dataRead[1])); + + dataWrite[0] = CAL_DATA_AC5; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + AC5 = ((dataRead[0] << 8) | (dataRead[1])); + + dataWrite[0] = CAL_DATA_AC6; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + AC6 = ((dataRead[0] << 8) | (dataRead[1])); + + dataWrite[0] = CAL_DATA_B1; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + B1 = ((dataRead[0] << 8) | (dataRead[1])); + + dataWrite[0] = CAL_DATA_B2; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + B2 = ((dataRead[0] << 8) | (dataRead[1])); + + dataWrite[0] = CAL_DATA_MB; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + MB = ((dataRead[0] << 8) | (dataRead[1])); + + dataWrite[0] = CAL_DATA_MC; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + MC = ((dataRead[0] << 8) | (dataRead[1])); + + dataWrite[0] = CAL_DATA_MD; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + MD = ((dataRead[0] << 8) | (dataRead[1])); +} + +void BMP085::readUncompTemp() +{ + char dataWrite[2]; + char dataRead[2]; + + dataWrite[0] = CTRL_REG_ADDR; + dataWrite[1] = MEASURE_TEMP_CMD; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 2, 0); // stop + wait_ms(5); + dataWrite[0] = DATA_REG_ADDR; + dataWrite[1] = 0; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0); + UT = (long)((dataRead[0] << 8) | (dataRead[1])); +} + +void BMP085::readUncompPressure(int mode) +{ + char dataWrite[2]; + char dataRead[4]; + + dataWrite[0] = CTRL_REG_ADDR; + dataWrite[1] = (MEASURE_PRES_CMD | ((((char)mode) & 0x3) << 6)); + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 2, 0); // stop + wait_ms(10 * (mode + 1)); // TODO: ensure this is accurate, based on oss + dataWrite[0] = DATA_REG_ADDR; + dataWrite[1] = 0; + i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop + i2c->read(BMP085_I2C_ADDR_READ, dataRead, 3, 0); + UP = (long)( ((dataRead[0] << 16) | (dataRead[1] << 8) | dataRead[0]) >> ( 8 - mode)); + //UP = (long)((dataRead[0] << 8) | (dataRead[1])); +} + +float BMP085::getTemperature() +{ + readUncompTemp(); + + X1 = (((long)UT - (long)AC6)*(long)AC5) >> 15; + X2= ((long)MC << 11)/(X1+ MD); + B5 = X1 + X2; + T = ((B5 + 8) >> 4); + + return (float)(T / 10.0); +} + +float BMP085::getPressure(int oss) +{ + readUncompPressure(oss); + + // Calculate B3 + B6 = B5 - 4000; + X1 = (B2 * ((B6 * B6)>>12)) >>11; + X2 = (AC2 * B6)>>11; + X3 = X1 + X2; + B3 = (((((long)AC1) * 4 + X3) << oss) + 2) >> 2; + + // Calculate B4, B7, p + X1 = (AC3 + B6) >> 13; + X2 = (B1 * ((B6 * B6) >> 12)) >> 16; + X3 = ((X1 + X2) + 2 ) >> 2; + B4 = (AC4 * (unsigned long)(X3 + 32768)) >> 15; + B7 = ((unsigned long)(UP - B3) * (50000 >> oss)); + if (B7 < 0x80000000) { p = (B7 << 1) / B4; } + else { p = (B7/B4) << 1; } + + X1 = (p >> 8) * (p >> 8); + X1 = (X1 * 3038) >> 16; + X2 = (-7357 * p) >> 16; + p += ((X1 + X2 + 3791) >> 4); + + return (float)p; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bmp085.h Thu Mar 19 03:46:13 2015 +0000 @@ -0,0 +1,118 @@ +/** +@file bmp085.h + +@brief Header file containing member functions and variables + +*/ + +#ifndef __BMP085_H__ +#define __BMP085_H__ + +#include "mbed.h" + +#define BMP085_I2C_ADDR_READ (0xEF) +#define BMP085_I2C_ADDR_WRITE (0xEE) + +#define CTRL_REG_ADDR (0xF4) +#define DATA_REG_ADDR (0xF6) + +#define MEASURE_TEMP_CMD (0x2E) +#define MEASURE_PRES_CMD (0x34) + +// MSB addresses, MSB first +#define CAL_DATA_AC1 (0xAA) +#define CAL_DATA_AC2 (0xAC) +#define CAL_DATA_AC3 (0xAE) +#define CAL_DATA_AC4 (0xB0) +#define CAL_DATA_AC5 (0xB2) +#define CAL_DATA_AC6 (0xB4) +#define CAL_DATA_B1 (0xB6) +#define CAL_DATA_B2 (0xB8) +#define CAL_DATA_MB (0xBA) +#define CAL_DATA_MC (0xBC) +#define CAL_DATA_MD (0xBE) + + +/** +@brief Simple library for interfacing with Bosch BMP085 + +@brief Revision 1.0 + +@author Tim Meese +@date January 2015 + * + * Example: + * @code + + #include "mbed.h" + #include "bmp085.h" + + + * @endcode + */ + + +class BMP085 +{ + +private: + + // I2C interface + I2C * i2c; + + const float p0 = 101325; // Pressure at sea level (Pa) + float altitude; + + // Calibration parameters + short AC1; + short AC2; + short AC3; + unsigned short AC4; + unsigned short AC5; + unsigned short AC6; + short B1; + short B2; + short MB; + short MC; + short MD; + + // uncalibrated temp, pressure + long UT; + long UP; + + // shared values + long X1; + long X2; + long X3; + long B3; + unsigned long B4; + long B5; + long B6; + unsigned long B7; + long T; // temp in 0.1 degrees C + long p; // pressure in Pascals + + void readCalData(); + void readUncompTemp(); + void readUncompPressure(int mode); + +public: + /** Create a BMP085 object connected to the specified pins + * + * @param clkPin Pin connected to clk + * @param dataPin Pin connected to data + * + */ + BMP085(PinName clkPin, PinName dataPin); + + /** Initialise SHT11 + * + */ + void init(); + float getTemperature(); + float getPressure(int oss); + long getUT(); + long getUP(); +}; + +#endif /* __BMP085_H__ */