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
MS5803_14BA.cpp@1:373f735e50e2, 2016-06-29 (annotated)
- 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?
User | Revision | Line number | New 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 | } |