Bosch BMP085 Barometric Pressure Sensor

bmp085.cpp

Committer:
timm
Date:
2015-03-19
Revision:
0:e8f53e502a4c

File content as of revision 0:e8f53e502a4c:

#include "mbed.h"
#include "bmp085.h"

BMP085::BMP085(PinName sclPin, PinName sdaPin)
{
    i2c = new I2C(sdaPin, sclPin);
    i2c->frequency(1000); // run at 1KHz
}

long BMP085::getUT() { return UT; }
long BMP085::getUP() { return UP; }
void BMP085::init() { readCalData(); }

void BMP085::readCalData()
{
    char dataWrite[2];
    char dataRead[2];

    dataWrite[0] = CAL_DATA_AC1;   
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    AC1 = ((dataRead[0] << 8) | (dataRead[1]));

    dataWrite[0] = CAL_DATA_AC2;
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    AC2 = ((dataRead[0] << 8) | (dataRead[1]));

    dataWrite[0] = CAL_DATA_AC3;
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    AC3 = ((dataRead[0] << 8) | (dataRead[1]));

    dataWrite[0] = CAL_DATA_AC4;   
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    AC4 = ((dataRead[0] << 8) | (dataRead[1]));

    dataWrite[0] = CAL_DATA_AC5;
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    AC5 = ((dataRead[0] << 8) | (dataRead[1]));

    dataWrite[0] = CAL_DATA_AC6;
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    AC6 = ((dataRead[0] << 8) | (dataRead[1]));

    dataWrite[0] = CAL_DATA_B1;   
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    B1 = ((dataRead[0] << 8) | (dataRead[1]));

    dataWrite[0] = CAL_DATA_B2;
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    B2 = ((dataRead[0] << 8) | (dataRead[1]));

    dataWrite[0] = CAL_DATA_MB;   
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    MB = ((dataRead[0] << 8) | (dataRead[1]));

    dataWrite[0] = CAL_DATA_MC;
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    MC = ((dataRead[0] << 8) | (dataRead[1]));

    dataWrite[0] = CAL_DATA_MD;
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    MD = ((dataRead[0] << 8) | (dataRead[1]));
}

void BMP085::readUncompTemp()
{
    char dataWrite[2];
    char dataRead[2];

    dataWrite[0] = CTRL_REG_ADDR;
    dataWrite[1] = MEASURE_TEMP_CMD;
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 2, 0); // stop
    wait_ms(5);
    dataWrite[0] = DATA_REG_ADDR;
    dataWrite[1] = 0;
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 2, 0);
    UT = (long)((dataRead[0] << 8) | (dataRead[1]));
}

void BMP085::readUncompPressure(int mode)
{
    char dataWrite[2];
    char dataRead[4];

    dataWrite[0] = CTRL_REG_ADDR;
    dataWrite[1] = (MEASURE_PRES_CMD | ((((char)mode) & 0x3) << 6));
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 2, 0); // stop
    wait_ms(10 * (mode + 1)); // TODO: ensure this is accurate, based on oss
    dataWrite[0] = DATA_REG_ADDR;
    dataWrite[1] = 0;
    i2c->write(BMP085_I2C_ADDR_WRITE, dataWrite, 1, 1); // no stop
    i2c->read(BMP085_I2C_ADDR_READ, dataRead, 3, 0);
    UP = (long)( ((dataRead[0] << 16) | (dataRead[1] << 8) | dataRead[0]) >> ( 8 - mode));
    //UP = (long)((dataRead[0] << 8) | (dataRead[1]));
}
  
float BMP085::getTemperature()
{
    readUncompTemp();

    X1 = (((long)UT - (long)AC6)*(long)AC5) >> 15;
    X2= ((long)MC << 11)/(X1+ MD);
    B5 = X1 + X2;
    T = ((B5 + 8) >> 4);
    
    return (float)(T / 10.0);
}

float BMP085::getPressure(int oss)
{
    readUncompPressure(oss);
  
    // Calculate B3
    B6 = B5 - 4000;
    X1 = (B2 * ((B6 * B6)>>12)) >>11;
    X2 = (AC2 * B6)>>11;
    X3 = X1 + X2;
    B3 = (((((long)AC1) * 4 + X3) << oss) + 2) >> 2;

    // Calculate B4, B7, p
    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));
    if (B7 < 0x80000000) { p = (B7 << 1) / B4; }
    else { p = (B7/B4) << 1; }
    
    X1 = (p >> 8) * (p >> 8);
    X1 = (X1 * 3038) >> 16;
    X2 = (-7357 * p) >> 16;
    p += ((X1 + X2 + 3791) >> 4);
    
    return (float)p;
}