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

Files at this revision

API Documentation at this revision

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
--- 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];
+}
--- 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