High resolution barometer and altimeter using i2c mode

Dependents:   Q2_Stabi

Fork of ms5611 by Kevin Braun

ms5611.h

Committer:
loopsva
Date:
2015-07-14
Revision:
9:6104e8cdb3ec
Parent:
8:461f68bc94f2

File content as of revision 9:6104e8cdb3ec:

#ifndef MS5611_H
#define MS5611_H

#include "mbed.h"

//IMPORTANT NOTE: First attempt at also using the MS5805.  This code is untested!!

//    #define MS5611i2cLOWLEVEL   1           //if the use of low-level I2C routines is needed
//    #warning "MS5611 using low level I2C routines"
// IMPORTANT NOTE:  On the K64F, "ack/nack", returns from single byte i2c.write(int data) are opposite 
//                  of i2c.write(int address, const char *data, int length, bool repeated=false)    

#define SEA_PRESS           1013.25         //default sea level pressure level in mb
#define KNOWNALT            327.0           //default known altitude, 5200 Franklin Dr., 94588
#define DEGC_DEGF_FLOAT     9.0 / 5.0 + 32.0//convert degrees C to degrees F
#define METERS_FEET         3.2808399       //convert meters to feet
#define FEET_METERS         0.3048006       //convert feet to meters
#define MB_INHG_DOUBLE      0.02952998751   //convert millibars to inches_of_mercury
#define INHG_MB_DOUBLE      33.8638815767   //convert inches_of_mercury to millibars


/** Software routines to access the Measurement Specialties' MS5611-01BA03 
 *  Variometer Module using the I2C bus option.  The MS5611 is a 24 bit 
 *  temperature and pressure transducer for high accuracy Barometer and 
 *  Altimeter applications.  It also includes compensation coefficients
 *  stored within the device. 
 * 
 *  Code adapted from Measurement Specialties:
 *  "AN520 C-code example for MS56xx, MS57xx (except analog sensor), and 
 *  MS58xx series pressure sensors"
 *
 *  Note: AN520 has not been updated for use with the MS5611.  Changes
 *  were necessary to "calcPT()" in order to correct scaling of 
 *  pressure readings.
 * 
 *  Features:
 *          Altitude resolution to 10cm
 *          Fast conversion down to 1 ms
 *          Low power, 1 μA (standby < 0.15 μA)
 *          QFN package 5.0 x 3.0 x 1.0 mm^3
 *          Supply voltage 1.8 to 3.6 V
 *          Integrated digital pressure sensor (24 bit DeltaSigma ADC)
 *          Operating range: 10 to 1200 mbar, -40 to +85 °C
 *          I2C and SPI interface up to 20 MHz
 *          No external components (Internal oscillator)
 *          Excellent long term stability
 *
 * @code
 * #include "mbed.h"
 * #include "ms5611.h" 
 *  
 * #define SDA  PTE25
 * #define SCL  PTE24
 *  
 * //ms5611 ms(SDA, SCL);                        // i2c pins used, legacy default constructor
 * ms5611 ms(SDA, SCL, ms5611::CSBpin_0);      // NEW!! with rev 7. User can set polarity of CSB pin
 * //ms5611 ms(SDA, SCL, ms5611::CSBpin_1);
 * //ms5611 ms(SDA, SCL, ms5611::MS5805);      // NEW!! with rev 8. Allow use of MS5805 as well
 *  
 * Serial pc(USBTX, USBRX);                    // local terminal interface
 *  
 * int main (void) {
 *     pc.baud(230400);                        // set up USB serial speed
 *  
 *     // set up the ms5611
 *     pc.printf("\n\nInitializing the MS5611..\r\n");
 *     int msFlag = ms.cmd_reset();
 *     if(!(msFlag)) {
 *        pc.printf("MS5611 I2C error!!\r\n");
 *        return(-1);
 *    }
 *     pc.printf("Ready\n");
 *  
 *     while(1) {
 *         double Temp = ms.calcTemp();                         //calculate press and temp, then returns current temperature in degC
 *         double Press = ms.calcPressure();                    //calculate press and temp, then returns current pressure in mb
 *         double GetPress = ms.getPressure();                  //returns current pressure in mb. Does no calculations.  Ususally done after calcTemp()
 *         double Altitude = ms.getAltitudeFT(1013.25);         //enter pressure at sea level in mb, returns altitude in feet
 *         double PressSeaLvlFT = ms.getSeaLevelBaroFT(327.2);  //enter known altitude in feet, returns sea level pressure in mb
 *  
 *         pc.printf("Temp:       %6.2f degC   %6.2f  degF\r\n", Temp, Temp * 9.0 / 5.0 + 32.0);    
 *         pc.printf("Barometer: %7.2f mB    %8.3f in/Hg\r\n", Press, Press * MB_INHG_DOUBLE);
 *         pc.printf("Sea_Lvl:   %7.2f mB    %8.3f in/Hg\r\n", PressSeaLvlFT, PressSeaLvlFT * MB_INHG_DOUBLE);
 *         pc.printf("Alt:       %7.2f m     %7.2f  ft\r\n\r\n", Altitude, Altitude * FEET_METERS);
 *         wait(2.0);
 *     }
 * }
 *
 * @endcode
 */
 
//_____ M A C R O S

#define MS5611_ADDR_W 0xEE          // Module address write mode (CSBpin = 0);
#define MS5611_ADDR_R 0xEF          // Module address read mode
#define MS5611_CMD_RESET 0x1E       // ADC reset command
#define MS5611_CMD_ADC_READ 0x00    // ADC read command
#define MS5611_CMD_ADC_CONV 0x40    // ADC conversion command
#define MS5611_CMD_ADC_D1 0x00      // ADC D1 conversion
#define MS5611_CMD_ADC_D2 0x10      // ADC D2 conversion
#define MS5611_CMD_ADC_256 0x00     // ADC OSR=256
#define MS5611_CMD_ADC_512 0x02     // ADC OSR=512
#define MS5611_CMD_ADC_1024 0x04    // ADC OSR=1024
#define MS5611_CMD_ADC_2048 0x06    // ADC OSR=2048
#define MS5611_CMD_ADC_4096 0x08    // ADC OSR=4096
#define MS5805_CMD_ADC_8192 0x0A    // ADC OSR=8192
#define MS5611_CMD_PROM_RD 0xA0     // Prom read command

    /** Create ms5611 controller class
     *
     * @param ms5611 class
     *
     */
class ms5611 {

public:
    enum CSBpolarity {
        CSBpin_0,   //CSB pin is grounded, I2C address is 0xEE and 0xEF
        CSBpin_1,   //CSB pin is tied to Vdd, I2C address is 0xEC and 0xED
        MS5805,     //MS5805 fixed at 0EC and 0xED
    };
    
    /** Create a MS5611 object using the specified I2C object
     *   - User fixed I2C address 0xEE, CSB pin = 0
     *   - This is the default legacy constructor
     * @param sda - mbed I2C interface pin
     * @param scl - mbed I2C interface pin
     * @return NONE
     */
    ms5611(PinName sda, PinName scl);
    
    /** Create a MS5611 object using the specified I2C object
     *   - User defined use of the CSB pin
     *   - CSB pin = 0, user set I2C address to 0xEE
     *   - CSB pin = 1, user set I2C address to 0xEC 
     * @param sda - mbed I2C interface pin
     * @param scl - mbed I2C interface pin
     * @param ms5611::CSBpin_0 - CSB pin tied to ground
     * @param ms5611::CSBpin_1 - CSB pin tied to VDD
     * @param ms5611::MS5805   - MS5805 has only one i2c address
     * @return NONE
     */
    ms5611(PinName sda, PinName scl, CSBpolarity CSBpin);
    
    /** Initialize the MS5611 and set up the coefficients
     *   - First - reset the MS5611
     *   - Second - load coefficient values from the MS5611 PROM
     *   - Third  - calculate coefficient checksum
     *   - This routine only needs to be run once at boot up
     * @param NONE
     * @return int I2C ack/nack status
     */
    int cmd_reset();
    
    /** Calculates compensated temperature
     * @param NONE
     * @return double temperature in degC
     */
    double calcTemp();
    
    /** Calculates compensated barometric pressure
     * @param NONE
     * @return double pressure in millibars
     */
    double calcPressure();
    
    /** Get compensated barometric pressure
     *  - DOES NOT RE-CALCULATE FIRST!!!
     *  - Result only valid if you calcTemp(); first
     * @param NONE
     * @eturn double pressure in millibars
     */
    double getPressure();
    
    /** Calculates altitude in feet
     * @param float known pressure (mB) at sea level
     * @return float altitude in feet
     */
    float getAltitudeFT(float sea_pressure);
    
    /** Calculates sea level baro
     * @param float known altitude in feet
     * @return float sea level barometer in feet
     */
    float getSeaLevelBaroFT(float known_alt);
    
    /** Calculates sea level baro
     * @param float known altitude in meters
     * @return float sea level barometer in meters
     */
    float getSeaLevelBaroM(float known_alt);
    
private:
    char _i2cWAddr;
    char _i2cRAddr;
    int m_i2c_start(bool readMode);
    int MStype;
    void m_i2c_stop(void);
    unsigned char m_i2c_write(unsigned char data);
    unsigned char m_i2c_readAck(void);
    unsigned char m_i2c_readNak(void);
    int m_i2c_send(char cmd);
    void loadCoefs();
    unsigned long cmd_adc(char cmd);
    unsigned int cmd_prom(char coef_num);
    unsigned char crc4(unsigned  n_prom[]);
    void calcPT();
    unsigned int PTbuffer[8];       // calibration coefficients
  
protected:
    I2C     _i2c;
    

}; 
#endif