Pressure, Temperature, Altitude Sensor on breakout from sparkfun (I2C)
Embed:
(wiki syntax)
Show/hide line numbers
BMP085.cpp
00001 /* 00002 * @file BMP085.cpp 00003 * @author Tyler Weaver 00004 * @author Kory Hill 00005 * 00006 * @section LICENSE 00007 * 00008 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00009 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00010 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00011 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00012 * furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included in all copies or 00015 * substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00018 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00020 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00022 * 00023 * @section DESCRIPTION 00024 * 00025 * BMP085 I2C Temperature/Pressure/Altitude Sensor 00026 * 00027 * Datasheet: 00028 * 00029 * http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Pressure/BST-BMP085-DS000-06.pdf 00030 */ 00031 00032 #include "BMP085.h" 00033 #include <new> 00034 00035 BMP085::BMP085(PinName sda, PinName scl) : i2c_(*reinterpret_cast<I2C*>(i2cRaw)) 00036 { 00037 // Placement new to avoid additional heap memory allocation. 00038 new(i2cRaw) I2C(sda, scl); 00039 00040 init(); 00041 } 00042 00043 BMP085::~BMP085() 00044 { 00045 // If the I2C object is initialized in the buffer in this object, call destructor of it. 00046 if(&i2c_ == reinterpret_cast<I2C*>(&i2cRaw)) 00047 reinterpret_cast<I2C*>(&i2cRaw)->~I2C(); 00048 } 00049 00050 void BMP085::init() 00051 { 00052 get_cal_param(); 00053 set_oss(8); // standard over sampling (2 samples) 00054 get_ut(); // initalize values 00055 get_up(); 00056 } 00057 00058 void BMP085::get_cal_param() 00059 { 00060 // get calibration values 00061 AC1 = read_int16(0xAA); 00062 AC2 = read_int16(0xAC); 00063 AC3 = read_int16(0xAE); 00064 AC4 = read_uint16(0xB0); 00065 AC5 = read_uint16(0xB2); 00066 AC6 = read_uint16(0xB4); 00067 B1 = read_int16(0xB6); 00068 B2 = read_int16(0xB8); 00069 MB = read_int16(0xBA); 00070 MC = read_int16(0xBC); 00071 MD = read_int16(0xBE); 00072 } 00073 00074 void BMP085::display_cal_param(Serial *pc) 00075 { 00076 pc->printf("AC1 %x\r\n", AC1); 00077 pc->printf("AC2 %x\r\n", AC2); 00078 pc->printf("AC3 %x\r\n", AC3); 00079 pc->printf("AC4 %x\r\n", AC4); 00080 pc->printf("AC5 %x\r\n", AC5); 00081 pc->printf("AC6 %x\r\n", AC6); 00082 pc->printf("B1 %x\r\n", B1); 00083 pc->printf("B2 %x\r\n", B2); 00084 pc->printf("MB %x\r\n", MB); 00085 pc->printf("MC %x\r\n", MC); 00086 pc->printf("MD %x\r\n", MD); 00087 } 00088 00089 void BMP085::get_ut() 00090 { 00091 write_char(0xF4,0x2E); 00092 wait(0.045); 00093 char buffer[3]; 00094 read_multiple(0xF6, buffer, 2); 00095 00096 UT = (buffer[0]<<8) | buffer[1]; 00097 } 00098 00099 void BMP085::get_up() 00100 { 00101 // set sample setting 00102 write_char(0xF4, oversampling_setting_); 00103 00104 // wait 00105 wait(conversion_time_); 00106 00107 // read the three bits 00108 char buffer[3]; 00109 read_multiple(0xF6, buffer, 3); 00110 00111 UP = ((buffer[0]<<16) | (buffer[1]<<8) | (buffer[2])) >> (8 - oss_bit_); 00112 } 00113 00114 void BMP085::set_oss(int oss) 00115 { 00116 switch(oss) { 00117 case 1: // low power 00118 oss_bit_ = 0; 00119 oversampling_setting_ = 0x34; 00120 conversion_time_ = 0.045; 00121 break; 00122 case 2: // standard 00123 oss_bit_ = 1; 00124 oversampling_setting_ = 0x74; 00125 conversion_time_ = 0.075; 00126 break; 00127 case 4: // high resolution 00128 oss_bit_ = 2; 00129 oversampling_setting_ = 0xB4; 00130 conversion_time_ = 0.135; 00131 break; 00132 case 8: // ultra high resolution 00133 oss_bit_ = 3; 00134 oversampling_setting_ = 0xF4; 00135 conversion_time_ = 0.255; 00136 break; 00137 default: // standard 00138 oss_bit_ = 1; 00139 oversampling_setting_ = 0x74; 00140 conversion_time_ = 0.075; 00141 } 00142 } 00143 00144 void BMP085::write_char(char address, char data) 00145 { 00146 char cmd[2]; 00147 cmd[0] = address; 00148 cmd[1] = data; 00149 i2c_.write( I2C_ADDRESS , cmd, 2); 00150 } 00151 00152 int16_t BMP085::read_int16(char address) 00153 { 00154 char tx[2]; 00155 tx[0] = address; 00156 i2c_.write(I2C_ADDRESS, tx, 1); 00157 i2c_.read(I2C_ADDRESS, tx, 2); 00158 int16_t value = ((tx[0] << 8) | tx[1]); 00159 return value; 00160 } 00161 00162 void BMP085::read_multiple(char address, char* buffer, int bits) 00163 { 00164 char cmd[2]; 00165 cmd[0] = address; 00166 i2c_.write(I2C_ADDRESS, cmd, 1); 00167 i2c_.read(I2C_ADDRESS, buffer, bits); 00168 } 00169 00170 uint16_t BMP085::read_uint16(char address) 00171 { 00172 char tx[2]; 00173 tx[0] = address; 00174 i2c_.write(I2C_ADDRESS, tx, 1); 00175 i2c_.read(I2C_ADDRESS, tx, 2); 00176 uint16_t value = ((tx[0] << 8) | tx[1]); 00177 return value; 00178 } 00179 00180 int32_t BMP085::get_temperature() 00181 { 00182 get_ut(); // uncompressed temperature 00183 get_up(); // uncompressed pressure 00184 00185 long x1,x2; 00186 00187 //Start temperature calculation 00188 x1 = ((UT - AC6) * AC5) >> 15; 00189 x2 = (MC << 11) / (x1 + MD); 00190 B5 = x1 + x2; 00191 temperature = ((B5 + 8) >> 4); 00192 return temperature; 00193 } 00194 00195 int32_t BMP085::get_pressure() 00196 { 00197 get_up(); // get uncompressed pressure (uncompressed temperature must be called recently) 00198 00199 B6 = B5 - 4000; 00200 X1 = (B2 * ((B6 * B6) >> 12)) >> 11; 00201 X2 = (AC2 * B6) >> 11; 00202 X3 = X1 + X2; 00203 B3 = ((((((long)(AC1) * 4) + X3) << oss_bit_) + 2) >> 2); 00204 X1 = (AC3 * B6) >> 13; 00205 X2 = (B1 * ((B6 * B6) >> 12)) >> 16; 00206 X3 = ((X1 + X2) + 2) >> 2; 00207 B4 = (AC4 * (unsigned long)(X3 + 32768)) >> 15; 00208 B7 = ((unsigned long)(UP - B3) * (50000 >> oss_bit_)); 00209 if (B7 < 0x80000000) 00210 pressure = (B7 << 1) / B4; 00211 else 00212 pressure = (B7 / B4) << 1; 00213 00214 X1 = (pressure >> 8); 00215 X1 *= X1; 00216 X1 = (X1 * 3038) >>16; 00217 X2 = (-7357 * pressure) >>16; 00218 pressure += (X1 + X2 + 3791)>>4; 00219 00220 return pressure; 00221 } 00222 00223 double BMP085::get_altitude_m() 00224 { 00225 const double P0 = 1013.25; //pressure at sea level in hPa 00226 double pres_hpa = pressure / 100.0; 00227 altitude = 44330.0 * (1.0 - pow((pres_hpa/P0), 0.190295)); 00228 return altitude; 00229 } 00230 00231 double BMP085::get_altitude_ft() 00232 { 00233 return get_altitude_m()*3.28084; 00234 }
Generated on Wed Jul 13 2022 10:31:14 by 1.7.2