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

bmp085.cpp

Committer:
Quincy31
Date:
2015-03-11
Revision:
0:904377b11e64

File content as of revision 0:904377b11e64:

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

#define BMP085_ADDR 0xee

const float BMP085::p0 = 1013.25;
float BMP085::altitude(float p)
{
    return (float)(44330.0 * (1.0 - pow((double)p/p0, 1/5.255)));
}
    
BMP085::BMP085(PinName sda, PinName scl): m_i2c(sda, scl), 
    m_addr(BMP085_ADDR), oss(0)
{
    // calibration
    uint8_t bmp085_cali_regs[] = {0xAA,0xAC,0xAE,0xB0,0xB2,0xB4,0xB6,0xB8,0xBA,0xBC,0xBE,0};
    uint8_t *ptr = bmp085_cali_regs;
    int16_t bmp085_value[11]={0};
    int i = 0;
    uint8_t data[2];
    
    while(*ptr)
    {
        readRegs(*ptr, data, 2);
    
        bmp085_value[i++] = (data[0] << 8) | data[1];
        
        ptr++;
    }
    
    ac1 = bmp085_value[0];
    ac2 = bmp085_value[1];
    ac3 = bmp085_value[2];
    ac4 = (uint16_t)bmp085_value[3];
    ac5 = (uint16_t)bmp085_value[4];
    ac6 = (uint16_t)bmp085_value[5];
    b1 = bmp085_value[6];
    b2 = bmp085_value[7];
    mb = bmp085_value[8];
    mc = bmp085_value[9];
    md = bmp085_value[10];
    
    /*printf("\tAC1 = %d\r\n", ac1);
    printf("\tAC2 = %d\r\n", ac2);
    printf("\tAC3 = %d\r\n", ac3);
    printf("\tAC4 = %d\r\n", ac4);
    printf("\tAC5 = %d\r\n", ac5);
    printf("\tAC6 = %d\r\n", ac6);
    printf("\tB1 = %d\r\n", b1);
    printf("\tB2 = %d\r\n", b2);
    printf("\tMB = %d\r\n", mb);
    printf("\tMC = %d\r\n", mc);
    printf("\tMD = %d\r\n", md);
    printf("------------------------\r\n");*/
}

void BMP085::set_oversampling(int osrs)
{
    if(osrs > 0 && osrs < 4)
    {
        oss = osrs;
    }
}
    
void BMP085::readRegs(int addr, uint8_t * data, int len)
{
    char t[1] = {addr};
    
    m_i2c.write(m_addr, t, 1, true);
    m_i2c.read(m_addr, (char *)data, len);
}

void BMP085::writeRegs(uint8_t * data, int len)
{
    m_i2c.write(m_addr, (char *)data, len);
}

int32_t BMP085::read_temp(void)
{
    uint8_t data[2] = {0xf4, 0x2e};
    
    // write 0x2e into reg 0xf4
    writeRegs(data, 2);
    
    // wait 4.5ms
    wait_us(4500);
    
    // read reg 0xf6(MSB), 0xf7(LSB)
    readRegs(0xf6, data, 2);
    
    // UT = (MSB << 8) + LSB
    return (data[0] << 8) | data[1];
}

int32_t BMP085::read_pressure(void)
{
    static int delay_ms[] = {4500, 7500, 13500, 25500};
    
    uint8_t data[3] = {0};
    
    // write 0x34+(oss << 6) into reg 0xf4
    data[0] = 0xf4;
    data[1] = 0x34 + (oss << 6);
    writeRegs(data, 2);
    
    // wait
    wait_us(delay_ms[oss]);
    
    // read reg 0xf6(MSB), 0xf7(LSB), 0xf8(XLSB)
    readRegs(0xf6, data, 3);
    
    // UP = ((MSB << 16) + (LSB << 8) + XLSB) >> (8-oss)
    return ((data[0] << 16) | (data[1] << 8) | data[2]) >> (8-oss);
}

void BMP085::read(int32_t * temperature, int32_t * pressure)
{
    int32_t ut, up;
    int32_t x1, x2, b5, b6, x3, b3, p;
    uint32_t b4, b7;
    
    ut = read_temp();
    up = read_pressure();
    
    x1 = ((int32_t)ut - ac6) * ac5 >> 15;
    x2 = ((int32_t) mc << 11) / (x1 + md);
    b5 = x1 + x2;
    *temperature = (b5 + 8) >> 4;
    
    b6 = b5 - 4000;
    x1 = (b2 * (b6 * b6 >> 12)) >> 11;
    x2 = ac2 * b6 >> 11;
    x3 = x1 + x2;
    b3 = (((int32_t) ac1 * 4 + x3) + 2)/4;
    x1 = ac3 * b6 >> 13;
    x2 = (b1 * (b6 * b6 >> 12)) >> 16;
    x3 = ((x1 + x2) + 2) >> 2;
    b4 = (ac4 * (unsigned int32_t) (x3 + 32768)) >> 15;
    b7 = ((unsigned int32_t) up - b3) * (50000 >> oss);
    p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
    x1 = (p >> 8) * (p >> 8);
    x1 = (x1 * 3038) >> 16;
    x2 = (-7357 * p) >> 16;
    *pressure = p + ((x1 + x2 + 3791) >> 4);
}