BMP180 Pressure/Temperature Sensor library

Dependents:   LinkNode_TemperatureAdvertising

Fork of BMP180 by Spiridion Mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BMP180.cpp Source File

BMP180.cpp

00001 /*******************************************************************************
00002  * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017  * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020  * OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  * Except as contained in this notice, the name of Maxim Integrated
00023  * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024  * Products, Inc. Branding Policy.
00025  *
00026  * The mere transfer of this software does not imply any licenses
00027  * of trade secrets, proprietary technology, copyrights, patents,
00028  * trademarks, maskwork rights, or any other form of intellectual
00029  * property whatsoever. Maxim Integrated Products, Inc. retains all
00030  * ownership rights.
00031  *******************************************************************************
00032  */
00033 
00034 #include "BMP180.h"
00035 
00036 /***** Definitions *****/
00037 #define I2C_ADDR            (0xEE) // 1110111x
00038 
00039 #define REG_ADDR_RESET      (0xE0)
00040 #define REG_ADDR_ID         (0xD0)
00041 #define REG_ADDR_CTRL       (0xF4)
00042 #define REG_ADDR_DATA       (0xF6)
00043 #define REG_ADDR_AC1        (0xAA)
00044 
00045 #define CTRL_REG_TEMP       (0x2E)
00046 #define CTRL_REG_PRESS_0    (0x34)
00047 #define CTRL_REG_PRESS_1    (0x74)
00048 #define CTRL_REG_PRESS_2    (0xB4)
00049 #define CTRL_REG_PRESS_3    (0xF4)
00050 
00051 //******************************************************************************
00052 BMP180::BMP180(PinName sda, PinName scl)
00053 {
00054     i2c_ = new I2C(sda, scl);
00055     i2c_owner = true;
00056 
00057     i2c_->frequency(400000);  //400000
00058 }
00059 
00060 //******************************************************************************
00061 BMP180::BMP180(I2C *i2c) :
00062     i2c_(i2c)
00063 {
00064     i2c_owner = false;
00065 }
00066 
00067 //******************************************************************************
00068 BMP180::~BMP180()
00069 {
00070     if(i2c_owner) {
00071         delete i2c_;
00072     }
00073 }
00074 
00075 //******************************************************************************
00076 int BMP180::init(void)
00077 {
00078     char addr;
00079     char data[22];
00080     int i;
00081 
00082     if (checkId() != 0) {
00083         return -1;
00084     }
00085 
00086     addr = REG_ADDR_AC1;
00087     if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
00088         return -1;
00089     }
00090 
00091     if (i2c_->read(I2C_ADDR, data, 22) != 0) {
00092         return -1;
00093     }
00094 
00095     for (i = 0; i < 11; i++) {
00096         calib.value[i] = (data[2*i] << 8) | data[(2*i)+1];
00097     }
00098 
00099     return 0;
00100 }
00101 
00102 //******************************************************************************
00103 int BMP180::reset(void)
00104 {
00105     char data;
00106 
00107     data = REG_ADDR_RESET;
00108     if (i2c_->write(I2C_ADDR, &data, 1) != 0) {
00109         return -1;
00110     }
00111 
00112     data = 0xB6;
00113     if (i2c_->write(I2C_ADDR, &data, 1) != 0) {
00114         return -1;
00115     }
00116 
00117     return 0;
00118 }
00119 
00120 //******************************************************************************
00121 int BMP180::checkId(void)
00122 {
00123     char addr;
00124     char data;
00125 
00126     addr = REG_ADDR_ID;
00127     if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
00128         return -1;
00129     }
00130 
00131     if (i2c_->read(I2C_ADDR, &data, 1) != 0) {
00132         return -1;
00133     }
00134 
00135     if (data != 0x55) {
00136         return -1;
00137     }
00138 
00139     return 0;
00140 }
00141 
00142 //******************************************************************************
00143 int BMP180::startPressure(BMP180::oversampling_t oss)
00144 {
00145     char data[2];
00146 
00147     data[0] = REG_ADDR_CTRL;
00148     data[1] = CTRL_REG_PRESS_0 | ((oss & 0x3) << 6);
00149     oss_ = oss;
00150 
00151     if (i2c_->write(I2C_ADDR, data, 2) != 0) {
00152         return -1;
00153     }
00154 
00155     return 0;
00156 }
00157 
00158 //******************************************************************************
00159 int BMP180::getPressure(int *pressure)
00160 {
00161     char addr, byte[3];
00162     uint32_t up;
00163     int32_t b6, x1, x2, x3, b3, p;
00164     uint32_t b4, b7;
00165 
00166     addr = REG_ADDR_DATA;
00167     if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
00168         return -1;
00169     }
00170 
00171     if (i2c_->read(I2C_ADDR, byte, 3) != 0) {
00172         return -1;
00173     }
00174 
00175     up = ((byte[0] << 16) | (byte[1] << 8) | byte[2]) >> (8 - oss_);
00176 
00177     b6 = b5 - 4000;
00178     x1 = (b6 * b6) >> 12;
00179     x1 *= calib.b2;
00180     x1 >>= 11;
00181     x2 = calib.ac2 * b6;
00182     x2 >>= 11;
00183     x3 = x1 + x2;
00184     b3 = (((((int32_t)calib.ac1) * 4 + x3) << oss_) + 2);
00185     b3 >>= 2;
00186 
00187     x1 = (calib.ac3 * b6) >> 13;
00188     x2 = (calib.b1 * ((b6 * b6) >> 12)) >> 16;
00189     x3 = (x1 + x2 + 2) >> 2;
00190     b4 = (calib.ac4 * (uint32_t)(x3 + 32768)) >> 15;
00191     b7 = ((uint32_t)up - b3) * (50000 >> oss_);
00192     p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
00193     x1 = p >> 8;
00194     x1 *= x1;
00195     x1 = (x1 * 3038) >> 16;
00196     x2 = (-7357 * p) >> 16;
00197     p += (x1 + x2 + 3791) >> 4;
00198 
00199     *pressure = p;
00200 
00201     return 0;
00202 }
00203 
00204 //******************************************************************************
00205 int BMP180::startTemperature(void)
00206 {
00207     char data[2] = { REG_ADDR_CTRL, CTRL_REG_TEMP };
00208 
00209     if (i2c_->write(I2C_ADDR, data, 2) != 0) {
00210         return -1;
00211     }
00212 
00213     return 0;
00214 }
00215 
00216 //******************************************************************************
00217 int BMP180::getTemperature(float *tempC)
00218 {
00219     char addr, byte[2];
00220     uint16_t ut;
00221     int32_t x1, x2;
00222 
00223     addr = REG_ADDR_DATA;
00224     if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
00225         return -1;
00226     }
00227 
00228     if (i2c_->read(I2C_ADDR, byte, 2) != 0) {
00229         return -1;
00230     }
00231 
00232     ut = (byte[0] << 8) | byte[1];
00233 
00234     x1 = ((ut - calib.ac6) * calib.ac5) >> 15;
00235     x2 = (calib.mc << 11) / (x1 + calib.md);
00236     b5 = x1 + x2;
00237 
00238     *tempC = (float)(b5 + 8) / 160;
00239 
00240     return 0;
00241 }
00242 
00243 //******************************************************************************
00244 int BMP180::getTemperature(int16_t *tempCx10)
00245 {
00246     char addr, byte[2];
00247     uint16_t ut;
00248     int32_t x1, x2;
00249 
00250     addr = REG_ADDR_DATA;
00251     if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
00252         return -1;
00253     }
00254 
00255     if (i2c_->read(I2C_ADDR, byte, 2) != 0) {
00256         return -1;
00257     }
00258 
00259     ut = (byte[0] << 8) | byte[1];
00260 
00261     x1 = ((ut - calib.ac6) * calib.ac5) >> 15;
00262     x2 = (calib.mc << 11) / (x1 + calib.md);
00263     b5 = x1 + x2;
00264 
00265     *tempCx10 = (b5 + 8) >> 4;
00266 
00267     return 0;
00268 }