BMP085 Digital, barometric pressure sensor. Manufacturer: Bosch Sensortec.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bmp085.cpp Source File

bmp085.cpp

00001 #include "bmp085.h"
00002 #include "mbed.h"
00003 #include "math.h"
00004 
00005 #define BMP085_ADDR 0xee
00006 
00007 const float BMP085::p0 = 1013.25;
00008 float BMP085::altitude(float p)
00009 {
00010     return (float)(44330.0 * (1.0 - pow((double)p/p0, 1/5.255)));
00011 }
00012     
00013 BMP085::BMP085(PinName sda, PinName scl): m_i2c(sda, scl), 
00014     m_addr(BMP085_ADDR), oss(0)
00015 {
00016     // calibration
00017     uint8_t bmp085_cali_regs[] = {0xAA,0xAC,0xAE,0xB0,0xB2,0xB4,0xB6,0xB8,0xBA,0xBC,0xBE,0};
00018     uint8_t *ptr = bmp085_cali_regs;
00019     int16_t bmp085_value[11]={0};
00020     int i = 0;
00021     uint8_t data[2];
00022     
00023     while(*ptr)
00024     {
00025         readRegs(*ptr, data, 2);
00026     
00027         bmp085_value[i++] = (data[0] << 8) | data[1];
00028         
00029         ptr++;
00030     }
00031     
00032     ac1 = bmp085_value[0];
00033     ac2 = bmp085_value[1];
00034     ac3 = bmp085_value[2];
00035     ac4 = (uint16_t)bmp085_value[3];
00036     ac5 = (uint16_t)bmp085_value[4];
00037     ac6 = (uint16_t)bmp085_value[5];
00038     b1 = bmp085_value[6];
00039     b2 = bmp085_value[7];
00040     mb = bmp085_value[8];
00041     mc = bmp085_value[9];
00042     md = bmp085_value[10];
00043     
00044     /*printf("\tAC1 = %d\r\n", ac1);
00045     printf("\tAC2 = %d\r\n", ac2);
00046     printf("\tAC3 = %d\r\n", ac3);
00047     printf("\tAC4 = %d\r\n", ac4);
00048     printf("\tAC5 = %d\r\n", ac5);
00049     printf("\tAC6 = %d\r\n", ac6);
00050     printf("\tB1 = %d\r\n", b1);
00051     printf("\tB2 = %d\r\n", b2);
00052     printf("\tMB = %d\r\n", mb);
00053     printf("\tMC = %d\r\n", mc);
00054     printf("\tMD = %d\r\n", md);
00055     printf("------------------------\r\n");*/
00056 }
00057 
00058 void BMP085::set_oversampling(int osrs)
00059 {
00060     if(osrs > 0 && osrs < 4)
00061     {
00062         oss = osrs;
00063     }
00064 }
00065     
00066 void BMP085::readRegs(int addr, uint8_t * data, int len)
00067 {
00068     char t[1] = {addr};
00069     
00070     m_i2c.write(m_addr, t, 1, true);
00071     m_i2c.read(m_addr, (char *)data, len);
00072 }
00073 
00074 void BMP085::writeRegs(uint8_t * data, int len)
00075 {
00076     m_i2c.write(m_addr, (char *)data, len);
00077 }
00078 
00079 int32_t BMP085::read_temp(void)
00080 {
00081     uint8_t data[2] = {0xf4, 0x2e};
00082     
00083     // write 0x2e into reg 0xf4
00084     writeRegs(data, 2);
00085     
00086     // wait 4.5ms
00087     wait_us(4500);
00088     
00089     // read reg 0xf6(MSB), 0xf7(LSB)
00090     readRegs(0xf6, data, 2);
00091     
00092     // UT = (MSB << 8) + LSB
00093     return (data[0] << 8) | data[1];
00094 }
00095 
00096 int32_t BMP085::read_pressure(void)
00097 {
00098     static int delay_ms[] = {4500, 7500, 13500, 25500};
00099     
00100     uint8_t data[3] = {0};
00101     
00102     // write 0x34+(oss << 6) into reg 0xf4
00103     data[0] = 0xf4;
00104     data[1] = 0x34 + (oss << 6);
00105     writeRegs(data, 2);
00106     
00107     // wait
00108     wait_us(delay_ms[oss]);
00109     
00110     // read reg 0xf6(MSB), 0xf7(LSB), 0xf8(XLSB)
00111     readRegs(0xf6, data, 3);
00112     
00113     // UP = ((MSB << 16) + (LSB << 8) + XLSB) >> (8-oss)
00114     return ((data[0] << 16) | (data[1] << 8) | data[2]) >> (8-oss);
00115 }
00116 
00117 void BMP085::read(int32_t * temperature, int32_t * pressure)
00118 {
00119     int32_t ut, up;
00120     int32_t x1, x2, b5, b6, x3, b3, p;
00121     uint32_t b4, b7;
00122     
00123     ut = read_temp();
00124     up = read_pressure();
00125     
00126     x1 = ((int32_t)ut - ac6) * ac5 >> 15;
00127     x2 = ((int32_t) mc << 11) / (x1 + md);
00128     b5 = x1 + x2;
00129     *temperature = (b5 + 8) >> 4;
00130     
00131     b6 = b5 - 4000;
00132     x1 = (b2 * (b6 * b6 >> 12)) >> 11;
00133     x2 = ac2 * b6 >> 11;
00134     x3 = x1 + x2;
00135     b3 = (((int32_t) ac1 * 4 + x3) + 2)/4;
00136     x1 = ac3 * b6 >> 13;
00137     x2 = (b1 * (b6 * b6 >> 12)) >> 16;
00138     x3 = ((x1 + x2) + 2) >> 2;
00139     b4 = (ac4 * (unsigned int32_t) (x3 + 32768)) >> 15;
00140     b7 = ((unsigned int32_t) up - b3) * (50000 >> oss);
00141     p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
00142     x1 = (p >> 8) * (p >> 8);
00143     x1 = (x1 * 3038) >> 16;
00144     x2 = (-7357 * p) >> 16;
00145     *pressure = p + ((x1 + x2 + 3791) >> 4);
00146 }