Lib for HP03SA atmospheric pressure sensor. Provides pressure, temperature and altitude data.

Dependents:   mbed_HP03SA_LM77

Committer:
wim
Date:
Sat Jan 10 19:10:17 2015 +0000
Revision:
0:61bbd81782de
First version of HP03SA library.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wim 0:61bbd81782de 1 /* mbed HP03SA Library, for an I2C Pressure and Temperature sensor which provides derived Altitude values
wim 0:61bbd81782de 2 * Copyright (c) 2015, v01: WH, Initial version, ported in part from Elektor weatherstation (Sept 2011), Author: W. Waetzig
wim 0:61bbd81782de 3 * See http://www.elektor-labs.com/project/usb-long-term-weather-logger-100888.12037.html
wim 0:61bbd81782de 4 * Code also based on several other public sources:
wim 0:61bbd81782de 5 * See http://en.wikipedia.org/wiki/Atmospheric_pressure
wim 0:61bbd81782de 6 * See https://learn.sparkfun.com/tutorials/bmp180-barometric-pressure-sensor-hookup-?_ga=1.94307604.888266135.1310146152
wim 0:61bbd81782de 7 *
wim 0:61bbd81782de 8 * The HP03S pressure sensor from Hope Microelectronics contains a piezoresistive transducer and
wim 0:61bbd81782de 9 * integrated 16-bit A/D converter (ADC), along with control logic and an I2C interface.
wim 0:61bbd81782de 10 * The transducer outputs one voltage that depends on pressure and one that depends on temperature.
wim 0:61bbd81782de 11 * These analogue values are alternately converted by the ADC and the results made available on the I2C interface.
wim 0:61bbd81782de 12 * During the manufacturing process eleven sensor-specific calibration values with a length of two bytes are stored
wim 0:61bbd81782de 13 * in the device’s EEPROM, and these can also be retrieved by the microcontroller.
wim 0:61bbd81782de 14 * The correction-parameters are read out from the device in used in the calculation.
wim 0:61bbd81782de 15 * A 32 kHz clock with an amplitude of 3 V is required to drive the ADC. This could be derived from the mbed PwmOut.
wim 0:61bbd81782de 16 * The HP03SA has an absolute pressure range between 300-1100 hPa. Operating temp is -20 to +60 degrees Celsius.
wim 0:61bbd81782de 17 * Note: 1 atm = 1013.25 hPa = 1013.25 mbar
wim 0:61bbd81782de 18 *
wim 0:61bbd81782de 19 * Unit conversions see http://www.hoperf.com/docs/guide/160.htm
wim 0:61bbd81782de 20 *
wim 0:61bbd81782de 21 * bar Bar convert to 100,000 Pascals exactly
wim 0:61bbd81782de 22 * psi Pounds per Square Inch convert to 6894.76 Pascals
wim 0:61bbd81782de 23 * mb or mbar Millibar convert to 100 Pascals (1 hPa) exactly
wim 0:61bbd81782de 24 * hPa Hectopascal convert to 100 Pascals exactly
wim 0:61bbd81782de 25 * kPa Kilopascal convert to 1,000 Pascals
wim 0:61bbd81782de 26 * MPa Megapascal convert to 1,000,000 Pascals
wim 0:61bbd81782de 27 * Kgf/cm² or kg/cm² Kilogram force per Square Centimetre convert to 98,066.5 Pascals
wim 0:61bbd81782de 28 * N/m² Newton per Square Meter convert to 1 Pascal (SI unit for pressure)
wim 0:61bbd81782de 29 * torr Torr convert to 133.322 Pascals
wim 0:61bbd81782de 30 * mtorr Millitorr convert to 0.133322 Pascals
wim 0:61bbd81782de 31 * mm Hg convert to 133.322387415 Pascals
wim 0:61bbd81782de 32 * 1 atm 1 Atmosphere convert to 101325 Pascals exactly (760 mm Hg)
wim 0:61bbd81782de 33 * 1 atm 1 Atmosphere convert to 1013.25 hPa exactly
wim 0:61bbd81782de 34 * Dynes/cm² or D/cm² Dynes per Square Centimetre convert to 0.1 Pascals exactly
wim 0:61bbd81782de 35 * oz/in² Ounces per Square Inch convert to 430.922 Pascals
wim 0:61bbd81782de 36 * tsi (UK) or tfsi (UK) Tonnes Force per Square Inch (Long, UK) convert to 15444300 Pascals
wim 0:61bbd81782de 37 * tsi (USA) or tfsi (USA) Ton Force per Square Inch (Short, USA) convert to 13789500 Pascals
wim 0:61bbd81782de 38 * tsf (USA) or tfsf (USA) Tons Force per Square Foot (Short, USA) convert to 95760.5 Pascals
wim 0:61bbd81782de 39 * psf Pounds per Square Foot convert to 47.8803 Pascals
wim 0:61bbd81782de 40 * g/cm² or gf/cm² Grammes Force per Square Centimetre convert to 98.0665 Pascals
wim 0:61bbd81782de 41 *
wim 0:61bbd81782de 42 * The Altitude calculation is based on the ICAO Standard Atmosphere model ISA. The code has
wim 0:61bbd81782de 43 * certainly not been thoroughly validated! Use at own risk.
wim 0:61bbd81782de 44 *
wim 0:61bbd81782de 45 * QNH is the barometric altimeter setting that causes an altimeter to read
wim 0:61bbd81782de 46 * airfield elevation above mean sea level when on the airfield. In ISA temperature
wim 0:61bbd81782de 47 * conditions the altimeter will read altitude above mean sea level in the vicinity of the airfield.
wim 0:61bbd81782de 48 * Note: Remember QNH as mnemonic for "nautical height"
wim 0:61bbd81782de 49 * Average sea-level pressure is 101.325 kPa (1013.25 hPa or mbar) or 29.92 inches (inHg) or
wim 0:61bbd81782de 50 * 760 millimetres of mercury (mmHg). In aviation weather reports (METAR), QNH is transmitted
wim 0:61bbd81782de 51 * around the world in hectopascals or millibars (1 hectopascal = 1 millibar), except in the
wim 0:61bbd81782de 52 * United States, Canada, and Colombia where it is reported in inches (to two decimal places) of mercury.
wim 0:61bbd81782de 53 *
wim 0:61bbd81782de 54 *
wim 0:61bbd81782de 55 * Permission is hereby granted, free of charge, to any person obtaining a copy
wim 0:61bbd81782de 56 * of this software and associated documentation files (the "Software"), to deal
wim 0:61bbd81782de 57 * in the Software without restriction, including without limitation the rights
wim 0:61bbd81782de 58 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
wim 0:61bbd81782de 59 * copies of the Software, and to permit persons to whom the Software is
wim 0:61bbd81782de 60 * furnished to do so, subject to the following conditions:
wim 0:61bbd81782de 61 *
wim 0:61bbd81782de 62 * The above copyright notice and this permission notice shall be included in
wim 0:61bbd81782de 63 * all copies or substantial portions of the Software.
wim 0:61bbd81782de 64 *
wim 0:61bbd81782de 65 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
wim 0:61bbd81782de 66 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
wim 0:61bbd81782de 67 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
wim 0:61bbd81782de 68 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
wim 0:61bbd81782de 69 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
wim 0:61bbd81782de 70 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
wim 0:61bbd81782de 71 * THE SOFTWARE.
wim 0:61bbd81782de 72 */
wim 0:61bbd81782de 73 #ifndef MBED_HP03SA_H
wim 0:61bbd81782de 74 #define MBED_HP03SA_H
wim 0:61bbd81782de 75
wim 0:61bbd81782de 76 #include "mbed.h"
wim 0:61bbd81782de 77
wim 0:61bbd81782de 78 /** An interface for the HP03S I2C pressure and temperature sensor
wim 0:61bbd81782de 79 *
wim 0:61bbd81782de 80 * @code
wim 0:61bbd81782de 81 * #include "mbed.h"
wim 0:61bbd81782de 82 * #include "HP03S.h"
wim 0:61bbd81782de 83 *
wim 0:61bbd81782de 84 * // I2C Communication
wim 0:61bbd81782de 85 * I2C i2c(p28,p27); // SDA, SCL
wim 0:61bbd81782de 86 *
wim 0:61bbd81782de 87 * // Serial Communication*
wim 0:61bbd81782de 88 * Serial pc(USBTX,USBRX);
wim 0:61bbd81782de 89 *
wim 0:61bbd81782de 90 * // Instantiate HP03SA
wim 0:61bbd81782de 91 * HP03SA hp03sa(&i2c, D_XCLR); // I2C bus, XCLK Pin
wim 0:61bbd81782de 92 * // Generate the 32kHz master clock for HP03SA
wim 0:61bbd81782de 93 * PwmOut mclk(p21);
wim 0:61bbd81782de 94 *
wim 0:61bbd81782de 95 * int main() {
wim 0:61bbd81782de 96 * pc.printf("Hello World!\n");
wim 0:61bbd81782de 97 *
wim 0:61bbd81782de 98 * //Init MCLK for HP03SA
wim 0:61bbd81782de 99 * mclk.period_us(30); //32768 KHz
wim 0:61bbd81782de 100 * mclk.pulsewidth_us(15); //32768 KHz
wim 0:61bbd81782de 101 *
wim 0:61bbd81782de 102 * while(1) {
wim 0:61bbd81782de 103 * // Take reading from sensor
wim 0:61bbd81782de 104 * hp03sa.sample();
wim 0:61bbd81782de 105 *
wim 0:61bbd81782de 106 * // Show Pressure
wim 0:61bbd81782de 107 * pc.printf("Absolute atmospheric pressure is %.1f [hPa]\r\n", (float) hp03sa.getAbsPressure() / 10.0f);
wim 0:61bbd81782de 108 * pc.printf("Sealevel atmospheric pressure is %.1f [hPa]\r\n", (float) hp03sa.getSeaPressure(20) / 10.0f); // About right where I live..
wim 0:61bbd81782de 109 *
wim 0:61bbd81782de 110 * // Show Temperature
wim 0:61bbd81782de 111 * pc.printf("Ambient temperature is %.1f [C]\r\n", (float) hp03sa.getTemperature() / 10.0f);
wim 0:61bbd81782de 112 *
wim 0:61bbd81782de 113 * // Show Altitude meters
wim 0:61bbd81782de 114 * pc.printf("Altitude estimated at %d [m]\r\n", hp03sa.getAltitude());
wim 0:61bbd81782de 115 *
wim 0:61bbd81782de 116 * // Show Altitude Ft
wim 0:61bbd81782de 117 * pc.printf("Altitude estimated at %d [ft]\r\n", hp03sa.getAltitudeFt());
wim 0:61bbd81782de 118 *
wim 0:61bbd81782de 119 * wait(1.0);
wim 0:61bbd81782de 120 * }
wim 0:61bbd81782de 121 * }
wim 0:61bbd81782de 122 * @endcode
wim 0:61bbd81782de 123 */
wim 0:61bbd81782de 124
wim 0:61bbd81782de 125 // Device I2C Slave addresses
wim 0:61bbd81782de 126 #define HP03SA_BARO_SA 0xEE
wim 0:61bbd81782de 127 #define HP03SA_EEPROM_SA 0xA0
wim 0:61bbd81782de 128
wim 0:61bbd81782de 129 //ISA computation constants
wim 0:61bbd81782de 130 #define RLGM 0.19026674f // ISA Exponent (R * L) / (g * M)
wim 0:61bbd81782de 131 #define GMRL 5.25578009f // ISA Exponent (g * M) / (R * L)
wim 0:61bbd81782de 132 #define LBASE_X10 0.065f // ISA Temp Lapse (i.e. drop) in K per meter x10
wim 0:61bbd81782de 133 #define TBASE_X10 (150.0f + 2731.5f) // ISA Ref Temp in K x10
wim 0:61bbd81782de 134 #define PBASE_X10 (1013.25f * 10.0f) // ISA Ref Pres in hPa x10
wim 0:61bbd81782de 135
wim 0:61bbd81782de 136 /** Create an HP03SA Class instance
wim 0:61bbd81782de 137 *
wim 0:61bbd81782de 138 */
wim 0:61bbd81782de 139 class HP03SA {
wim 0:61bbd81782de 140
wim 0:61bbd81782de 141 public:
wim 0:61bbd81782de 142
wim 0:61bbd81782de 143 /** Create an HP03SA device instance
wim 0:61bbd81782de 144 *
wim 0:61bbd81782de 145 * @param i2c I2C Bus
wim 0:61bbd81782de 146 * @param XCLR Clock enable control line
wim 0:61bbd81782de 147 */
wim 0:61bbd81782de 148 HP03SA(I2C *i2c, PinName XCLR);
wim 0:61bbd81782de 149
wim 0:61bbd81782de 150 /** Get Status
wim 0:61bbd81782de 151 *
wim 0:61bbd81782de 152 * @return bool Sensor ready
wim 0:61bbd81782de 153 */
wim 0:61bbd81782de 154 bool getStatus(void);
wim 0:61bbd81782de 155
wim 0:61bbd81782de 156 /** Get Pressure and Temperature sample
wim 0:61bbd81782de 157 *
wim 0:61bbd81782de 158 * @return none
wim 0:61bbd81782de 159 */
wim 0:61bbd81782de 160 void sample(void);
wim 0:61bbd81782de 161
wim 0:61bbd81782de 162 /** Get Absolute Atmospheric Pressure in hPa x 10
wim 0:61bbd81782de 163 * Note: sample() must be called before getAbsPressure()
wim 0:61bbd81782de 164 *
wim 0:61bbd81782de 165 * @return int Pressure in hPa x 10
wim 0:61bbd81782de 166 */
wim 0:61bbd81782de 167 int getAbsPressure(void);
wim 0:61bbd81782de 168
wim 0:61bbd81782de 169 /** Get Sealevel Atmospheric Pressure in hPa x 10
wim 0:61bbd81782de 170 * Note: sample() must be called before getSeaPressure()
wim 0:61bbd81782de 171 *
wim 0:61bbd81782de 172 * @param int alt_meter Altitude above Mean Sea Level where measurement is taken
wim 0:61bbd81782de 173 * @return int Pressure at sea level in hPa x 10
wim 0:61bbd81782de 174 */
wim 0:61bbd81782de 175 int getSeaPressure(int alt_meter);
wim 0:61bbd81782de 176
wim 0:61bbd81782de 177 /** Get Temperature as int in °Celsius x 10
wim 0:61bbd81782de 178 * Note: sample() must be called before getTemperature()
wim 0:61bbd81782de 179 *
wim 0:61bbd81782de 180 * @return int Temperature in °Celsius x 10
wim 0:61bbd81782de 181 */
wim 0:61bbd81782de 182 int getTemperatureInt(void);
wim 0:61bbd81782de 183
wim 0:61bbd81782de 184 /** Get Temperature as float in °Celsius
wim 0:61bbd81782de 185 * Note: sample() must be called before getTemperatureFl()
wim 0:61bbd81782de 186 *
wim 0:61bbd81782de 187 * @return float Temperature in °Celsius
wim 0:61bbd81782de 188 */
wim 0:61bbd81782de 189 float getTemperature(void);
wim 0:61bbd81782de 190
wim 0:61bbd81782de 191 /** Get Altitude in meters using ISA
wim 0:61bbd81782de 192 * Note: sample() must be called before getAltitude()
wim 0:61bbd81782de 193 *
wim 0:61bbd81782de 194 * @return int Altitude in meters above Mean Sea Level (MSL)
wim 0:61bbd81782de 195 */
wim 0:61bbd81782de 196 int getAltitude(void);
wim 0:61bbd81782de 197
wim 0:61bbd81782de 198 /** Get Altitude in feet using ISA
wim 0:61bbd81782de 199 * Note: sample() must be called before getAltitudeFt()
wim 0:61bbd81782de 200 *
wim 0:61bbd81782de 201 * @return int Altitude in feet above Mean Sea Level (MSL)
wim 0:61bbd81782de 202 */
wim 0:61bbd81782de 203 int getAltitudeFt();
wim 0:61bbd81782de 204
wim 0:61bbd81782de 205 /** Set QNH Pressure to calibrate sensor
wim 0:61bbd81782de 206 *
wim 0:61bbd81782de 207 * @param int pressure_x10 at Mean Sea Level in hPa x 10
wim 0:61bbd81782de 208 * The getAltitude() reading will be 0 m for the set pressure.
wim 0:61bbd81782de 209 */
wim 0:61bbd81782de 210 void setPressure(int pressure_x10 = PBASE_X10);
wim 0:61bbd81782de 211
wim 0:61bbd81782de 212 /** Set QNH Altitude in meter to calibrate sensor
wim 0:61bbd81782de 213 *
wim 0:61bbd81782de 214 * @param int alt_meter Altitude in meters above Mean Sea Level (MSL) for current pressure
wim 0:61bbd81782de 215 * The getAltitude() reading will be 'alt_meter' m for the current pressure.
wim 0:61bbd81782de 216 */
wim 0:61bbd81782de 217 void setAltitude(int alt_meter = 0);
wim 0:61bbd81782de 218
wim 0:61bbd81782de 219
wim 0:61bbd81782de 220 /** Set QNH Altitude in feet to calibrate sensor
wim 0:61bbd81782de 221 *
wim 0:61bbd81782de 222 * @param int alt_feet Altitude in meters above Mean Sea Level (MSL) for current pressure
wim 0:61bbd81782de 223 * The getAltitudeFt() reading will be 'alt_feet' ft for the current pressure.
wim 0:61bbd81782de 224 */
wim 0:61bbd81782de 225 void setAltitudeFt(int alt_feet = 0);
wim 0:61bbd81782de 226
wim 0:61bbd81782de 227
wim 0:61bbd81782de 228 /** Convert Temperature from °Celsius into °Fahrenheit
wim 0:61bbd81782de 229 *
wim 0:61bbd81782de 230 * @param float celsius in °Celsius
wim 0:61bbd81782de 231 * @return float temperature in °Fahrenheit
wim 0:61bbd81782de 232 */
wim 0:61bbd81782de 233 float celsiusToFahrenheit(float celsius);
wim 0:61bbd81782de 234
wim 0:61bbd81782de 235 private:
wim 0:61bbd81782de 236
wim 0:61bbd81782de 237 /** Init HP03SA device
wim 0:61bbd81782de 238 *
wim 0:61bbd81782de 239 * @return none
wim 0:61bbd81782de 240 */
wim 0:61bbd81782de 241 void _init();
wim 0:61bbd81782de 242
wim 0:61bbd81782de 243 /** Read ADC value (either pressure or temperature depending on Control Register setting)
wim 0:61bbd81782de 244 *
wim 0:61bbd81782de 245 * @return int pressure or temperature
wim 0:61bbd81782de 246 */
wim 0:61bbd81782de 247 int _readADC (void);
wim 0:61bbd81782de 248
wim 0:61bbd81782de 249 /** Read Pressure and Temperature
wim 0:61bbd81782de 250 *
wim 0:61bbd81782de 251 * @return none
wim 0:61bbd81782de 252 */
wim 0:61bbd81782de 253 void _readTempPres(void);
wim 0:61bbd81782de 254
wim 0:61bbd81782de 255 /** Calculate Pressure and Temperature
wim 0:61bbd81782de 256 *
wim 0:61bbd81782de 257 * @return none
wim 0:61bbd81782de 258 */
wim 0:61bbd81782de 259 void _calcTempPres(void);
wim 0:61bbd81782de 260
wim 0:61bbd81782de 261 /** Calculate Altitude
wim 0:61bbd81782de 262 *
wim 0:61bbd81782de 263 * @return none
wim 0:61bbd81782de 264 */
wim 0:61bbd81782de 265 void _calcAlt(void);
wim 0:61bbd81782de 266
wim 0:61bbd81782de 267 //I2C interface and ADC control
wim 0:61bbd81782de 268 I2C *_i2c;
wim 0:61bbd81782de 269 DigitalOut _xclr;
wim 0:61bbd81782de 270
wim 0:61bbd81782de 271 //Raw values, computed values
wim 0:61bbd81782de 272 int _D1, _D2; // measured values: pressure,temperature.
wim 0:61bbd81782de 273 int _dUT, _off; // auxiliary variables
wim 0:61bbd81782de 274 int _sens, _x; // auxiliary variables
wim 0:61bbd81782de 275 int _temp_x10; // temperature in Celsius x 10
wim 0:61bbd81782de 276 int _pres_x10; // pressure in hPa x 10
wim 0:61bbd81782de 277 int _alt; // altitude in m
wim 0:61bbd81782de 278 float _pres_base_x10;
wim 0:61bbd81782de 279 float _temp_base_x10;
wim 0:61bbd81782de 280
wim 0:61bbd81782de 281 //Calibration coefficients
wim 0:61bbd81782de 282 int _C1, //Sensitivity coefficient
wim 0:61bbd81782de 283 _C2, //Offset coefficient
wim 0:61bbd81782de 284 _C3, //Temp coefficient of sensitivity
wim 0:61bbd81782de 285 _C4, //Temp coefficient of offset
wim 0:61bbd81782de 286 _C5, //Reference temperature
wim 0:61bbd81782de 287 _C6, //Temp coefficient of temperrature
wim 0:61bbd81782de 288 _C7; //Offset fine tuning
wim 0:61bbd81782de 289 //Sensor correction-parameters A, B, C, D
wim 0:61bbd81782de 290 int _A, _B, _C, _D;
wim 0:61bbd81782de 291 };
wim 0:61bbd81782de 292
wim 0:61bbd81782de 293 #endif