Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: MS5803_demo ARNSRS_SERVOS_USB_TFT pdiot-MS5803-test
Revision 1:373f735e50e2, committed 2016-06-29
- Comitter:
- frada
- Date:
- Wed Jun 29 09:14:44 2016 +0000
- Parent:
- 0:a5f77652b3bb
- Commit message:
- 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).
Changed in this revision
| MS5803_14BA.cpp | Show annotated file Show diff for this revision Revisions of this file |
| MS5803_14BA.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r a5f77652b3bb -r 373f735e50e2 MS5803_14BA.cpp
--- a/MS5803_14BA.cpp Fri Apr 24 18:56:03 2015 +0000
+++ b/MS5803_14BA.cpp Wed Jun 29 09:14:44 2016 +0000
@@ -29,86 +29,104 @@
#include <stdlib.h>
#include "MS5803_14BA.h"
-MS5803_14BA::MS5803_14BA(PinName sda, PinName scl, char MS5803_ADDR) : _i2c(sda, scl) {
- device_address = MS5803_ADDR << 1;
+MS5803_14BA::MS5803_14BA(PinName sda, PinName scl, uint8_t address) : _i2c(sda, scl) {
+ _address = address << 1;
_d1_osr = D1_OSR_4096;
_d2_osr = D2_OSR_4096;
reset(); // reset the sensor
readPROM(); // read the calibration values
}
-MS5803_14BA::MS5803_14BA(PinName sda, PinName scl, char MS5803_ADDR, char d1_osr, char d2_osr) : _i2c( sda, scl ) {
- device_address = MS5803_ADDR << 1;
- _d1_osr = D1_OSR_4096;
- _d2_osr = D2_OSR_4096;
+MS5803_14BA::MS5803_14BA(PinName sda, PinName scl, uint8_t address, uint8_t d1_osr, uint8_t d2_osr) : _i2c( sda, scl ) {
+ _address = address << 1;
+ _d1_osr = d1_osr;
+ _d2_osr = d2_osr;
reset(); // reset the sensor
- readPROM(); // read the calibration values and store them in array C[ ]
+ readPROM(); // read the calibration values and store them in array C
}
/* Send soft reset to the sensor */
void MS5803_14BA::reset(void) {
MS5803_tx_data[0] = COMMAND_RESET;
- _i2c.write(device_address, MS5803_tx_data, 1);
+ _i2c.write(_address, MS5803_tx_data, 1);
wait_ms(20);
}
/* read the sensor calibration data from ROM */
void MS5803_14BA::readPROM(void) {
+
for (uint8_t i = 0; i < 8; i++) {
MS5803_tx_data[0] = COMMAND_READ_PROM + (i << 1);
- _i2c.write( device_address, MS5803_tx_data, 1);
- _i2c.read( device_address, MS5803_rx_data, 2);
+ _i2c.write(_address, MS5803_tx_data, 1);
+
+ _i2c.read(_address, MS5803_rx_data, 2);
C[i] = (MS5803_rx_data[0] << 8) + MS5803_rx_data[1];
}
}
-/* Start the sensor pressure conversion */
-void MS5803_14BA::convertD1(void) {
- MS5803_tx_data[0] = _d1_osr;
- _i2c.write( device_address, MS5803_tx_data, 1);
-}
-
-/* Start the sensor temperature conversion */
-void MS5803_14BA::convertD2(void) {
- MS5803_tx_data[0] = _d2_osr;
- _i2c.write(device_address, MS5803_tx_data, 1);
-}
-
-/* Read the previous started conversion results */
-int32_t MS5803_14BA::readADC(void) {
- wait_ms(150);
- MS5803_tx_data[0] = COMMAND_READ_ADC;
- _i2c.write(device_address, MS5803_tx_data, 1);
- _i2c.read(device_address, MS5803_rx_data, 3);
- return (MS5803_rx_data[0] << 16) + (MS5803_rx_data[1] << 8) + MS5803_rx_data[2];
-}
-
-/* return the results */
-float MS5803_14BA::getPressure(void) {
- return P_MS5803;
-}
-
-float MS5803_14BA::getTemperature (void) {
- return T_MS5803;
-}
/* Sensor reading and calculation procedure */
void MS5803_14BA::convert(void) {
int32_t dT, TEMP;
int64_t OFF, SENS, P;
- convertD1(); // start pressure convertion
- D1 = readADC(); // read the pressure value
- convertD2(); // start temperature convertion
+ MS5803_tx_data[0] = _d1_osr;
+
+ _i2c.write(_address, MS5803_tx_data, 1);
+ wait_ms(10);
+ D1 = readADC(); // read the temperature value
+
+ MS5803_tx_data[0] = _d2_osr;
+ _i2c.write(_address, MS5803_tx_data, 1);
+ wait_ms(10);
D2 = readADC(); // read the temperature value
-
+
/* calculation according MS5803-14BA data sheet */
- dT = D2 - (C[5]* 256);
- TEMP = 2000 + (dT * C[6])/8388608;
- T_MS5803 = (float) TEMP/100.0f; // result of temperature in deg C in this var
+ dT = D2 - (C[5]* 256);
+ TEMP = 2000 + (dT * C[6])/8388608;
+
+ //Now we have our first order Temperature, let's calculate the second order.
+ int64_t T2, OFF2, SENS2; //working variables
- OFF = (int64_t)65536*C[2] + ((int64_t)dT * (int64_t)C[4])/128;
- SENS = (int64_t)32768*C[1] + ((int64_t)dT * (int64_t)C[3])/256;
- P = (((int64_t)D1 * SENS)/2097152 - OFF)/32768;
- P_MS5803 = (float) P/10.0f; // result of pressure in mBar in this var
+ if (TEMP < 2000) {
+ // If temp_calc is below 20.0C
+ T2 = 3 * (((int64_t)dT * dT) >> 33);
+ OFF2 = 3 * (TEMP - 2000)^2 / 2;
+ SENS2 = 5 * (TEMP - 2000)^2 / 8;
+
+ if(TEMP < -1500) {
+ // If temp_calc is below -15.0C
+ OFF2 = OFF2 + 7 * (TEMP + 1500)^2;
+ SENS2 = SENS2 + 4 * (TEMP + 1500)^2;
+ }
+ }
+ else {
+ // If temp_calc is above 20.0C
+ T2 = 7 * ((uint64_t)dT * dT) >> 37;
+ OFF2 = (TEMP - 2000)^2 / 16;
+ SENS2 = 0;
+ }
+
+ // Now bring it all together to apply offsets
+ OFF = ((int64_t)C[2] << 16) + (((C[4] * (int64_t)dT)) >> 7);
+ SENS = ((int64_t)C[1] << 15) + (((C[3] * (int64_t)dT)) >> 8);
+
+ TEMP = TEMP - T2;
+ OFF = OFF - OFF2;
+ SENS = SENS - SENS2;
+
+ temperature = (float) TEMP/100.0f; // result of temperature in degC in this var
+
+ P = ((((int64_t)D1 * SENS) >> 21) - OFF) >> 15;
+ pressure = (float) P/10.0f; // result of pressure in mBar in this var
}
+
+/* Read the previous started conversion results */
+int32_t MS5803_14BA::readADC(void) {
+ //wait_ms(150);
+ MS5803_tx_data[0] = COMMAND_READ_ADC;
+ _i2c.write(_address, MS5803_tx_data, 1);
+ _i2c.read(_address, MS5803_rx_data, 3);
+
+ return (MS5803_rx_data[0] << 16) + (MS5803_rx_data[1] << 8) + MS5803_rx_data[2];
+}
diff -r a5f77652b3bb -r 373f735e50e2 MS5803_14BA.h
--- a/MS5803_14BA.h Fri Apr 24 18:56:03 2015 +0000
+++ b/MS5803_14BA.h Wed Jun 29 09:14:44 2016 +0000
@@ -35,14 +35,14 @@
#define MS5803_TX_DEPTH 2
-#define MS5803_ADDRC_L 0x77 //0b1110111 CSB Pin is low
-#define MS5803_ADDRC_H 0x76 //0b1110110 CSB Pin is high
+#define MS5803_ADDRC_L (uint8_t) 0x77 //0b01110111 CSB Pin is low
+#define MS5803_ADDRC_H (uint8_t) 0x76 //0b01110110 CSB Pin is high
-#define MS5803_BASE_ADDR MS5803_ADDRC_L // choose your connection here
+#define MS5803_BASE_ADDR MS5803_ADDRC_H // choose your connection here
#define COMMAND_RESET 0x1E // Sensor Reset
-#define D1_OSR_256 0x40 // Convert D1 OSR 256
+#define D1_OSR_256 0x40 // Convert D1 OSR 256
#define D1_OSR_512 0x42 // Convert D1 OSR 512
#define D1_OSR_1024 0x44 // Convert D1 OSR 1024
#define D1_OSR_2048 0x46 // Convert D1 OSR 2048
@@ -60,26 +60,23 @@
class MS5803_14BA {
private:
I2C _i2c;
- char device_address, _d1_osr, _d2_osr;
+ uint8_t _address, _d1_osr, _d2_osr;
uint32_t D1, D2;
uint16_t C[8];
- float T_MS5803, P_MS5803;
/* Data buffers */
char MS5803_rx_data[MS5803_RX_DEPTH];
char MS5803_tx_data[MS5803_TX_DEPTH];
public:
- MS5803_14BA(PinName sda, PinName scl, char MS5803_ADDR);
- MS5803_14BA(PinName sda, PinName scl, char MS5803_ADDR, char d1_osr, char d2_osr);
+ float temperature, pressure;
+
+ MS5803_14BA(PinName sda, PinName scl, uint8_t MS5803_ADDR);
+ MS5803_14BA(PinName sda, PinName scl, uint8_t MS5803_ADDR, uint8_t d1_osr, uint8_t d2_osr);
void reset(void);
void readPROM(void);
- void convertD1(void);
- void convertD2(void);
- int32_t readADC(void);
- float getPressure(void);
- float getTemperature(void);
void convert(void);
+ int32_t readADC();
};
#endif