Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: LinkNode_TemperatureAdvertising
Fork of BMP180 by
Diff: BMP180.cpp
- Revision:
- 2:5b3e84563dcb
- Parent:
- 1:072073c79cfd
--- a/BMP180.cpp Mon Mar 17 20:42:23 2014 +0000
+++ b/BMP180.cpp Wed Mar 02 05:45:36 2016 +0000
@@ -1,226 +1,268 @@
-/*
- @file BMP180.cpp
-
- @brief Barometric Pressure and Temperature Sensor BMP180 Breakout I2C Library
-
- @Author spiridion (http://mailme.spiridion.net)
-
- Tested on LPC1768 and FRDM-KL25Z
-
- Copyright (c) 2014 spiridion
- Released under the MIT License (see http://mbed.org/license/mit)
-
- Documentation regarding the BMP180 can be found here:
- http://mbed.org/media/uploads/spiridion/bst-bmp180-ds000-09.pdf
-*/
+/*******************************************************************************
+ * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Maxim Integrated
+ * Products, Inc. shall not be used except as stated in the Maxim Integrated
+ * Products, Inc. Branding Policy.
+ *
+ * The mere transfer of this software does not imply any licenses
+ * of trade secrets, proprietary technology, copyrights, patents,
+ * trademarks, maskwork rights, or any other form of intellectual
+ * property whatsoever. Maxim Integrated Products, Inc. retains all
+ * ownership rights.
+ *******************************************************************************
+ */
#include "BMP180.h"
-#include "mbed.h"
+
+/***** Definitions *****/
+#define I2C_ADDR (0xEE) // 1110111x
-// Uncomment to test the documentation algorithm against the documentation example
-// Result should be 699.64 hPa and 15°C
-// #define BMP180_TEST_FORMULA
+#define REG_ADDR_RESET (0xE0)
+#define REG_ADDR_ID (0xD0)
+#define REG_ADDR_CTRL (0xF4)
+#define REG_ADDR_DATA (0xF6)
+#define REG_ADDR_AC1 (0xAA)
-BMP180::BMP180(PinName sda, PinName scl, int address)
- : m_i2c(sda,scl), m_addr(address)
+#define CTRL_REG_TEMP (0x2E)
+#define CTRL_REG_PRESS_0 (0x34)
+#define CTRL_REG_PRESS_1 (0x74)
+#define CTRL_REG_PRESS_2 (0xB4)
+#define CTRL_REG_PRESS_3 (0xF4)
+
+//******************************************************************************
+BMP180::BMP180(PinName sda, PinName scl)
{
- m_altitude = 0;
- m_oss = BMP180_OSS_NORMAL;
- m_temperature = UNSET_BMP180_TEMPERATURE_VALUE;
- m_pressure = UNSET_BMP180_PRESSURE_VALUE;
-}
+ i2c_ = new I2C(sda, scl);
+ i2c_owner = true;
-BMP180::BMP180(I2C& i2c, int address)
- : m_i2c(i2c), m_addr(address)
-{
- m_altitude = 0;
- m_oss = BMP180_OSS_NORMAL;
- m_temperature = UNSET_BMP180_TEMPERATURE_VALUE;
- m_pressure = UNSET_BMP180_PRESSURE_VALUE;
+ i2c_->frequency(400000); //400000
}
-int BMP180::Initialize(float altitude, int overSamplingSetting)
+//******************************************************************************
+BMP180::BMP180(I2C *i2c) :
+ i2c_(i2c)
{
- char data[22];
- int errors = 0;
-
- m_altitude = altitude;
- m_oss = overSamplingSetting;
- m_temperature = UNSET_BMP180_TEMPERATURE_VALUE;
- m_pressure = UNSET_BMP180_PRESSURE_VALUE;
-
- // read calibration data
- data[0]=0xAA;
- errors = m_i2c.write(m_addr, data, 1); // set the eeprom pointer position to 0xAA
- errors += m_i2c.read(m_addr, 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];
- mc = data[18] << 8 | data[19];
- md = data[20] << 8 | data[21];
+ i2c_owner = false;
+}
-#ifdef BMP180_TEST_FORMULA
- ac1 = 408;
- ac2 = -72;
- ac3 = -14383;
- ac4 = 32741;
- ac5 = 32757;
- ac6 = 23153;
- b1 = 6190;
- b2 = 4;
- mb = -32768;
- mc = -8711;
- md = 2868;
- m_oss = 0;
- errors = 0;
-#endif // #ifdef BMP180_TEST_FORMULA
-
- return errors? 0 : 1;
+//******************************************************************************
+BMP180::~BMP180()
+{
+ if(i2c_owner) {
+ delete i2c_;
+ }
}
-int BMP180::ReadData(float* pTemperature, float* pPressure)
+//******************************************************************************
+int BMP180::init(void)
{
- long t, p;
+ char addr;
+ char data[22];
+ int i;
- if (!ReadRawTemperature(&t) || !ReadRawPressure(&p))
- {
- m_temperature = UNSET_BMP180_TEMPERATURE_VALUE;
- m_pressure = UNSET_BMP180_PRESSURE_VALUE;
- return 0;
+ if (checkId() != 0) {
+ return -1;
+ }
+
+ addr = REG_ADDR_AC1;
+ if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
+ return -1;
+ }
+
+ if (i2c_->read(I2C_ADDR, data, 22) != 0) {
+ return -1;
}
- m_temperature = TrueTemperature(t);
- m_pressure = TruePressure(p);
+ for (i = 0; i < 11; i++) {
+ calib.value[i] = (data[2*i] << 8) | data[(2*i)+1];
+ }
+
+ return 0;
+}
+
+//******************************************************************************
+int BMP180::reset(void)
+{
+ char data;
- if (pPressure)
- *pPressure = m_pressure;
- if (pTemperature)
- *pTemperature = m_temperature;
+ data = REG_ADDR_RESET;
+ if (i2c_->write(I2C_ADDR, &data, 1) != 0) {
+ return -1;
+ }
- return 1;
+ data = 0xB6;
+ if (i2c_->write(I2C_ADDR, &data, 1) != 0) {
+ return -1;
+ }
+
+ return 0;
}
-int BMP180::ReadRawTemperature(long* pUt)
+//******************************************************************************
+int BMP180::checkId(void)
{
- int errors = 0;
- char data[2];
-
- // request temperature measurement
- data[0] = 0xF4;
- data[1] = 0x2E;
- errors = m_i2c.write(m_addr, data, 2); // write 0XF2 into reg 0XF4
-
- wait_ms(4.5F);
+ char addr;
+ char data;
- // read raw temperature data
- data[0] = 0xF6;
- errors += m_i2c.write(m_addr, data, 2); // set eeprom pointer position to 0XF6
- errors += m_i2c.read(m_addr, data, 2); // get 16 bits at this position
-
-#ifdef BMP180_TEST_FORMULA
- errors = 0;
-#endif // #ifdef BMP180_TEST_FORMULA
+ addr = REG_ADDR_ID;
+ if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
+ return -1;
+ }
- if (errors)
- return 0;
- else
- *pUt = data[0] << 8 | data[1];
+ if (i2c_->read(I2C_ADDR, &data, 1) != 0) {
+ return -1;
+ }
-#ifdef BMP180_TEST_FORMULA
- *pUt = 27898;
-#endif // #ifdef BMP180_TEST_FORMULA
-
- return 1;
+ if (data != 0x55) {
+ return -1;
+ }
+
+ return 0;
}
-int BMP180::ReadRawPressure(long* pUp)
+//******************************************************************************
+int BMP180::startPressure(BMP180::oversampling_t oss)
{
- int errors = 0;
char data[2];
-
- // request pressure measurement
- data[0] = 0xF4;
- data[1] = 0x34 + (m_oss << 6);
- errors = m_i2c.write(m_addr, data, 2); // write 0x34 + (m_oss << 6) into reg 0XF4
+
+ data[0] = REG_ADDR_CTRL;
+ data[1] = CTRL_REG_PRESS_0 | ((oss & 0x3) << 6);
+ oss_ = oss;
+
+ if (i2c_->write(I2C_ADDR, data, 2) != 0) {
+ return -1;
+ }
+
+ return 0;
+}
- switch (m_oss)
- {
- case BMP180_OSS_ULTRA_LOW_POWER: wait_ms(4.5); break;
- case BMP180_OSS_NORMAL: wait_ms(7.5); break;
- case BMP180_OSS_HIGH_RESOLUTION: wait_ms(13.5); break;
- case BMP180_OSS_ULTRA_HIGH_RESOLUTION: wait_ms(25.5); break;
+//******************************************************************************
+int BMP180::getPressure(int *pressure)
+{
+ char addr, byte[3];
+ uint32_t up;
+ int32_t b6, x1, x2, x3, b3, p;
+ uint32_t b4, b7;
+
+ addr = REG_ADDR_DATA;
+ if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
+ return -1;
+ }
+
+ if (i2c_->read(I2C_ADDR, byte, 3) != 0) {
+ return -1;
}
- // read raw pressure data
- data[0] = 0xF6;
- errors += m_i2c.write(m_addr, data, 1); // set eeprom pointer position to 0XF6
- errors += m_i2c.read(m_addr, data, 2); // get 16 bits at this position
-
-#ifdef BMP180_TEST_FORMULA
- errors = 0;
-#endif // #ifdef BMP180_TEST_FORMULA
+ up = ((byte[0] << 16) | (byte[1] << 8) | byte[2]) >> (8 - oss_);
+
+ b6 = b5 - 4000;
+ x1 = (b6 * b6) >> 12;
+ x1 *= calib.b2;
+ x1 >>= 11;
+ x2 = calib.ac2 * b6;
+ x2 >>= 11;
+ x3 = x1 + x2;
+ b3 = (((((int32_t)calib.ac1) * 4 + x3) << oss_) + 2);
+ b3 >>= 2;
- if (errors)
- return 0;
- else
- *pUp = (data[0] << 16 | data[1] << 8) >> (8 - m_oss);
-#ifdef BMP180_TEST_FORMULA
- *pUp = 23843;
-#endif // #ifdef BMP180_TEST_FORMULA
+ x1 = (calib.ac3 * b6) >> 13;
+ x2 = (calib.b1 * ((b6 * b6) >> 12)) >> 16;
+ x3 = (x1 + x2 + 2) >> 2;
+ b4 = (calib.ac4 * (uint32_t)(x3 + 32768)) >> 15;
+ b7 = ((uint32_t)up - b3) * (50000 >> oss_);
+ p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
+ x1 = p >> 8;
+ x1 *= x1;
+ x1 = (x1 * 3038) >> 16;
+ x2 = (-7357 * p) >> 16;
+ p += (x1 + x2 + 3791) >> 4;
+
+ *pressure = p;
- return 1;
+ return 0;
+}
+
+//******************************************************************************
+int BMP180::startTemperature(void)
+{
+ char data[2] = { REG_ADDR_CTRL, CTRL_REG_TEMP };
+
+ if (i2c_->write(I2C_ADDR, data, 2) != 0) {
+ return -1;
+ }
+
+ return 0;
}
-float BMP180::TrueTemperature(long ut)
+//******************************************************************************
+int BMP180::getTemperature(float *tempC)
{
- long t;
-
- // straight out from the documentation
- x1 = ((ut - ac6) * ac5) >> 15;
- x2 = ((long)mc << 11) / (x1 + md);
+ char addr, byte[2];
+ uint16_t ut;
+ int32_t x1, x2;
+
+ addr = REG_ADDR_DATA;
+ if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
+ return -1;
+ }
+
+ if (i2c_->read(I2C_ADDR, byte, 2) != 0) {
+ return -1;
+ }
+
+ ut = (byte[0] << 8) | byte[1];
+
+ x1 = ((ut - calib.ac6) * calib.ac5) >> 15;
+ x2 = (calib.mc << 11) / (x1 + calib.md);
b5 = x1 + x2;
- t = (b5 + 8) >> 4;
- // convert to celcius
- return t / 10.F;
+ *tempC = (float)(b5 + 8) / 160;
+
+ return 0;
}
-float BMP180::TruePressure(long up)
+//******************************************************************************
+int BMP180::getTemperature(int16_t *tempCx10)
{
- long p;
-
- // straight out from the documentation
- b6 = b5 - 4000;
- x1 = (b2 * (b6 * b6 >> 12)) >> 11;
- x2 = ac2 * b6 >> 11;
- x3 = x1 + x2;
- b3 = (((ac1 * 4 + x3) << 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);
+ char addr, byte[2];
+ uint16_t ut;
+ int32_t x1, x2;
+
+ addr = REG_ADDR_DATA;
+ if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
+ return -1;
+ }
- // convert to hPa and, if altitude has been initialized, to sea level pressure
- if (m_altitude == 0.F)
- return p / 100.F;
- else
- return p / (100.F * pow((1.F - m_altitude / 44330.0L), 5.255L));
-}
\ No newline at end of file
+ if (i2c_->read(I2C_ADDR, byte, 2) != 0) {
+ return -1;
+ }
+
+ ut = (byte[0] << 8) | byte[1];
+
+ x1 = ((ut - calib.ac6) * calib.ac5) >> 15;
+ x2 = (calib.mc << 11) / (x1 + calib.md);
+ b5 = x1 + x2;
+
+ *tempCx10 = (b5 + 8) >> 4;
+
+ return 0;
+}
