Bosch BMP085 Barometric Pressure Sensor

Files at this revision

API Documentation at this revision

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
diff -r 000000000000 -r e8f53e502a4c bmp085.cpp
--- /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
diff -r 000000000000 -r e8f53e502a4c bmp085.h
--- /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__ */