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
--- /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
--- /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
--- /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);
+}*/
+
--- 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());
-}
-
-

