High resolution barometer and altimeter using i2c mode

Dependents:   Q2_Stabi

Fork of ms5611 by Kevin Braun

Committer:
loopsva
Date:
Tue Jul 14 16:19:59 2015 +0000
Revision:
9:6104e8cdb3ec
Parent:
8:461f68bc94f2
Fixed minor bugs when using low-level I2C routines.  Hi-level I2C routines ok. Also added hooks for the MS5805 (untested).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
loopsva 0:f97f410d4a21 1 #ifndef MS5611_H
loopsva 0:f97f410d4a21 2 #define MS5611_H
loopsva 0:f97f410d4a21 3
loopsva 0:f97f410d4a21 4 #include "mbed.h"
loopsva 0:f97f410d4a21 5
loopsva 9:6104e8cdb3ec 6 //IMPORTANT NOTE: First attempt at also using the MS5805. This code is untested!!
loopsva 9:6104e8cdb3ec 7
loopsva 9:6104e8cdb3ec 8 // #define MS5611i2cLOWLEVEL 1 //if the use of low-level I2C routines is needed
loopsva 9:6104e8cdb3ec 9 // #warning "MS5611 using low level I2C routines"
loopsva 9:6104e8cdb3ec 10 // IMPORTANT NOTE: On the K64F, "ack/nack", returns from single byte i2c.write(int data) are opposite
loopsva 9:6104e8cdb3ec 11 // of i2c.write(int address, const char *data, int length, bool repeated=false)
loopsva 8:461f68bc94f2 12
loopsva 9:6104e8cdb3ec 13 #define SEA_PRESS 1013.25 //default sea level pressure level in mb
loopsva 9:6104e8cdb3ec 14 #define KNOWNALT 327.0 //default known altitude, 5200 Franklin Dr., 94588
loopsva 9:6104e8cdb3ec 15 #define DEGC_DEGF_FLOAT 9.0 / 5.0 + 32.0//convert degrees C to degrees F
loopsva 9:6104e8cdb3ec 16 #define METERS_FEET 3.2808399 //convert meters to feet
loopsva 9:6104e8cdb3ec 17 #define FEET_METERS 0.3048006 //convert feet to meters
loopsva 9:6104e8cdb3ec 18 #define MB_INHG_DOUBLE 0.02952998751 //convert millibars to inches_of_mercury
loopsva 9:6104e8cdb3ec 19 #define INHG_MB_DOUBLE 33.8638815767 //convert inches_of_mercury to millibars
loopsva 5:0d7b229474c6 20
loopsva 5:0d7b229474c6 21
loopsva 0:f97f410d4a21 22 /** Software routines to access the Measurement Specialties' MS5611-01BA03
loopsva 0:f97f410d4a21 23 * Variometer Module using the I2C bus option. The MS5611 is a 24 bit
loopsva 0:f97f410d4a21 24 * temperature and pressure transducer for high accuracy Barometer and
loopsva 0:f97f410d4a21 25 * Altimeter applications. It also includes compensation coefficients
loopsva 0:f97f410d4a21 26 * stored within the device.
loopsva 0:f97f410d4a21 27 *
loopsva 0:f97f410d4a21 28 * Code adapted from Measurement Specialties:
loopsva 0:f97f410d4a21 29 * "AN520 C-code example for MS56xx, MS57xx (except analog sensor), and
loopsva 0:f97f410d4a21 30 * MS58xx series pressure sensors"
loopsva 0:f97f410d4a21 31 *
loopsva 0:f97f410d4a21 32 * Note: AN520 has not been updated for use with the MS5611. Changes
loopsva 0:f97f410d4a21 33 * were necessary to "calcPT()" in order to correct scaling of
loopsva 0:f97f410d4a21 34 * pressure readings.
loopsva 0:f97f410d4a21 35 *
loopsva 0:f97f410d4a21 36 * Features:
loopsva 0:f97f410d4a21 37 * Altitude resolution to 10cm
loopsva 0:f97f410d4a21 38 * Fast conversion down to 1 ms
loopsva 0:f97f410d4a21 39 * Low power, 1 μA (standby < 0.15 μA)
loopsva 0:f97f410d4a21 40 * QFN package 5.0 x 3.0 x 1.0 mm^3
loopsva 0:f97f410d4a21 41 * Supply voltage 1.8 to 3.6 V
loopsva 0:f97f410d4a21 42 * Integrated digital pressure sensor (24 bit DeltaSigma ADC)
loopsva 0:f97f410d4a21 43 * Operating range: 10 to 1200 mbar, -40 to +85 °C
loopsva 0:f97f410d4a21 44 * I2C and SPI interface up to 20 MHz
loopsva 0:f97f410d4a21 45 * No external components (Internal oscillator)
loopsva 0:f97f410d4a21 46 * Excellent long term stability
loopsva 0:f97f410d4a21 47 *
loopsva 0:f97f410d4a21 48 * @code
loopsva 0:f97f410d4a21 49 * #include "mbed.h"
loopsva 0:f97f410d4a21 50 * #include "ms5611.h"
loopsva 9:6104e8cdb3ec 51 *
loopsva 9:6104e8cdb3ec 52 * #define SDA PTE25
loopsva 9:6104e8cdb3ec 53 * #define SCL PTE24
loopsva 9:6104e8cdb3ec 54 *
loopsva 9:6104e8cdb3ec 55 * //ms5611 ms(SDA, SCL); // i2c pins used, legacy default constructor
loopsva 9:6104e8cdb3ec 56 * ms5611 ms(SDA, SCL, ms5611::CSBpin_0); // NEW!! with rev 7. User can set polarity of CSB pin
loopsva 9:6104e8cdb3ec 57 * //ms5611 ms(SDA, SCL, ms5611::CSBpin_1);
loopsva 9:6104e8cdb3ec 58 * //ms5611 ms(SDA, SCL, ms5611::MS5805); // NEW!! with rev 8. Allow use of MS5805 as well
loopsva 9:6104e8cdb3ec 59 *
loopsva 9:6104e8cdb3ec 60 * Serial pc(USBTX, USBRX); // local terminal interface
loopsva 9:6104e8cdb3ec 61 *
loopsva 0:f97f410d4a21 62 * int main (void) {
loopsva 9:6104e8cdb3ec 63 * pc.baud(230400); // set up USB serial speed
loopsva 9:6104e8cdb3ec 64 *
loopsva 0:f97f410d4a21 65 * // set up the ms5611
loopsva 9:6104e8cdb3ec 66 * pc.printf("\n\nInitializing the MS5611..\r\n");
loopsva 9:6104e8cdb3ec 67 * int msFlag = ms.cmd_reset();
loopsva 9:6104e8cdb3ec 68 * if(!(msFlag)) {
loopsva 9:6104e8cdb3ec 69 * pc.printf("MS5611 I2C error!!\r\n");
loopsva 9:6104e8cdb3ec 70 * return(-1);
loopsva 9:6104e8cdb3ec 71 * }
loopsva 0:f97f410d4a21 72 * pc.printf("Ready\n");
loopsva 9:6104e8cdb3ec 73 *
loopsva 0:f97f410d4a21 74 * while(1) {
loopsva 6:41c370fa1f7b 75 * double Temp = ms.calcTemp(); //calculate press and temp, then returns current temperature in degC
loopsva 6:41c370fa1f7b 76 * double Press = ms.calcPressure(); //calculate press and temp, then returns current pressure in mb
loopsva 6:41c370fa1f7b 77 * double GetPress = ms.getPressure(); //returns current pressure in mb. Does no calculations. Ususally done after calcTemp()
loopsva 6:41c370fa1f7b 78 * double Altitude = ms.getAltitudeFT(1013.25); //enter pressure at sea level in mb, returns altitude in feet
loopsva 6:41c370fa1f7b 79 * double PressSeaLvlFT = ms.getSeaLevelBaroFT(327.2); //enter known altitude in feet, returns sea level pressure in mb
loopsva 9:6104e8cdb3ec 80 *
loopsva 9:6104e8cdb3ec 81 * pc.printf("Temp: %6.2f degC %6.2f degF\r\n", Temp, Temp * 9.0 / 5.0 + 32.0);
loopsva 9:6104e8cdb3ec 82 * pc.printf("Barometer: %7.2f mB %8.3f in/Hg\r\n", Press, Press * MB_INHG_DOUBLE);
loopsva 9:6104e8cdb3ec 83 * pc.printf("Sea_Lvl: %7.2f mB %8.3f in/Hg\r\n", PressSeaLvlFT, PressSeaLvlFT * MB_INHG_DOUBLE);
loopsva 9:6104e8cdb3ec 84 * pc.printf("Alt: %7.2f m %7.2f ft\r\n\r\n", Altitude, Altitude * FEET_METERS);
loopsva 0:f97f410d4a21 85 * wait(2.0);
loopsva 0:f97f410d4a21 86 * }
loopsva 0:f97f410d4a21 87 * }
loopsva 0:f97f410d4a21 88 *
loopsva 0:f97f410d4a21 89 * @endcode
loopsva 0:f97f410d4a21 90 */
loopsva 0:f97f410d4a21 91
loopsva 0:f97f410d4a21 92 //_____ M A C R O S
loopsva 0:f97f410d4a21 93
loopsva 9:6104e8cdb3ec 94 #define MS5611_ADDR_W 0xEE // Module address write mode (CSBpin = 0);
loopsva 9:6104e8cdb3ec 95 #define MS5611_ADDR_R 0xEF // Module address read mode
loopsva 9:6104e8cdb3ec 96 #define MS5611_CMD_RESET 0x1E // ADC reset command
loopsva 9:6104e8cdb3ec 97 #define MS5611_CMD_ADC_READ 0x00 // ADC read command
loopsva 9:6104e8cdb3ec 98 #define MS5611_CMD_ADC_CONV 0x40 // ADC conversion command
loopsva 9:6104e8cdb3ec 99 #define MS5611_CMD_ADC_D1 0x00 // ADC D1 conversion
loopsva 9:6104e8cdb3ec 100 #define MS5611_CMD_ADC_D2 0x10 // ADC D2 conversion
loopsva 9:6104e8cdb3ec 101 #define MS5611_CMD_ADC_256 0x00 // ADC OSR=256
loopsva 9:6104e8cdb3ec 102 #define MS5611_CMD_ADC_512 0x02 // ADC OSR=512
loopsva 9:6104e8cdb3ec 103 #define MS5611_CMD_ADC_1024 0x04 // ADC OSR=1024
loopsva 9:6104e8cdb3ec 104 #define MS5611_CMD_ADC_2048 0x06 // ADC OSR=2048
loopsva 9:6104e8cdb3ec 105 #define MS5611_CMD_ADC_4096 0x08 // ADC OSR=4096
loopsva 9:6104e8cdb3ec 106 #define MS5805_CMD_ADC_8192 0x0A // ADC OSR=8192
loopsva 9:6104e8cdb3ec 107 #define MS5611_CMD_PROM_RD 0xA0 // Prom read command
loopsva 0:f97f410d4a21 108
loopsva 2:05804ed70748 109 /** Create ms5611 controller class
loopsva 2:05804ed70748 110 *
loopsva 2:05804ed70748 111 * @param ms5611 class
loopsva 2:05804ed70748 112 *
loopsva 2:05804ed70748 113 */
loopsva 1:94a46b4fed9d 114 class ms5611 {
loopsva 0:f97f410d4a21 115
loopsva 0:f97f410d4a21 116 public:
loopsva 7:90ee2168baa7 117 enum CSBpolarity {
loopsva 9:6104e8cdb3ec 118 CSBpin_0, //CSB pin is grounded, I2C address is 0xEE and 0xEF
loopsva 9:6104e8cdb3ec 119 CSBpin_1, //CSB pin is tied to Vdd, I2C address is 0xEC and 0xED
loopsva 9:6104e8cdb3ec 120 MS5805, //MS5805 fixed at 0EC and 0xED
loopsva 7:90ee2168baa7 121 };
loopsva 9:6104e8cdb3ec 122
loopsva 0:f97f410d4a21 123 /** Create a MS5611 object using the specified I2C object
loopsva 7:90ee2168baa7 124 * - User fixed I2C address 0xEE, CSB pin = 0
loopsva 7:90ee2168baa7 125 * - This is the default legacy constructor
loopsva 7:90ee2168baa7 126 * @param sda - mbed I2C interface pin
loopsva 7:90ee2168baa7 127 * @param scl - mbed I2C interface pin
loopsva 9:6104e8cdb3ec 128 * @return NONE
loopsva 0:f97f410d4a21 129 */
loopsva 0:f97f410d4a21 130 ms5611(PinName sda, PinName scl);
loopsva 9:6104e8cdb3ec 131
loopsva 7:90ee2168baa7 132 /** Create a MS5611 object using the specified I2C object
loopsva 7:90ee2168baa7 133 * - User defined use of the CSB pin
loopsva 7:90ee2168baa7 134 * - CSB pin = 0, user set I2C address to 0xEE
loopsva 7:90ee2168baa7 135 * - CSB pin = 1, user set I2C address to 0xEC
loopsva 7:90ee2168baa7 136 * @param sda - mbed I2C interface pin
loopsva 7:90ee2168baa7 137 * @param scl - mbed I2C interface pin
loopsva 7:90ee2168baa7 138 * @param ms5611::CSBpin_0 - CSB pin tied to ground
loopsva 7:90ee2168baa7 139 * @param ms5611::CSBpin_1 - CSB pin tied to VDD
loopsva 9:6104e8cdb3ec 140 * @param ms5611::MS5805 - MS5805 has only one i2c address
loopsva 9:6104e8cdb3ec 141 * @return NONE
loopsva 7:90ee2168baa7 142 */
loopsva 7:90ee2168baa7 143 ms5611(PinName sda, PinName scl, CSBpolarity CSBpin);
loopsva 9:6104e8cdb3ec 144
loopsva 0:f97f410d4a21 145 /** Initialize the MS5611 and set up the coefficients
loopsva 9:6104e8cdb3ec 146 * - First - reset the MS5611
loopsva 9:6104e8cdb3ec 147 * - Second - load coefficient values from the MS5611 PROM
loopsva 9:6104e8cdb3ec 148 * - Third - calculate coefficient checksum
loopsva 9:6104e8cdb3ec 149 * - This routine only needs to be run once at boot up
loopsva 0:f97f410d4a21 150 * @param NONE
loopsva 9:6104e8cdb3ec 151 * @return int I2C ack/nack status
loopsva 0:f97f410d4a21 152 */
loopsva 9:6104e8cdb3ec 153 int cmd_reset();
loopsva 9:6104e8cdb3ec 154
loopsva 9:6104e8cdb3ec 155 /** Calculates compensated temperature
loopsva 0:f97f410d4a21 156 * @param NONE
loopsva 9:6104e8cdb3ec 157 * @return double temperature in degC
loopsva 0:f97f410d4a21 158 */
loopsva 0:f97f410d4a21 159 double calcTemp();
loopsva 9:6104e8cdb3ec 160
loopsva 9:6104e8cdb3ec 161 /** Calculates compensated barometric pressure
loopsva 0:f97f410d4a21 162 * @param NONE
loopsva 9:6104e8cdb3ec 163 * @return double pressure in millibars
loopsva 0:f97f410d4a21 164 */
loopsva 0:f97f410d4a21 165 double calcPressure();
loopsva 9:6104e8cdb3ec 166
loopsva 9:6104e8cdb3ec 167 /** Get compensated barometric pressure
loopsva 9:6104e8cdb3ec 168 * - DOES NOT RE-CALCULATE FIRST!!!
loopsva 9:6104e8cdb3ec 169 * - Result only valid if you calcTemp(); first
loopsva 3:c2d1b0d432ad 170 * @param NONE
loopsva 9:6104e8cdb3ec 171 * @eturn double pressure in millibars
loopsva 3:c2d1b0d432ad 172 */
loopsva 3:c2d1b0d432ad 173 double getPressure();
loopsva 9:6104e8cdb3ec 174
loopsva 9:6104e8cdb3ec 175 /** Calculates altitude in feet
loopsva 5:0d7b229474c6 176 * @param float known pressure (mB) at sea level
loopsva 9:6104e8cdb3ec 177 * @return float altitude in feet
loopsva 3:c2d1b0d432ad 178 */
loopsva 3:c2d1b0d432ad 179 float getAltitudeFT(float sea_pressure);
loopsva 9:6104e8cdb3ec 180
loopsva 9:6104e8cdb3ec 181 /** Calculates sea level baro
loopsva 5:0d7b229474c6 182 * @param float known altitude in feet
loopsva 9:6104e8cdb3ec 183 * @return float sea level barometer in feet
loopsva 5:0d7b229474c6 184 */
loopsva 5:0d7b229474c6 185 float getSeaLevelBaroFT(float known_alt);
loopsva 9:6104e8cdb3ec 186
loopsva 9:6104e8cdb3ec 187 /** Calculates sea level baro
loopsva 5:0d7b229474c6 188 * @param float known altitude in meters
loopsva 9:6104e8cdb3ec 189 * @return float sea level barometer in meters
loopsva 5:0d7b229474c6 190 */
loopsva 5:0d7b229474c6 191 float getSeaLevelBaroM(float known_alt);
loopsva 0:f97f410d4a21 192
loopsva 0:f97f410d4a21 193 private:
loopsva 7:90ee2168baa7 194 char _i2cWAddr;
loopsva 7:90ee2168baa7 195 char _i2cRAddr;
loopsva 0:f97f410d4a21 196 int m_i2c_start(bool readMode);
loopsva 9:6104e8cdb3ec 197 int MStype;
loopsva 0:f97f410d4a21 198 void m_i2c_stop(void);
loopsva 0:f97f410d4a21 199 unsigned char m_i2c_write(unsigned char data);
loopsva 0:f97f410d4a21 200 unsigned char m_i2c_readAck(void);
loopsva 0:f97f410d4a21 201 unsigned char m_i2c_readNak(void);
loopsva 9:6104e8cdb3ec 202 int m_i2c_send(char cmd);
loopsva 0:f97f410d4a21 203 void loadCoefs();
loopsva 0:f97f410d4a21 204 unsigned long cmd_adc(char cmd);
loopsva 0:f97f410d4a21 205 unsigned int cmd_prom(char coef_num);
loopsva 2:05804ed70748 206 unsigned char crc4(unsigned n_prom[]);
loopsva 0:f97f410d4a21 207 void calcPT();
loopsva 0:f97f410d4a21 208 unsigned int PTbuffer[8]; // calibration coefficients
loopsva 0:f97f410d4a21 209
loopsva 0:f97f410d4a21 210 protected:
loopsva 0:f97f410d4a21 211 I2C _i2c;
loopsva 0:f97f410d4a21 212
loopsva 0:f97f410d4a21 213
loopsva 0:f97f410d4a21 214 };
loopsva 0:f97f410d4a21 215 #endif