Library for the barometric pressure sensor BMP183
Diff: BMP183.cpp
- Revision:
- 0:3750c8d10767
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BMP183.cpp Tue Jun 21 10:02:13 2016 +0000 @@ -0,0 +1,119 @@ + +#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