Library to control a BMP180 sensor.

BMP180 sensor

Revision:
0:373de0f4d5cd
Child:
1:608e890e88e7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BMP180.cpp	Fri Aug 26 00:19:21 2016 +0000
@@ -0,0 +1,138 @@
+/*
+  @file BMP180.cpp
+  @brief Barometric Pressure and Temperature Sensor BMP180 Breakout I2C Library
+*/
+
+#include "BMP180.h"
+
+BMP180::BMP180(I2C& i2c) : m_i2c(i2c) {
+    m_altitude      = 0;
+    m_oss           = STANDARD;
+}
+
+int BMP180::initialize(float altitude, OverSamplingSetting oss) {
+    char data[22];
+    int errors = 0;
+
+    m_altitude      = altitude;
+    m_oss           = oss;
+
+    // read calibration data
+    data[0]=0xAA;
+    errors = m_i2c.write(BMP180_I2C_ADDRESS, data, 1);  // set the eeprom pointer position to 0xAA
+    errors += m_i2c.read(BMP180_I2C_ADDRESS, data, 22); // read 11 x 16 bits at this position
+    wait_ms(10);
+
+    // store calibration data for further calculus
+    ac1 = data[0]  << 8 | data[1];
+    ac2 = data[2]  << 8 | data[3];
+    ac3 = data[4]  << 8 | data[5];
+    ac4 = data[6]  << 8 | data[7];
+    ac5 = data[8]  << 8 | data[9];
+    ac6 = data[10] << 8 | data[11];
+    b1  = data[12] << 8 | data[13];
+    b2  = data[14] << 8 | data[15];
+    //mb  = data[16] << 8 | data[17];   // Not used?
+    mc  = data[18] << 8 | data[19];
+    md  = data[20] << 8 | data[21];
+
+    // Pre-calc
+    ac1 = ac1 << 2;
+    mc  = mc  << 11;
+
+    return errors == 0; // 0 = ACK = success
+}
+
+int BMP180::ReadData(float& pTemperature, float& pPressure) {
+    long t, p;
+
+    if (!ReadRawTemperature(&t) || !ReadRawPressure(&p))
+        return 0;   // Error
+
+    pTemperature    = TrueTemperature(t);
+    pPressure       = TruePressure(p);
+
+    return 1;
+}
+
+int BMP180::ReadRawTemperature(long* pUt) {
+    int errors = 0;
+
+    // request temperature measurement
+    m_data[0] = 0xF4;
+    m_data[1] = 0x2E;
+    errors = m_i2c.write(BMP180_I2C_ADDRESS, m_data, 2); // write 0XF2 into reg 0XF4
+
+    wait_ms(5);
+
+    // read raw temperature data
+    m_data[0] = 0xF6;
+    errors += m_i2c.write(BMP180_I2C_ADDRESS, m_data, 2); // set eeprom pointer position to 0XF6
+    errors += m_i2c.read(BMP180_I2C_ADDRESS, m_data, 2);  // get 16 bits at this position
+
+    if (errors) return 0;
+    *pUt = m_data[0] << 8 | m_data[1];
+
+    return 1;
+}
+
+int BMP180::ReadRawPressure(long* pUp) {
+    int errors = 0;
+
+    // request pressure measurement
+    m_data[0] = 0xF4;
+    m_data[1] = 0x34 + (m_oss << 6);
+    errors = m_i2c.write(BMP180_I2C_ADDRESS, m_data, 2); // write 0x34 + (m_oss << 6) into reg 0XF4
+
+    switch (m_oss) {    // Rounded up wait times to be safe
+        case ULTRA_LOW_POWER:        wait_ms(5); break;
+        case STANDARD:               wait_ms(8); break;
+        case HIGH_RESOLUTION:        wait_ms(14); break;
+        case ULTRA_HIGH_RESOLUTION:  wait_ms(26); break;
+    }
+
+    // read raw pressure data
+    m_data[0] = 0xF6;
+    errors += m_i2c.write(BMP180_I2C_ADDRESS, m_data, 1); // set eeprom pointer position to 0XF6
+    errors += m_i2c.read(BMP180_I2C_ADDRESS, m_data, 2);  // get 16 bits at this position
+
+    if (errors) return 0;
+    *pUp = (m_data[0] << 16 | m_data[1] << 8) >> (8 - m_oss);
+
+    return 1;
+}
+
+float BMP180::TrueTemperature(long ut) {
+    // straight out from the documentation
+    x1 = ((ut - ac6) * ac5) >> 15;
+    x2 = mc / (x1 + md);
+    b5 = x1 + x2;
+
+    // convert to Celsius
+    return (long)((b5 + 8) >> 4) / 10.F;
+}
+
+float BMP180::TruePressure(long up) {
+    long p;
+
+    // straight out from the documentation
+    b6 = b5 - 4000;
+    x1 = (b2 * (b6 * b6 >> 12)) >> 11;
+    x2 = ac2 * b6 >> 11;
+    b3 = (((ac1 + x1 + x2) << m_oss) + 2) >> 2;
+    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 >> m_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 = p + ((x1 + x2 + 3791) >> 4);
+
+    // convert to hPa and, if altitude has been initialized, to sea level pressure
+    return (m_altitude == 0.F) ? p / 100.F
+                               : p / (100.F * pow((1.F - m_altitude / 44330.0L), 5.255L));
+}