High resolution barometer and altimeter using i2c mode

Dependents:   Q2_Stabi

Fork of ms5611 by Kevin Braun

Files at this revision

API Documentation at this revision

Comitter:
Decimus
Date:
Mon May 30 08:10:56 2016 +0000
Parent:
11:e0417b67a4b5
Commit message:
[+] Some renaming ang adding getGyro

Changed in this revision

ms5611.cpp Show annotated file Show diff for this revision Revisions of this file
ms5611.h Show annotated file Show diff for this revision Revisions of this file
diff -r e0417b67a4b5 -r af100556f99e ms5611.cpp
--- a/ms5611.cpp	Thu Dec 03 19:47:10 2015 +0000
+++ b/ms5611.cpp	Mon May 30 08:10:56 2016 +0000
@@ -30,6 +30,7 @@
         _i2c.frequency(400000);
         _i2cWAddr = MS5611_ADDR_W;
         _i2cRAddr = MS5611_ADDR_R;
+        step = 1;
 }
 
 //--------------------------------------------------------------------------------------------------------------------------------------//
@@ -44,6 +45,7 @@
             _i2cRAddr -= 2;
         
         }
+        step = 1;
 }
 
 //********************************************************
@@ -148,37 +150,47 @@
 
 uint64_t ms5611::cmd_adc(uint8_t cmd) {
     uint64_t temp = 0;
+    if( step & 0b101 ){ // or 0b1 either 0b100
 #if defined  MS5611i2cLOWLEVEL
-    m_i2c_send(MS5611_CMD_ADC_CONV + cmd);
+        m_i2c_send(MS5611_CMD_ADC_CONV + cmd);
 #else
-    cobuf[0] = 0;
-    cobuf[1] = 0;
-    cobuf[2] = 0;
-    cobuf[0] = MS5611_CMD_ADC_CONV + cmd;
-    _i2c.write(_i2cWAddr, cobuf, 1, false);
+        cobuf[0] = 0;
+        cobuf[1] = 0;
+        cobuf[2] = 0;
+        cobuf[0] = MS5611_CMD_ADC_CONV + cmd;
+        _i2c.write(_i2cWAddr, cobuf, 1, false);
 #endif
-    switch (cmd & 0x0f) {
-        case MS5611_CMD_ADC_256 : wait_us(900); break;
-        case MS5611_CMD_ADC_512 : wait_ms(3); break;
-        case MS5611_CMD_ADC_1024: wait_ms(4); break;
-        case MS5611_CMD_ADC_2048: wait_ms(6); break;
-        case MS5611_CMD_ADC_4096: wait_ms(10); break;
+        /*
+        switch (cmd & 0x0f) {
+            case MS5611_CMD_ADC_256 : wait_us(900); break;
+            case MS5611_CMD_ADC_512 : wait_ms(3); break;
+            case MS5611_CMD_ADC_1024: wait_ms(4); break;
+            case MS5611_CMD_ADC_2048: wait_ms(6); break;
+            case MS5611_CMD_ADC_4096: wait_ms(10); break;
+        }
+        */
+        step = step<<1; // will be 0b10 or 0b1000    
+        return 0;
     }
+    else if( step & 0b1010 ){ // or 0b10 either 0b1000
 #if defined  MS5611i2cLOWLEVEL
-    m_i2c_send(MS5611_CMD_ADC_READ);
-    m_i2c_start(true);
-    temp = m_i2c_readAck();
-    temp = (temp << 8) | m_i2c_readAck();
-    temp = (temp << 8) | m_i2c_readNak();
-    m_i2c_stop();
+        m_i2c_send(MS5611_CMD_ADC_READ);
+        m_i2c_start(true);
+        temp = m_i2c_readAck();
+        temp = (temp << 8) | m_i2c_readAck();
+        temp = (temp << 8) | m_i2c_readNak();
+        m_i2c_stop();
 #else
-    cobuf[0] = MS5611_CMD_ADC_READ;
-    _i2c.write(_i2cWAddr, cobuf, 1, true);
-    cobuf[0] = 0;
-    _i2c.read(_i2cRAddr, cobuf, 3, false);
-    temp = (cobuf[0] << 16) | (cobuf[1] << 8) | cobuf[2];
-#endif    
-    return temp;
+        cobuf[0] = MS5611_CMD_ADC_READ;
+        _i2c.write(_i2cWAddr, cobuf, 1, true);
+        cobuf[0] = 0;
+        _i2c.read(_i2cRAddr, cobuf, 3, false);
+        temp = (cobuf[0] << 16) | (cobuf[1] << 8) | cobuf[2];
+#endif
+        step = step<<1; // will be 0b100 or 0b10000    
+        return temp;
+    }
+    return 0;
 }
 
 //********************************************************
@@ -293,29 +305,38 @@
 //! @return none
 //********************************************************   
      
-void ms5611::calcPT() {
-    int32_t D2 = cmd_adc(MS5611_CMD_ADC_D2 + MS5611_CMD_ADC_4096); // read D2
-    int32_t D1 = cmd_adc(MS5611_CMD_ADC_D1 + MS5611_CMD_ADC_4096); // read D1
-    int64_t dT = D2 - ((uint64_t)C[5] << 8);
-    int64_t OFF  = ((uint32_t)C[2] << 16) + ((dT * (C[4]) >> 7));     //was  OFF  = (C[2] << 17) + dT * C[4] / (1 << 6);
-    int64_t SENS = ((uint32_t)C[1] << 15) + ((dT * (C[3]) >> 8));     //was  SENS = (C[1] << 16) + dT * C[3] / (1 << 7);
-    int32_t TEMP = 2000 + (int64_t)dT * (int64_t)C[6] / (int64_t)(1 << 23);
-    T = (double) TEMP / 100.0;
+uint8_t ms5611::calcPT() {
+    if( step & 0b11 ){ // or 0b1 either 0b10
+        D2 = cmd_adc(MS5611_CMD_ADC_D2 + MS5611_CMD_ADC_2048); // read D2
+    }
+    if( step & 0b1100 ){ // or 0b10 either 0b100 
+        D1 = cmd_adc(MS5611_CMD_ADC_D1 + MS5611_CMD_ADC_2048); // read D1
+    }
+    if( step & 0b10000 ){
+        int64_t dT = D2 - ((uint64_t)C[5] << 8);
+        int64_t OFF  = ((uint32_t)C[2] << 16) + ((dT * (C[4]) >> 7));     //was  OFF  = (C[2] << 17) + dT * C[4] / (1 << 6);
+        int64_t SENS = ((uint32_t)C[1] << 15) + ((dT * (C[3]) >> 8));     //was  SENS = (C[1] << 16) + dT * C[3] / (1 << 7);
+        int32_t TEMP = 2000 + (int64_t)dT * (int64_t)C[6] / (int64_t)(1 << 23);
+        T = (double) TEMP / 100.0;
 
-    if(TEMP < 2000) { // if temperature lower than +20 Celsius
-        int64_t T1 = ((int64_t)TEMP - 2000) * ((int64_t)TEMP - 2000);
-        int64_t OFF1  = (5 * T1) >> 1;
-        int64_t SENS1 = (5 * T1) >> 2;
+        if(TEMP < 2000) { // if temperature lower than +20 Celsius
+            int64_t T1 = ((int64_t)TEMP - 2000) * ((int64_t)TEMP - 2000);
+            int64_t OFF1  = (5 * T1) >> 1;
+            int64_t SENS1 = (5 * T1) >> 2;
 
-        if(TEMP < -1500) { // if temperature lower than -15 Celsius
-            T1 = ((int64_t)TEMP + 1500) * ((int64_t)TEMP + 1500);
-            OFF1  +=  7 * T1;
-            SENS1 += 11 * T1 >> 1;
-        } 
-        OFF -= OFF1;
-        SENS -= SENS1;
+            if(TEMP < -1500) { // if temperature lower than -15 Celsius
+                T1 = ((int64_t)TEMP + 1500) * ((int64_t)TEMP + 1500);
+                OFF1  +=  7 * T1;
+                SENS1 += 11 * T1 >> 1;
+            } 
+            OFF -= OFF1;
+            SENS -= SENS1;
+        }
+        P = (double)(((((int64_t)D1 * SENS ) >> 21) - OFF) / (double) (1 << 15)) / 100.0;
+        step = 1;
+        return 1;
     }
-    P = (double)(((((int64_t)D1 * SENS ) >> 21) - OFF) / (double) (1 << 15)) / 100.0;
+    return 0;
 }
 
 //********************************************************
@@ -347,10 +368,16 @@
 //********************************************************  
 
 double ms5611::getPressure() {
-    calcPT();
+    //calcPT();
     return(P);
 } 
 
+float ms5611::getAltitude() {
+    A = (1 - pow(P/(double)1013.250, 0.190295)) * 44330.0;
+    //A = (1 - (pow((P / (double)sea_pressure), 0.190284))) * 145366.45;
+    return((float)A);
+} 
+
 //********************************************************
 //! @brief get altitude from known sea level barometer, 
 //! @      no pre-pressure calculation
diff -r e0417b67a4b5 -r af100556f99e ms5611.h
--- a/ms5611.h	Thu Dec 03 19:47:10 2015 +0000
+++ b/ms5611.h	Mon May 30 08:10:56 2016 +0000
@@ -156,6 +156,7 @@
      *
      * @param float known pressure (mB) at sea level
      */
+    float getAltitude();
     float getAltitudeFT(float sea_pressure);
     /** Calculate and returns sea level baro
      *    Returns float seal level barometer in feet
@@ -169,6 +170,9 @@
      * @param float known altitude in meters
      */
     float getSeaLevelBaroM(float known_alt);
+
+    uint8_t calcPT();
+
     
 private:
 #if not defined  MS5611i2cLOWLEVEL
@@ -186,8 +190,10 @@
     uint64_t cmd_adc(uint8_t cmd);
     uint32_t cmd_prom(uint8_t coef_num);
     uint8_t crc4(uint32_t  n_prom[]);
-    void calcPT();
     uint32_t PTbuffer[8];       // calibration coefficients
+
+    uint8_t step;
+    int32_t D1, D2;
   
 protected:
     I2C     _i2c;