This is a fork of MS5803-01 library by Raig Kaufer adapted for the MS5803-14BA.
Dependents: MS5803_demo ARNSRS_SERVOS_USB_TFT pdiot-MS5803-test
Revision 1:373f735e50e2, committed 2016-06-29
- Comitter:
- frada
- Date:
- Wed Jun 29 09:14:44 2016 +0000
- Parent:
- 0:a5f77652b3bb
- Commit message:
- Many improvements done; among all the most relevant is the use of second order temperature compensation for temperature and pressure readings (as specified in the MS5803-14BA datasheet from Measurement Specitalties).
Changed in this revision
MS5803_14BA.cpp | Show annotated file Show diff for this revision Revisions of this file |
MS5803_14BA.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r a5f77652b3bb -r 373f735e50e2 MS5803_14BA.cpp --- a/MS5803_14BA.cpp Fri Apr 24 18:56:03 2015 +0000 +++ b/MS5803_14BA.cpp Wed Jun 29 09:14:44 2016 +0000 @@ -29,86 +29,104 @@ #include <stdlib.h> #include "MS5803_14BA.h" -MS5803_14BA::MS5803_14BA(PinName sda, PinName scl, char MS5803_ADDR) : _i2c(sda, scl) { - device_address = MS5803_ADDR << 1; +MS5803_14BA::MS5803_14BA(PinName sda, PinName scl, uint8_t address) : _i2c(sda, scl) { + _address = address << 1; _d1_osr = D1_OSR_4096; _d2_osr = D2_OSR_4096; reset(); // reset the sensor readPROM(); // read the calibration values } -MS5803_14BA::MS5803_14BA(PinName sda, PinName scl, char MS5803_ADDR, char d1_osr, char d2_osr) : _i2c( sda, scl ) { - device_address = MS5803_ADDR << 1; - _d1_osr = D1_OSR_4096; - _d2_osr = D2_OSR_4096; +MS5803_14BA::MS5803_14BA(PinName sda, PinName scl, uint8_t address, uint8_t d1_osr, uint8_t d2_osr) : _i2c( sda, scl ) { + _address = address << 1; + _d1_osr = d1_osr; + _d2_osr = d2_osr; reset(); // reset the sensor - readPROM(); // read the calibration values and store them in array C[ ] + readPROM(); // read the calibration values and store them in array C } /* Send soft reset to the sensor */ void MS5803_14BA::reset(void) { MS5803_tx_data[0] = COMMAND_RESET; - _i2c.write(device_address, MS5803_tx_data, 1); + _i2c.write(_address, MS5803_tx_data, 1); wait_ms(20); } /* read the sensor calibration data from ROM */ void MS5803_14BA::readPROM(void) { + for (uint8_t i = 0; i < 8; i++) { MS5803_tx_data[0] = COMMAND_READ_PROM + (i << 1); - _i2c.write( device_address, MS5803_tx_data, 1); - _i2c.read( device_address, MS5803_rx_data, 2); + _i2c.write(_address, MS5803_tx_data, 1); + + _i2c.read(_address, MS5803_rx_data, 2); C[i] = (MS5803_rx_data[0] << 8) + MS5803_rx_data[1]; } } -/* Start the sensor pressure conversion */ -void MS5803_14BA::convertD1(void) { - MS5803_tx_data[0] = _d1_osr; - _i2c.write( device_address, MS5803_tx_data, 1); -} - -/* Start the sensor temperature conversion */ -void MS5803_14BA::convertD2(void) { - MS5803_tx_data[0] = _d2_osr; - _i2c.write(device_address, MS5803_tx_data, 1); -} - -/* Read the previous started conversion results */ -int32_t MS5803_14BA::readADC(void) { - wait_ms(150); - MS5803_tx_data[0] = COMMAND_READ_ADC; - _i2c.write(device_address, MS5803_tx_data, 1); - _i2c.read(device_address, MS5803_rx_data, 3); - return (MS5803_rx_data[0] << 16) + (MS5803_rx_data[1] << 8) + MS5803_rx_data[2]; -} - -/* return the results */ -float MS5803_14BA::getPressure(void) { - return P_MS5803; -} - -float MS5803_14BA::getTemperature (void) { - return T_MS5803; -} /* Sensor reading and calculation procedure */ void MS5803_14BA::convert(void) { int32_t dT, TEMP; int64_t OFF, SENS, P; - convertD1(); // start pressure convertion - D1 = readADC(); // read the pressure value - convertD2(); // start temperature convertion + MS5803_tx_data[0] = _d1_osr; + + _i2c.write(_address, MS5803_tx_data, 1); + wait_ms(10); + D1 = readADC(); // read the temperature value + + MS5803_tx_data[0] = _d2_osr; + _i2c.write(_address, MS5803_tx_data, 1); + wait_ms(10); D2 = readADC(); // read the temperature value - + /* calculation according MS5803-14BA data sheet */ - dT = D2 - (C[5]* 256); - TEMP = 2000 + (dT * C[6])/8388608; - T_MS5803 = (float) TEMP/100.0f; // result of temperature in deg C in this var + dT = D2 - (C[5]* 256); + TEMP = 2000 + (dT * C[6])/8388608; + + //Now we have our first order Temperature, let's calculate the second order. + int64_t T2, OFF2, SENS2; //working variables - OFF = (int64_t)65536*C[2] + ((int64_t)dT * (int64_t)C[4])/128; - SENS = (int64_t)32768*C[1] + ((int64_t)dT * (int64_t)C[3])/256; - P = (((int64_t)D1 * SENS)/2097152 - OFF)/32768; - P_MS5803 = (float) P/10.0f; // result of pressure in mBar in this var + if (TEMP < 2000) { + // If temp_calc is below 20.0C + T2 = 3 * (((int64_t)dT * dT) >> 33); + OFF2 = 3 * (TEMP - 2000)^2 / 2; + SENS2 = 5 * (TEMP - 2000)^2 / 8; + + if(TEMP < -1500) { + // If temp_calc is below -15.0C + OFF2 = OFF2 + 7 * (TEMP + 1500)^2; + SENS2 = SENS2 + 4 * (TEMP + 1500)^2; + } + } + else { + // If temp_calc is above 20.0C + T2 = 7 * ((uint64_t)dT * dT) >> 37; + OFF2 = (TEMP - 2000)^2 / 16; + SENS2 = 0; + } + + // Now bring it all together to apply offsets + OFF = ((int64_t)C[2] << 16) + (((C[4] * (int64_t)dT)) >> 7); + SENS = ((int64_t)C[1] << 15) + (((C[3] * (int64_t)dT)) >> 8); + + TEMP = TEMP - T2; + OFF = OFF - OFF2; + SENS = SENS - SENS2; + + temperature = (float) TEMP/100.0f; // result of temperature in degC in this var + + P = ((((int64_t)D1 * SENS) >> 21) - OFF) >> 15; + pressure = (float) P/10.0f; // result of pressure in mBar in this var } + +/* Read the previous started conversion results */ +int32_t MS5803_14BA::readADC(void) { + //wait_ms(150); + MS5803_tx_data[0] = COMMAND_READ_ADC; + _i2c.write(_address, MS5803_tx_data, 1); + _i2c.read(_address, MS5803_rx_data, 3); + + return (MS5803_rx_data[0] << 16) + (MS5803_rx_data[1] << 8) + MS5803_rx_data[2]; +}
diff -r a5f77652b3bb -r 373f735e50e2 MS5803_14BA.h --- a/MS5803_14BA.h Fri Apr 24 18:56:03 2015 +0000 +++ b/MS5803_14BA.h Wed Jun 29 09:14:44 2016 +0000 @@ -35,14 +35,14 @@ #define MS5803_TX_DEPTH 2 -#define MS5803_ADDRC_L 0x77 //0b1110111 CSB Pin is low -#define MS5803_ADDRC_H 0x76 //0b1110110 CSB Pin is high +#define MS5803_ADDRC_L (uint8_t) 0x77 //0b01110111 CSB Pin is low +#define MS5803_ADDRC_H (uint8_t) 0x76 //0b01110110 CSB Pin is high -#define MS5803_BASE_ADDR MS5803_ADDRC_L // choose your connection here +#define MS5803_BASE_ADDR MS5803_ADDRC_H // choose your connection here #define COMMAND_RESET 0x1E // Sensor Reset -#define D1_OSR_256 0x40 // Convert D1 OSR 256 +#define D1_OSR_256 0x40 // Convert D1 OSR 256 #define D1_OSR_512 0x42 // Convert D1 OSR 512 #define D1_OSR_1024 0x44 // Convert D1 OSR 1024 #define D1_OSR_2048 0x46 // Convert D1 OSR 2048 @@ -60,26 +60,23 @@ class MS5803_14BA { private: I2C _i2c; - char device_address, _d1_osr, _d2_osr; + uint8_t _address, _d1_osr, _d2_osr; uint32_t D1, D2; uint16_t C[8]; - float T_MS5803, P_MS5803; /* Data buffers */ char MS5803_rx_data[MS5803_RX_DEPTH]; char MS5803_tx_data[MS5803_TX_DEPTH]; public: - MS5803_14BA(PinName sda, PinName scl, char MS5803_ADDR); - MS5803_14BA(PinName sda, PinName scl, char MS5803_ADDR, char d1_osr, char d2_osr); + float temperature, pressure; + + MS5803_14BA(PinName sda, PinName scl, uint8_t MS5803_ADDR); + MS5803_14BA(PinName sda, PinName scl, uint8_t MS5803_ADDR, uint8_t d1_osr, uint8_t d2_osr); void reset(void); void readPROM(void); - void convertD1(void); - void convertD2(void); - int32_t readADC(void); - float getPressure(void); - float getTemperature(void); void convert(void); + int32_t readADC(); }; #endif