Library for the barometric pressure sensor BMP183

Dependents:   BMP183Test

Committer:
Cirrus01
Date:
Tue Jun 21 10:02:13 2016 +0000
Revision:
0:3750c8d10767
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Cirrus01 0:3750c8d10767 1
Cirrus01 0:3750c8d10767 2 #include "BMP183.h"
Cirrus01 0:3750c8d10767 3
Cirrus01 0:3750c8d10767 4 BMP183::BMP183(PinName MOSI, PinName MISO, PinName SCLK, PinName CS): spi(MOSI, MISO, SCLK), cs(CS) {
Cirrus01 0:3750c8d10767 5 ChipDeselect();
Cirrus01 0:3750c8d10767 6 spi.format(8, 3);
Cirrus01 0:3750c8d10767 7 spi.frequency(5e6);
Cirrus01 0:3750c8d10767 8 }
Cirrus01 0:3750c8d10767 9
Cirrus01 0:3750c8d10767 10 uint8_t BMP183::getID(void)
Cirrus01 0:3750c8d10767 11 {
Cirrus01 0:3750c8d10767 12 char response[1];
Cirrus01 0:3750c8d10767 13 readRegister(BMP183_REGISTER_CHIPID, response, 1);
Cirrus01 0:3750c8d10767 14 return response[0];
Cirrus01 0:3750c8d10767 15 }
Cirrus01 0:3750c8d10767 16
Cirrus01 0:3750c8d10767 17 void BMP183::getCalibrationData(void)
Cirrus01 0:3750c8d10767 18 {
Cirrus01 0:3750c8d10767 19 char buffer[22]; // 8-Bit pieces of axis data
Cirrus01 0:3750c8d10767 20 readRegister(BMP183_REGISTER_CAL_AC1, buffer, 22); // read all calibration registers in one time 22 Byte = 176 Bit
Cirrus01 0:3750c8d10767 21
Cirrus01 0:3750c8d10767 22 AC1 = (short) (buffer[0] << 8 | buffer[1]); // join 8-Bit pieces to 16-bit short integers
Cirrus01 0:3750c8d10767 23 AC2 = (short) (buffer[2] << 8 | buffer[3]);
Cirrus01 0:3750c8d10767 24 AC3 = (short) (buffer[4] << 8 | buffer[5]);
Cirrus01 0:3750c8d10767 25 AC4 = (unsigned short) (buffer[6] << 8 | buffer[7]); // unsigned !!
Cirrus01 0:3750c8d10767 26 AC5 = (unsigned short) (buffer[8] << 8 | buffer[9]);
Cirrus01 0:3750c8d10767 27 AC6 = (unsigned short) (buffer[10] << 8 | buffer[11]);
Cirrus01 0:3750c8d10767 28 B1 = (short) (buffer[12] << 8 | buffer[13]);
Cirrus01 0:3750c8d10767 29 B2 = (short) (buffer[14] << 8 | buffer[15]);
Cirrus01 0:3750c8d10767 30 MB = (short) (buffer[16] << 8 | buffer[17]);
Cirrus01 0:3750c8d10767 31 MC = (short) (buffer[18] << 8 | buffer[19]);
Cirrus01 0:3750c8d10767 32 MD = (short) (buffer[20] << 8 | buffer[21]);
Cirrus01 0:3750c8d10767 33
Cirrus01 0:3750c8d10767 34
Cirrus01 0:3750c8d10767 35 oss = 0; // set Oversampling of Sensor
Cirrus01 0:3750c8d10767 36 }
Cirrus01 0:3750c8d10767 37
Cirrus01 0:3750c8d10767 38 void BMP183::read(void)
Cirrus01 0:3750c8d10767 39 {
Cirrus01 0:3750c8d10767 40 unsigned short Uncompensated_Temperature;
Cirrus01 0:3750c8d10767 41 long P, Uncompensated_Pressure, X1, X2, X3, B3, B5, B6;
Cirrus01 0:3750c8d10767 42 unsigned long B4, B7;
Cirrus01 0:3750c8d10767 43
Cirrus01 0:3750c8d10767 44 // read uncompensated Temperature
Cirrus01 0:3750c8d10767 45 writeRegister(BMP183_REGISTER_CONTROL, BMP183_REGISTER_READTEMPCMD);// say the sensor we want to read the temperature
Cirrus01 0:3750c8d10767 46 wait(0.005); // Wait at least 4.5ms (written in data sheet)
Cirrus01 0:3750c8d10767 47 char buffer[3]; // TODO: nur 2 wenn unten nicht gebraucht // read 16-Bit Temperature (2 registers)
Cirrus01 0:3750c8d10767 48 readRegister(BMP183_REGISTER_TEMPDATA, buffer, 2);
Cirrus01 0:3750c8d10767 49 Uncompensated_Temperature = buffer[0] << 8 | buffer[1]; // join 8-Bit pieces to 16-bit short integer
Cirrus01 0:3750c8d10767 50
Cirrus01 0:3750c8d10767 51 // calculate real Temperature
Cirrus01 0:3750c8d10767 52 X1 = ((Uncompensated_Temperature - AC6) * AC5) >> 15;
Cirrus01 0:3750c8d10767 53 X2 = (MC << 11) / (X1 + MD);
Cirrus01 0:3750c8d10767 54 B5 = X1 + X2; // - ((33 << 4) - 8);
Cirrus01 0:3750c8d10767 55 Temperature = (float)((B5 + 8) >> 4)/10.0; // we want temperature in degree with digit after comma
Cirrus01 0:3750c8d10767 56
Cirrus01 0:3750c8d10767 57 // read uncompensated Pressure
Cirrus01 0:3750c8d10767 58 writeRegister(BMP183_REGISTER_CONTROL, BMP183_REGISTER_READPRESSURECMD + (oss << 6));// say the sensor we want to read the pressure
Cirrus01 0:3750c8d10767 59 wait(0.005); // Wait at least 4.5ms (written in data sheet) TODO: oss fest, times vary and calculation of B3
Cirrus01 0:3750c8d10767 60 readRegister(BMP183_REGISTER_PRESSUREDATA, buffer, 3); // read 24-Bit Pressure (3 registers)
Cirrus01 0:3750c8d10767 61 Uncompensated_Pressure = (unsigned int) (buffer[0] << 16 | buffer[1] << 8 | buffer[0]) >> (8 - oss); // join 8-Bit pieces to 24-bit integer
Cirrus01 0:3750c8d10767 62
Cirrus01 0:3750c8d10767 63 // calculate real Pressure
Cirrus01 0:3750c8d10767 64 B6 = B5 - 4000; // B5 is updated by real temperature above
Cirrus01 0:3750c8d10767 65 X1 = (B2 * ( (B6 * B6) >> 12 )) >> 11;
Cirrus01 0:3750c8d10767 66 X2 = (AC2 * B6) >> 11;
Cirrus01 0:3750c8d10767 67 X3 = X1 + X2;
Cirrus01 0:3750c8d10767 68 B3 = (((AC1 * 4 + X3) << oss) + 2) >> 2;
Cirrus01 0:3750c8d10767 69
Cirrus01 0:3750c8d10767 70 X1 = (AC3 * B6) >> 13;
Cirrus01 0:3750c8d10767 71 X2 = (B1 * ( (B6 * B6) >> 12) ) >> 16;
Cirrus01 0:3750c8d10767 72 X3 = ((X1 + X2) + 2) >> 2;
Cirrus01 0:3750c8d10767 73 B4 = AC4 * ((unsigned long)X3 + 32768) >> 15;
Cirrus01 0:3750c8d10767 74
Cirrus01 0:3750c8d10767 75 B7 = ((unsigned long)Uncompensated_Pressure - B3) * (50000 >> oss);
Cirrus01 0:3750c8d10767 76
Cirrus01 0:3750c8d10767 77 if (B7 < 0x80000000)
Cirrus01 0:3750c8d10767 78 P = (B7 * 2) / B4;
Cirrus01 0:3750c8d10767 79 else
Cirrus01 0:3750c8d10767 80 P = (B7 / B4) * 2;
Cirrus01 0:3750c8d10767 81
Cirrus01 0:3750c8d10767 82 X1 = (P >> 8) * (P >> 8);
Cirrus01 0:3750c8d10767 83 X1 = (X1 * 3038) >> 16;
Cirrus01 0:3750c8d10767 84 X2 = (-7357 * P) >> 16;
Cirrus01 0:3750c8d10767 85 P = P + ((X1 + X2 + 3791) >> 4);
Cirrus01 0:3750c8d10767 86 Pressure = (float)P / 100.0;
Cirrus01 0:3750c8d10767 87
Cirrus01 0:3750c8d10767 88 // calculate height out of the pressure
Cirrus01 0:3750c8d10767 89 Altitude = 44330 * (1.0 - pow((Pressure / 1013.25), 1/5.25588));
Cirrus01 0:3750c8d10767 90 }
Cirrus01 0:3750c8d10767 91
Cirrus01 0:3750c8d10767 92 //////////////////////////////////////////////////////////////////////////
Cirrus01 0:3750c8d10767 93 /// SPI Functions
Cirrus01 0:3750c8d10767 94 //////////////////////////////////////////////////////////////////////////
Cirrus01 0:3750c8d10767 95
Cirrus01 0:3750c8d10767 96 void BMP183::readRegister(uint8_t reg, char *buffer, int length) {
Cirrus01 0:3750c8d10767 97 ChipSelect();
Cirrus01 0:3750c8d10767 98 spi.write(reg | 0x80); // send the register address we want to read and the read flag
Cirrus01 0:3750c8d10767 99 for(int i=0; i<length; i++) // get data
Cirrus01 0:3750c8d10767 100 buffer[i] = spi.write(0x00);
Cirrus01 0:3750c8d10767 101 ChipDeselect();
Cirrus01 0:3750c8d10767 102 }
Cirrus01 0:3750c8d10767 103
Cirrus01 0:3750c8d10767 104 void BMP183::writeRegister(uint8_t reg, char *buffer, int length) {
Cirrus01 0:3750c8d10767 105 ChipSelect();
Cirrus01 0:3750c8d10767 106 spi.write(reg & ~0x80); // send the register address we want to write and the write flag
Cirrus01 0:3750c8d10767 107 for(int i=0; i<length; i++) // put data
Cirrus01 0:3750c8d10767 108 spi.write(buffer[i]);
Cirrus01 0:3750c8d10767 109 ChipDeselect();
Cirrus01 0:3750c8d10767 110 }
Cirrus01 0:3750c8d10767 111
Cirrus01 0:3750c8d10767 112 void BMP183::writeRegister(uint8_t reg, int data) {
Cirrus01 0:3750c8d10767 113 ChipSelect();
Cirrus01 0:3750c8d10767 114 spi.write(reg & ~0x80); // send the register address we want to write and the write flag
Cirrus01 0:3750c8d10767 115 spi.write(data); // put data
Cirrus01 0:3750c8d10767 116 ChipDeselect();
Cirrus01 0:3750c8d10767 117 }
Cirrus01 0:3750c8d10767 118 void BMP183::ChipSelect() { cs = 0; } // set Cable Select pin low to start SPI transaction
Cirrus01 0:3750c8d10767 119 void BMP183::ChipDeselect() { cs = 1; } // set Cable Select pin high to stop SPI transaction