![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
demo program of BMP085 pressure sensor
Revision 6:2c0e7ee70b8b, committed 2012-11-09
- Comitter:
- newk8600
- Date:
- Fri Nov 09 20:05:44 2012 +0000
- Parent:
- 5:34e9a3921278
- Commit message:
- fixed botched revisions
Changed in this revision
diff -r 34e9a3921278 -r 2c0e7ee70b8b BMP085.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BMP085.cpp Fri Nov 09 20:05:44 2012 +0000 @@ -0,0 +1,234 @@ +/* + * @file BMP085.cpp + * @author Tyler Weaver + * @author Kory Hill + * + * @section LICENSE + * + * 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 THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * @section DESCRIPTION + * + * BMP085 I2C Temperature/Pressure/Altitude Sensor + * + * Datasheet: + * + * http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Pressure/BST-BMP085-DS000-06.pdf + */ + +#include "BMP085.h" +#include <new> + +BMP085::BMP085(PinName sda, PinName scl) : i2c_(*reinterpret_cast<I2C*>(i2cRaw)) +{ + // Placement new to avoid additional heap memory allocation. + new(i2cRaw) I2C(sda, scl); + + init(); +} + +BMP085::~BMP085() +{ + // If the I2C object is initialized in the buffer in this object, call destructor of it. + if(&i2c_ == reinterpret_cast<I2C*>(&i2cRaw)) + reinterpret_cast<I2C*>(&i2cRaw)->~I2C(); +} + +void BMP085::init() +{ + get_cal_param(); + set_oss(8); // standard over sampling (2 samples) + get_ut(); // initalize values + get_up(); +} + +void BMP085::get_cal_param() +{ + // get calibration values + AC1 = read_int16(0xAA); + AC2 = read_int16(0xAC); + AC3 = read_int16(0xAE); + AC4 = read_uint16(0xB0); + AC5 = read_uint16(0xB2); + AC6 = read_uint16(0xB4); + B1 = read_int16(0xB6); + B2 = read_int16(0xB8); + MB = read_int16(0xBA); + MC = read_int16(0xBC); + MD = read_int16(0xBE); +} + +void BMP085::display_cal_param(Serial *pc) +{ + pc->printf("AC1 %x\r\n", AC1); + pc->printf("AC2 %x\r\n", AC2); + pc->printf("AC3 %x\r\n", AC3); + pc->printf("AC4 %x\r\n", AC4); + pc->printf("AC5 %x\r\n", AC5); + pc->printf("AC6 %x\r\n", AC6); + pc->printf("B1 %x\r\n", B1); + pc->printf("B2 %x\r\n", B2); + pc->printf("MB %x\r\n", MB); + pc->printf("MC %x\r\n", MC); + pc->printf("MD %x\r\n", MD); +} + +void BMP085::get_ut() +{ + write_char(0xF4,0x2E); + wait(0.045); + char buffer[3]; + read_multiple(0xF6, buffer, 2); + + UT = (buffer[0]<<8) | buffer[1]; +} + +void BMP085::get_up() +{ + // set sample setting + write_char(0xF4, oversampling_setting_); + + // wait + wait(conversion_time_); + + // read the three bits + char buffer[3]; + read_multiple(0xF6, buffer, 3); + + UP = ((buffer[0]<<16) | (buffer[1]<<8) | (buffer[2])) >> (8 - oss_bit_); +} + +void BMP085::set_oss(int oss) +{ + switch(oss) { + case 1: // low power + oss_bit_ = 0; + oversampling_setting_ = 0x34; + conversion_time_ = 0.045; + break; + case 2: // standard + oss_bit_ = 1; + oversampling_setting_ = 0x74; + conversion_time_ = 0.075; + break; + case 4: // high resolution + oss_bit_ = 2; + oversampling_setting_ = 0xB4; + conversion_time_ = 0.135; + break; + case 8: // ultra high resolution + oss_bit_ = 3; + oversampling_setting_ = 0xF4; + conversion_time_ = 0.255; + break; + default: // standard + oss_bit_ = 1; + oversampling_setting_ = 0x74; + conversion_time_ = 0.075; + } +} + +void BMP085::write_char(char address, char data) +{ + char cmd[2]; + cmd[0] = address; + cmd[1] = data; + i2c_.write( I2C_ADDRESS , cmd, 2); +} + +int16_t BMP085::read_int16(char address) +{ + char tx[2]; + tx[0] = address; + i2c_.write(I2C_ADDRESS, tx, 1); + i2c_.read(I2C_ADDRESS, tx, 2); + int16_t value = ((tx[0] << 8) | tx[1]); + return value; +} + +void BMP085::read_multiple(char address, char* buffer, int bits) +{ + char cmd[2]; + cmd[0] = address; + i2c_.write(I2C_ADDRESS, cmd, 1); + i2c_.read(I2C_ADDRESS, buffer, bits); +} + +uint16_t BMP085::read_uint16(char address) +{ + char tx[2]; + tx[0] = address; + i2c_.write(I2C_ADDRESS, tx, 1); + i2c_.read(I2C_ADDRESS, tx, 2); + uint16_t value = ((tx[0] << 8) | tx[1]); + return value; +} + +int32_t BMP085::get_temperature() +{ + get_ut(); // uncompressed temperature + get_up(); // uncompressed pressure + + long x1,x2; + + //Start temperature calculation + x1 = ((UT - AC6) * AC5) >> 15; + x2 = (MC << 11) / (x1 + MD); + B5 = x1 + x2; + temperature = ((B5 + 8) >> 4); + return temperature; +} + +int32_t BMP085::get_pressure() +{ + get_up(); // get uncompressed pressure (uncompressed temperature must be called recently) + + B6 = B5 - 4000; + X1 = (B2 * ((B6 * B6) >> 12)) >> 11; + X2 = (AC2 * B6) >> 11; + X3 = X1 + X2; + B3 = ((((((long)(AC1) * 4) + X3) << oss_bit_) + 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 >> oss_bit_)); + if (B7 < 0x80000000) + pressure = (B7 << 1) / B4; + else + pressure = (B7 / B4) << 1; + + X1 = (pressure >> 8); + X1 *= X1; + X1 = (X1 * 3038) >>16; + X2 = (-7357 * pressure) >>16; + pressure += (X1 + X2 + 3791)>>4; + + return pressure; +} + +double BMP085::get_altitude_m() +{ + const double P0 = 1013.25; //pressure at sea level in hPa + double pres_hpa = pressure / 100.0; + altitude = 44330.0 * (1.0 - pow((pres_hpa/P0), 0.190295)); + return altitude; +} + +double BMP085::get_altitude_ft() +{ + return get_altitude_m()*3.28084; +} \ No newline at end of file
diff -r 34e9a3921278 -r 2c0e7ee70b8b BMP085.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BMP085.h Fri Nov 09 20:05:44 2012 +0000 @@ -0,0 +1,129 @@ +/* + * @file BMP085.h + * @author Tyler Weaver + * @author Kory Hill + * + * @section LICENSE + * + * 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 THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * @section DESCRIPTION + * + * BMP085 I2C Temperature/Pressure/Altitude Sensor + * + * Max sample rate: 128 samples/second (temperature at 1/second) + * + * Datasheet: + * + * http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Pressure/BST-BMP085-DS000-06.pdf + */ + +#ifndef BMP085_H +#define BMP085_H + +#include "mbed.h" + +class BMP085 +{ +public: + /** + * The I2C address that can be passed directly to i2c object (it's already shifted 1 bit left). + */ + static const int16_t I2C_ADDRESS = 0xEE; //address of bmp085 + + /** + * Constructor. + * + * Calls init function + * + * @param sda - mbed pin to use for the SDA I2C line. + * @param scl - mbed pin to use for the SCL I2C line. + */ + BMP085(PinName sda, PinName scl); + + /** + * Constructor that accepts external i2c interface object. + * + * Calls init function + * + * @param i2c The I2C interface object to use. + */ + BMP085(I2C &i2c) : i2c_(i2c) { + init(); + } + + ~BMP085(); + + /** + * Sets the oss rate variables + * Acceptable values = 1,2,4,8 + * + *@param oss the number of over sampling + */ + void set_oss(int oss); + + int32_t get_temperature(); + int32_t get_pressure(); + double get_altitude_m(); + double get_altitude_ft(); + + /** + * Initialize sensor and get calibration values + */ + void init(); + + void display_cal_param(Serial *pc); + +protected: + + +private: + + I2C &i2c_; + + /** + * The raw buffer for allocating I2C object in its own without heap memory. + */ + char i2cRaw[sizeof(I2C)]; + + // calculation variables + int16_t AC1, AC2, AC3, B1, B2, MB, MC, MD; + uint16_t AC4, AC5, AC6; + + int32_t UT,UP; // uncompressed temperature and pressure value + + int32_t X1, X2, B5, temperature; // get_temperature variables + + int32_t B6, B3, X3, pressure; // get_pressure variables + uint32_t B4, B7; + + double altitude; + + // setting variables + char oss_bit_; + char oversampling_setting_; + float conversion_time_; + + void get_cal_param(); // get calibration parameters + void get_ut(); // get uncompressed temperature + void get_up(); // get uncompressed pressure + void write_char(char,char); + int16_t read_int16(char); + uint16_t read_uint16(char); + void read_multiple(char, char*, int); +}; + +#endif \ No newline at end of file
diff -r 34e9a3921278 -r 2c0e7ee70b8b main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Nov 09 20:05:44 2012 +0000 @@ -0,0 +1,192 @@ +/* +* +* 1.8 - 3.6V (Vdd) +* 1.62 - 3.6 (Vddio) +* +* +*Altitude = 44330*(1-(p/p0)^(1/5.255)) +* set p0 to sealevel pressure +* delta p = 1hPa = 8.43m at sea level +* +*/ + +/* +*Pinout: +*pin9 = SDA +*pin10 = SCL +*pin11 = XCLR (digital out; active low; Resets sensor) +*pin12 = EOC ("end of conversation"; signal when conversion finished) +* +*/ + +#include "mbed.h" +#include "BMP085.h" + +I2C i2c(p9, p10); // sda, scl +BMP085 alt_sensor(i2c); +Serial pc(USBTX, USBRX); // tx, rx + +/* +const int bmp085_address = 0xEE; //address of bmp085 +const int P0 = 101325; //pressure at sea level + +void bmp085_calibration(void); +void display_calibration(void); +unsigned short read_short(int,int); + +void write_char(int,int,int); + +long get_raw_temp(void); +void calculations(long); + +float get_temperature(void); +long get_pressure(void); +float get_altitude(long); +*/ + +//short AC1, AC2, AC3, B1, B2, MB, MC, MD, OSS; +//unsigned short AC4, AC5, AC6; + +int main() +{ + pc.baud(9600); + //alt_sensor.display_cal_param(&pc); + while(1) + { + pc.printf("Temperature: %d\r\n", alt_sensor.get_temperature()); + pc.printf("Pressure: %d\r\n", alt_sensor.get_pressure()); + pc.printf("Altitude: %f\r\n", alt_sensor.get_altitude_ft()); + + wait(0.5); + } + //Initialize + //OSS = STANDARD; //change between enums under bmp085_oss for desired Sampling resolution + + //calibrate + //bmp085_calibration(); + //display_calibration(); + + //long raw_temp = get_raw_temp(); + + //calculations(raw_temp); + + //float altitude = get_altitude(pressure); + + //pc.printf("Temperature: %f\n",temperature); + //pc.printf("Pressure: %l\n", pressure); + //pc.printf("Altitude: %f\n", altitude); +} +/* +long get_raw_temp(void) +{ + long raw_temp; + + //Read raw temperature value + write_char(bmp085_address, 0xF4, 0x2E); + wait_ms(4.5); + raw_temp = read_short(bmp085_address, 0xF6); + + return raw_temp; +} + +void calculations(long raw_temp) +{ + long X1, X2, B5; //temperature; + + //Start temperature calculation + X1 = (((long)raw_temp - (long)AC6) * (long)AC5) >> 15; + X2 = ((long)MC << 11) / (X1 + MD); + B5 = X1 + X2; + temperature = ((B5 + 8) >> 4); + + temperature = ((float)temperature / 10.0); + + pc.printf("Temperature: %f\n",temperature); + + + long raw_pressure, B6, B3, X3; + unsigned long B4, B7; + + //Read raw pressure value + write_char(bmp085_address, 0xf4, 0x34 | (OSS << 6)); + wait_ms(5); + raw_pressure = read_short(bmp085_address, 0xF6) >> (8 - OSS); + + //Start Pressure calculation + B6 = B5 - 4000; + X1 = (B2 * (B6 * B6) >> 12) >> 11; + X2 = (AC2 * B6) >> 11; + X3 = X1 + X2; + B3 = (((AC1 * 4 + X3) << OSS + 2) / 4); + 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)(raw_pressure - B3) * (50000 >> OSS)); + if (B7 < 0x80000000) + pressure = (B7 *2) / B4; + else + pressure = (B7 / B4) * 2; + + X1 = (pressure >> 8) * (pressure >>8); + X1 = (X1 * 3038) >>16; + X2 = (-7357 * pressure) >>16; + pressure += (X1 + X2 + 3791)>>4; + + pc.printf("Pressure: %f\n", pressure); + +} + +float get_temperature(void) +{ + return temperature; +} + +long get_pressure(void) +{ + return pressure; +} + +float get_altitude(long pressure) +{ + float altitude; + + altitude = (float)44330 * (1 - pow(( pressure/P0), 0.190295)); + + pc.printf("Altitude: %f\n", altitude); + return altitude; + +} + +void bmp085_calibration(void) +{ + AC1 = read_short(bmp085_address, 0xAA); + AC2 = read_short(bmp085_address, 0xAC); + AC3 = read_short(bmp085_address, 0xAE); + AC4 = read_short(bmp085_address, 0xB0); + AC5 = read_short(bmp085_address, 0xB2); + AC6 = read_short(bmp085_address, 0xB4); + B1 = read_short(bmp085_address, 0xB6); + B2 = read_short(bmp085_address, 0xB8); + MB = read_short(bmp085_address, 0xBA); + MC = read_short(bmp085_address, 0xBC); + MD = read_short(bmp085_address, 0xBE); + +} + +void display_calibration(void) +{ + pc.printf("Calibration Values:\n"); + pc.printf("AC1 = %d\n",AC1); + pc.printf("AC2 = %d\n",AC2); + pc.printf("AC3 = %d\n",AC3); + pc.printf("AC4 = %d\n",AC4); + pc.printf("AC5 = %d\n",AC5); + pc.printf("AC6 = %d\n",AC6); + pc.printf("B1 = %d\n",B1); + pc.printf("B2 = %d\n",B2); + pc.printf("MB = %d\n",MB); + pc.printf("MC = %d\n",MC); + pc.printf("MD = %d\n",MD); +}*/ +
diff -r 34e9a3921278 -r 2c0e7ee70b8b test.cpp --- a/test.cpp Fri Nov 09 19:29:16 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* -* -* -* -* -* -* -* -* -* -* -* -*/ - -#include "mbed.h" -#include "BMP085.h" - - -int main() -{ - - - alt_sensor.display_cal_param(&pc); - - pc.printf("Temperature: %d\r\n", alt_sensor.get_temperature()); - pc.printf("Pressure: %d\r\n", alt_sensor.get_pressure()); - pc.printf("Altitude: %f\r\n", alt_sensor.get_altitude_ft()); -} - -