Library for the barometric pressure sensor BMP183

Dependents:   BMP183Test

BMP183.cpp

Committer:
Cirrus01
Date:
2016-06-21
Revision:
0:3750c8d10767

File content as of revision 0:3750c8d10767:


#include "BMP183.h"

BMP183::BMP183(PinName MOSI, PinName MISO, PinName SCLK, PinName CS): spi(MOSI, MISO, SCLK), cs(CS) {
    ChipDeselect();
    spi.format(8, 3);
    spi.frequency(5e6);
}

uint8_t BMP183::getID(void)
{
    char response[1];
    readRegister(BMP183_REGISTER_CHIPID, response, 1);
    return response[0];
}

void BMP183::getCalibrationData(void)
{
    char buffer[22];                                  // 8-Bit pieces of axis data
    readRegister(BMP183_REGISTER_CAL_AC1, buffer, 22);         // read all calibration registers in one time 22 Byte = 176 Bit
    
    AC1 = (short) (buffer[0] << 8 | buffer[1]);       // join 8-Bit pieces to 16-bit short integers
    AC2 = (short) (buffer[2] << 8 | buffer[3]);
    AC3 = (short) (buffer[4] << 8 | buffer[5]);
    AC4 = (unsigned short) (buffer[6] << 8 | buffer[7]);      // unsigned !!
    AC5 = (unsigned short) (buffer[8] << 8 | buffer[9]);
    AC6 = (unsigned short) (buffer[10] << 8 | buffer[11]);
    B1 = (short) (buffer[12] << 8 | buffer[13]);
    B2 = (short) (buffer[14] << 8 | buffer[15]);
    MB = (short) (buffer[16] << 8 | buffer[17]);
    MC = (short) (buffer[18] << 8 | buffer[19]);
    MD = (short) (buffer[20] << 8 | buffer[21]);
    
    
    oss = 0; // set Oversampling of Sensor
}

void BMP183::read(void)
{
    unsigned short Uncompensated_Temperature;
    long P, Uncompensated_Pressure, X1, X2, X3, B3, B5, B6;
    unsigned long B4, B7;
    
    // read uncompensated Temperature
    writeRegister(BMP183_REGISTER_CONTROL, BMP183_REGISTER_READTEMPCMD);// say the sensor we want to read the temperature
    wait(0.005); // Wait at least 4.5ms (written in data sheet)
    char buffer[3];  // TODO: nur 2 wenn unten nicht gebraucht                                           // read 16-Bit Temperature (2 registers)
    readRegister(BMP183_REGISTER_TEMPDATA, buffer, 2);        
    Uncompensated_Temperature =  buffer[0] << 8 | buffer[1];               // join 8-Bit pieces to 16-bit short integer
    
    // calculate real Temperature
    X1 = ((Uncompensated_Temperature - AC6) * AC5) >> 15;
    X2 = (MC << 11) / (X1 + MD);
    B5 = X1 + X2;                               // - ((33 << 4) - 8); 
    Temperature = (float)((B5 + 8) >> 4)/10.0;  // we want temperature in degree with digit after comma
    
    // read uncompensated Pressure
    writeRegister(BMP183_REGISTER_CONTROL, BMP183_REGISTER_READPRESSURECMD + (oss << 6));// say the sensor we want to read the pressure
    wait(0.005); // Wait at least 4.5ms (written in data sheet) TODO: oss fest, times vary and calculation of B3                         
    readRegister(BMP183_REGISTER_PRESSUREDATA, buffer, 3);                                                    // read 24-Bit Pressure (3 registers)
    Uncompensated_Pressure = (unsigned int) (buffer[0] << 16 | buffer[1] << 8 | buffer[0]) >> (8 - oss);    // join 8-Bit pieces to 24-bit integer
    
    // calculate real Pressure
    B6 = B5 - 4000;     // B5 is updated by real temperature above
    X1 = (B2 * ( (B6 * B6) >> 12 )) >> 11;
    X2 = (AC2 * B6) >> 11;
    X3 = X1 + X2;
    B3 = (((AC1 * 4 + X3) << oss) + 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)Uncompensated_Pressure - B3) * (50000 >> oss);
    
    if (B7 < 0x80000000)
        P = (B7 * 2) / B4;
    else 
        P = (B7 / B4) * 2;
    
    X1 = (P >> 8) * (P >> 8);
    X1 = (X1 * 3038) >> 16;
    X2 = (-7357 * P) >> 16;    
    P = P + ((X1 + X2 + 3791) >> 4);
    Pressure = (float)P / 100.0;
    
    // calculate height out of the pressure
    Altitude = 44330 * (1.0 - pow((Pressure / 1013.25), 1/5.25588));
}

//////////////////////////////////////////////////////////////////////////
/// SPI Functions
//////////////////////////////////////////////////////////////////////////

void BMP183::readRegister(uint8_t reg, char *buffer, int length) {
    ChipSelect();
    spi.write(reg | 0x80);                                  // send the register address we want to read and the read flag
    for(int i=0; i<length; i++)                             // get data
        buffer[i] = spi.write(0x00);
    ChipDeselect();
}
 
void BMP183::writeRegister(uint8_t reg, char *buffer, int length) {
    ChipSelect();
    spi.write(reg & ~0x80);                                 // send the register address we want to write and the write flag
    for(int i=0; i<length; i++)                             // put data
        spi.write(buffer[i]);
    ChipDeselect();
}

void BMP183::writeRegister(uint8_t reg, int data) {
    ChipSelect();
    spi.write(reg & ~0x80);                                 // send the register address we want to write and the write flag
    spi.write(data);                                        // put data
    ChipDeselect();
} 
void BMP183::ChipSelect() { cs = 0; }                          // set Cable Select pin low to start SPI transaction
void BMP183::ChipDeselect() { cs = 1; }                        // set Cable Select pin high to stop SPI transaction