High resolution barometer and altimeter using i2c mode
Fork of ms5611 by
ms5611.h@9:6104e8cdb3ec, 2015-07-14 (annotated)
- 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?
User | Revision | Line number | New 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 |