This is a fork of MS5803-01 library by Raig Kaufer adapted for the MS5803-14BA.

Dependents:   MS5803_demo ARNSRS_SERVOS_USB_TFT pdiot-MS5803-test

Committer:
frada
Date:
Wed Jun 29 09:14:44 2016 +0000
Revision:
1:373f735e50e2
Parent:
0:a5f77652b3bb
Many improvements done; among all the most relevant is the use of second order temperature compensation for temperature and pressure readings (as specified in the MS5803-14BA datasheet from Measurement Specitalties).

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frada 0:a5f77652b3bb 1 /*
frada 0:a5f77652b3bb 2 Permission is hereby granted, free of charge, to any person obtaining a copy
frada 0:a5f77652b3bb 3 of this software and associated documentation files (the "Software"), to deal
frada 0:a5f77652b3bb 4 in the Software without restriction, including without limitation the rights
frada 0:a5f77652b3bb 5 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
frada 0:a5f77652b3bb 6 copies of the Software, and to permit persons to whom the Software is
frada 0:a5f77652b3bb 7 furnished to do so, subject to the following conditions:
frada 0:a5f77652b3bb 8
frada 0:a5f77652b3bb 9 The above copyright notice and this permission notice shall be included in
frada 0:a5f77652b3bb 10 all copies or substantial portions of the Software.
frada 0:a5f77652b3bb 11
frada 0:a5f77652b3bb 12 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
frada 0:a5f77652b3bb 13 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
frada 0:a5f77652b3bb 14 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
frada 0:a5f77652b3bb 15 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
frada 0:a5f77652b3bb 16 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
frada 0:a5f77652b3bb 17 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
frada 0:a5f77652b3bb 18 THE SOFTWARE.
frada 0:a5f77652b3bb 19
frada 0:a5f77652b3bb 20 * Demo Program
frada 0:a5f77652b3bb 21 * Barometer Sensor (Altimeter) MS5803-01BA of MEAS Switzerland (www.meas-spec.com).
frada 0:a5f77652b3bb 22 * The driver uses I2C mode (sensor PS pin low).
frada 0:a5f77652b3bb 23 * Other types of MEAS are compatible but not tested.
frada 0:a5f77652b3bb 24 * Written by Raig Kaufer distribute freely!
frada 0:a5f77652b3bb 25 *
frada 0:a5f77652b3bb 26 * Modified for MS5803-14BA by Francesco Adamo, Italy
frada 0:a5f77652b3bb 27 */
frada 0:a5f77652b3bb 28
frada 0:a5f77652b3bb 29 #include <stdlib.h>
frada 0:a5f77652b3bb 30 #include "MS5803_14BA.h"
frada 0:a5f77652b3bb 31
frada 1:373f735e50e2 32 MS5803_14BA::MS5803_14BA(PinName sda, PinName scl, uint8_t address) : _i2c(sda, scl) {
frada 1:373f735e50e2 33 _address = address << 1;
frada 0:a5f77652b3bb 34 _d1_osr = D1_OSR_4096;
frada 0:a5f77652b3bb 35 _d2_osr = D2_OSR_4096;
frada 0:a5f77652b3bb 36 reset(); // reset the sensor
frada 0:a5f77652b3bb 37 readPROM(); // read the calibration values
frada 0:a5f77652b3bb 38 }
frada 0:a5f77652b3bb 39
frada 1:373f735e50e2 40 MS5803_14BA::MS5803_14BA(PinName sda, PinName scl, uint8_t address, uint8_t d1_osr, uint8_t d2_osr) : _i2c( sda, scl ) {
frada 1:373f735e50e2 41 _address = address << 1;
frada 1:373f735e50e2 42 _d1_osr = d1_osr;
frada 1:373f735e50e2 43 _d2_osr = d2_osr;
frada 0:a5f77652b3bb 44 reset(); // reset the sensor
frada 1:373f735e50e2 45 readPROM(); // read the calibration values and store them in array C
frada 0:a5f77652b3bb 46 }
frada 0:a5f77652b3bb 47
frada 0:a5f77652b3bb 48 /* Send soft reset to the sensor */
frada 0:a5f77652b3bb 49 void MS5803_14BA::reset(void) {
frada 0:a5f77652b3bb 50 MS5803_tx_data[0] = COMMAND_RESET;
frada 1:373f735e50e2 51 _i2c.write(_address, MS5803_tx_data, 1);
frada 0:a5f77652b3bb 52 wait_ms(20);
frada 0:a5f77652b3bb 53 }
frada 0:a5f77652b3bb 54
frada 0:a5f77652b3bb 55 /* read the sensor calibration data from ROM */
frada 0:a5f77652b3bb 56 void MS5803_14BA::readPROM(void) {
frada 1:373f735e50e2 57
frada 0:a5f77652b3bb 58 for (uint8_t i = 0; i < 8; i++) {
frada 0:a5f77652b3bb 59 MS5803_tx_data[0] = COMMAND_READ_PROM + (i << 1);
frada 1:373f735e50e2 60 _i2c.write(_address, MS5803_tx_data, 1);
frada 1:373f735e50e2 61
frada 1:373f735e50e2 62 _i2c.read(_address, MS5803_rx_data, 2);
frada 0:a5f77652b3bb 63 C[i] = (MS5803_rx_data[0] << 8) + MS5803_rx_data[1];
frada 0:a5f77652b3bb 64 }
frada 0:a5f77652b3bb 65 }
frada 0:a5f77652b3bb 66
frada 0:a5f77652b3bb 67
frada 0:a5f77652b3bb 68 /* Sensor reading and calculation procedure */
frada 0:a5f77652b3bb 69 void MS5803_14BA::convert(void) {
frada 0:a5f77652b3bb 70 int32_t dT, TEMP;
frada 0:a5f77652b3bb 71 int64_t OFF, SENS, P;
frada 0:a5f77652b3bb 72
frada 1:373f735e50e2 73 MS5803_tx_data[0] = _d1_osr;
frada 1:373f735e50e2 74
frada 1:373f735e50e2 75 _i2c.write(_address, MS5803_tx_data, 1);
frada 1:373f735e50e2 76 wait_ms(10);
frada 1:373f735e50e2 77 D1 = readADC(); // read the temperature value
frada 1:373f735e50e2 78
frada 1:373f735e50e2 79 MS5803_tx_data[0] = _d2_osr;
frada 1:373f735e50e2 80 _i2c.write(_address, MS5803_tx_data, 1);
frada 1:373f735e50e2 81 wait_ms(10);
frada 0:a5f77652b3bb 82 D2 = readADC(); // read the temperature value
frada 1:373f735e50e2 83
frada 0:a5f77652b3bb 84 /* calculation according MS5803-14BA data sheet */
frada 1:373f735e50e2 85 dT = D2 - (C[5]* 256);
frada 1:373f735e50e2 86 TEMP = 2000 + (dT * C[6])/8388608;
frada 1:373f735e50e2 87
frada 1:373f735e50e2 88 //Now we have our first order Temperature, let's calculate the second order.
frada 1:373f735e50e2 89 int64_t T2, OFF2, SENS2; //working variables
frada 0:a5f77652b3bb 90
frada 1:373f735e50e2 91 if (TEMP < 2000) {
frada 1:373f735e50e2 92 // If temp_calc is below 20.0C
frada 1:373f735e50e2 93 T2 = 3 * (((int64_t)dT * dT) >> 33);
frada 1:373f735e50e2 94 OFF2 = 3 * (TEMP - 2000)^2 / 2;
frada 1:373f735e50e2 95 SENS2 = 5 * (TEMP - 2000)^2 / 8;
frada 1:373f735e50e2 96
frada 1:373f735e50e2 97 if(TEMP < -1500) {
frada 1:373f735e50e2 98 // If temp_calc is below -15.0C
frada 1:373f735e50e2 99 OFF2 = OFF2 + 7 * (TEMP + 1500)^2;
frada 1:373f735e50e2 100 SENS2 = SENS2 + 4 * (TEMP + 1500)^2;
frada 1:373f735e50e2 101 }
frada 1:373f735e50e2 102 }
frada 1:373f735e50e2 103 else {
frada 1:373f735e50e2 104 // If temp_calc is above 20.0C
frada 1:373f735e50e2 105 T2 = 7 * ((uint64_t)dT * dT) >> 37;
frada 1:373f735e50e2 106 OFF2 = (TEMP - 2000)^2 / 16;
frada 1:373f735e50e2 107 SENS2 = 0;
frada 1:373f735e50e2 108 }
frada 1:373f735e50e2 109
frada 1:373f735e50e2 110 // Now bring it all together to apply offsets
frada 1:373f735e50e2 111 OFF = ((int64_t)C[2] << 16) + (((C[4] * (int64_t)dT)) >> 7);
frada 1:373f735e50e2 112 SENS = ((int64_t)C[1] << 15) + (((C[3] * (int64_t)dT)) >> 8);
frada 1:373f735e50e2 113
frada 1:373f735e50e2 114 TEMP = TEMP - T2;
frada 1:373f735e50e2 115 OFF = OFF - OFF2;
frada 1:373f735e50e2 116 SENS = SENS - SENS2;
frada 1:373f735e50e2 117
frada 1:373f735e50e2 118 temperature = (float) TEMP/100.0f; // result of temperature in degC in this var
frada 1:373f735e50e2 119
frada 1:373f735e50e2 120 P = ((((int64_t)D1 * SENS) >> 21) - OFF) >> 15;
frada 1:373f735e50e2 121 pressure = (float) P/10.0f; // result of pressure in mBar in this var
frada 0:a5f77652b3bb 122 }
frada 1:373f735e50e2 123
frada 1:373f735e50e2 124 /* Read the previous started conversion results */
frada 1:373f735e50e2 125 int32_t MS5803_14BA::readADC(void) {
frada 1:373f735e50e2 126 //wait_ms(150);
frada 1:373f735e50e2 127 MS5803_tx_data[0] = COMMAND_READ_ADC;
frada 1:373f735e50e2 128 _i2c.write(_address, MS5803_tx_data, 1);
frada 1:373f735e50e2 129 _i2c.read(_address, MS5803_rx_data, 3);
frada 1:373f735e50e2 130
frada 1:373f735e50e2 131 return (MS5803_rx_data[0] << 16) + (MS5803_rx_data[1] << 8) + MS5803_rx_data[2];
frada 1:373f735e50e2 132 }