Library for the barometric pressure sensor BMP183
BMP183.cpp@0:3750c8d10767, 2016-06-21 (annotated)
- Committer:
- Cirrus01
- Date:
- Tue Jun 21 10:02:13 2016 +0000
- Revision:
- 0:3750c8d10767
Initial commit
Who changed what in which revision?
User | Revision | Line number | New 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 |