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: upverter_fitbit_clone ReadingMag_HMC5883L_work
Diff: ms5611.cpp
- Revision:
- 2:05804ed70748
- Parent:
- 0:f97f410d4a21
- Child:
- 3:c2d1b0d432ad
diff -r 94a46b4fed9d -r 05804ed70748 ms5611.cpp
--- a/ms5611.cpp Tue May 07 18:55:31 2013 +0000
+++ b/ms5611.cpp Thu May 09 16:34:52 2013 +0000
@@ -16,11 +16,15 @@
#include "mbed.h"
#include "ms5611.h"
+double P; // compensated pressure value
+double T; // compensated temperature value
+
+uint32_t C[8]; //coefficient storage
+
//--------------------------------------------------------------------------------------------------------------------------------------//
// Constructor and destructor
ms5611::ms5611(PinName sda, PinName scl) : _i2c(sda, scl) {
-
}
//********************************************************
@@ -91,10 +95,10 @@
void ms5611::m_i2c_send(char cmd) {
unsigned char ret;
- ret = m_i2c_start(false); // set device address and write mode
- if(!(ret)) {//failed to issue start condition, possibly no device found */
+ ret = m_i2c_start(false);
+ if(!(ret)) {
m_i2c_stop();
- } else {// issuing start condition ok, device accessible
+ } else {
ret = m_i2c_write(cmd);
m_i2c_stop();
}
@@ -107,8 +111,8 @@
//********************************************************
void ms5611::cmd_reset() {
- m_i2c_send(MS5611_CMD_RESET); // send reset sequence
- wait_ms(4); // wait for the reset sequence timing
+ m_i2c_send(MS5611_CMD_RESET);
+ wait_ms(4);
loadCoefs();
}
@@ -125,8 +129,8 @@
cobuf[2] = 0;
unsigned int ret;
unsigned long temp = 0;
- m_i2c_send(MS5611_CMD_ADC_CONV + cmd); // send conversion command
- switch (cmd & 0x0f) { // wait necessary conversion time
+ m_i2c_send(MS5611_CMD_ADC_CONV + cmd);
+ switch (cmd & 0x0f) {
case MS5611_CMD_ADC_256 : wait_us(900); break;
case MS5611_CMD_ADC_512 : wait_ms(3); break;
case MS5611_CMD_ADC_1024: wait_ms(4); break;
@@ -167,14 +171,13 @@
//********************************************************
unsigned char ms5611::crc4(unsigned int n_prom[]) {
- //int cnt; // simple counter
- unsigned int n_rem; // crc reminder
- unsigned int crc_read; // original value of the crc
+ unsigned int n_rem;
+ unsigned int crc_read;
unsigned char n_bit;
n_rem = 0x00;
- crc_read = n_prom[7]; //save read CRC
- n_prom[7]=(0xFF00 & (n_prom[7])); //CRC byte is replaced by 0
- for (int cnt = 0; cnt < 16; cnt++) {// operation is performed on bytes // choose LSB or MSB
+ crc_read = n_prom[7];
+ n_prom[7]=(0xFF00 & (n_prom[7]));
+ for (int cnt = 0; cnt < 16; cnt++) {
if (cnt%2 == 1) {
n_rem ^= (unsigned short) ((n_prom[cnt>>1]) & 0x00FF);
} else {
@@ -188,11 +191,11 @@
}
}
}
- n_rem= (0x000F & (n_rem >> 12)); // final 4-bit reminder is CRC code
-// printf("n_rem: %x crc_read: %x n_prom[7]: %x\n", n_rem, crc_read, n_prom[7]);
-
- n_prom[7]=crc_read; // restore the crc_read to its original place
+ n_rem= (0x000F & (n_rem >> 12));
+ n_prom[7]=crc_read;
return (n_rem ^ 0x0);
+}
+
/*
The CRC code is calculated and written in factory with the LSB byte in the prom n_prom[7] set to 0x00 (see
Coefficient table below). It is thus important to clear those bytes from the calculation buffer before proceeding
@@ -215,42 +218,32 @@
*/
/*
//Returns 0x0b as per AP520_004
- PTbuffer[0] = 0x3132;
- PTbuffer[1] = 0x3334;
- PTbuffer[2] = 0x3536;
- PTbuffer[3] = 0x3738;
- PTbuffer[4] = 0x3940;
- PTbuffer[5] = 0x4142;
- PTbuffer[6] = 0x4344;
- PTbuffer[7] = 0x4546;
+ C[0] = 0x3132;
+ C[1] = 0x3334;
+ C[2] = 0x3536;
+ C[3] = 0x3738;
+ C[4] = 0x3940;
+ C[5] = 0x4142;
+ C[6] = 0x4344;
+ C[7] = 0x4546;
n_crc = ms.crc4(C); // calculate the CRC
pc.printf("testing CRC: 0x%x\n", n_crc);
*/
-
-}
+
//********************************************************
//! @brief load all calibration coefficients
//!
//! @return none
//********************************************************
-unsigned int PTbuffer[8]; // calibration coefficients
-
void ms5611::loadCoefs() {
- // printf("Getting coefficients... ");
for (int i = 0; i < 8; i++){
wait_ms(50);
- PTbuffer[i] = cmd_prom(i); // read coefficients
- // printf("0x%04x ", PTbuffer[i]);
+ C[i] = cmd_prom(i);
}
- // printf("\nCalculate CRC4: ");
- unsigned char n_crc = crc4(PTbuffer); // calculate the CRC
- // printf(" 0x%02x\n", n_crc);
+ unsigned char n_crc = crc4(C);
}
-double P; // compensated pressure value
-double T; // compensated temperature value
-
//********************************************************
//! @brief calculate temperature and pressure
//!
@@ -258,23 +251,30 @@
//********************************************************
void ms5611::calcPT() {
- unsigned long D2 = cmd_adc(MS5611_CMD_ADC_D2 + MS5611_CMD_ADC_4096); // read D2
- unsigned long D1 = cmd_adc(MS5611_CMD_ADC_D1 + MS5611_CMD_ADC_4096); // read D1
- // calculate 1st order pressure and temperature (MS5607 1st order algorithm)
+ int32_t D2 = cmd_adc(MS5611_CMD_ADC_D2 + MS5611_CMD_ADC_4096); // read D2
+ int32_t D1 = cmd_adc(MS5611_CMD_ADC_D1 + MS5611_CMD_ADC_4096); // read D1
+ int32_t dT = D2 - ((uint32_t)C[5] << 8);
+ int64_t OFF = ((uint32_t)C[2] << 16) + ((dT * (C[4]) >> 7)); //was OFF = (C[2] << 17) + dT * C[4] / (1 << 6);
+ int64_t SENS = ((uint32_t)C[1] << 15) + ((dT * (C[3]) >> 8)); //was SENS = (C[1] << 16) + dT * C[3] / (1 << 7);
+ T = (2000 + (((uint64_t)dT * C[6]) / (float)(1 << 23))) / 100;
+ int32_t TEMP = 2000 + (int64_t)dT * (int64_t)C[6] / (int64_t)(1 << 23);
- double dT = D2 - (PTbuffer[5] << 8);
- //change OFF and SENS scaling factor for ms5611
- double OFF = (PTbuffer[2] << 16) + dT * PTbuffer[4] / (1 << 6); //was OFF = (PTbuffer[2] << 17) + dT * PTbuffer[4] / (1 << 6);
- double SENS = (PTbuffer[1] << 15) + dT * PTbuffer[3] / (1 << 7); //was SENS = (PTbuffer[1] << 16) + dT * PTbuffer[3] / (1 << 7);
- T = (2000 + (dT * PTbuffer[6]) / (1 << 23)) / 100;
- P = (((D1*SENS) / (1 << 21) - OFF) / (1 << 15)) / 100;
-
-// dT = D2 - PTbuffer[5] * pow(2,8);
-// OFF = PTbuffer[2] * pow(2,17) + dT * PTbuffer[4] / pow(2,6);
-// SENS = PTbuffer[1] * pow(2,16) + dT * PTbuffer[3] / pow(2,7);
-// T = (2000 + (dT * PTbuffer[6]) / pow(2,23)) / 100;
-// P = (((D1*SENS) / pow(2,21) - OFF) / pow(2,15)) / 100;
- // place to use P, T, put them on LCD, send them trough RS232 interface...
+ if(TEMP < 2000) { // if temperature lower than 20 Celsius
+ float T1 = (TEMP - 2000) * (TEMP - 2000);
+ int64_t OFF1 = (5 * T1) / 2;
+ int64_t SENS1 = (5 * T1) / 4;
+
+ if(TEMP < -1500) { // if temperature lower than -15 Celsius
+ T1 = (TEMP + 1500) * (TEMP + 1500);
+ OFF1 += 7 * T1;
+ SENS1 += 11 * T1 / 2;
+ }
+ OFF -= OFF1;
+ SENS -= SENS1;
+ T = (float)TEMP / 100;
+ }
+// int64_t P1 = ((((int64_t)D1 * SENS) >> 21) - OFF) >> 15;
+ P = ((((int64_t)D1 * SENS ) >> 21) - OFF) / (double) (1 << 15) / 100.0;
}
//********************************************************
@@ -297,4 +297,4 @@
double ms5611::calcPressure() {
calcPT();
return(P);
-}
\ No newline at end of file
+}