High resolution barometer and altimeter using i2c mode
Fork of ms5611 by
Diff: ms5611.cpp
- Revision:
- 11:e0417b67a4b5
- Parent:
- 10:44e5b491a88c
- Child:
- 12:af100556f99e
diff -r 44e5b491a88c -r e0417b67a4b5 ms5611.cpp --- a/ms5611.cpp Tue Dec 01 17:23:12 2015 +0000 +++ b/ms5611.cpp Thu Dec 03 19:47:10 2015 +0000 @@ -52,8 +52,8 @@ //! @return 0 //******************************************************** -int ms5611::m_i2c_start(bool readMode) { - int twst; +int32_t ms5611::m_i2c_start(bool readMode) { + int32_t twst; _i2c.start(); if(readMode == true) { twst = m_i2c_write(_i2cRAddr); @@ -69,7 +69,7 @@ //! @return none //******************************************************** -void ms5611::m_i2c_stop(void) { +void ms5611::m_i2c_stop() { _i2c.stop(); } @@ -79,8 +79,8 @@ //! @return remote ack status //******************************************************** -unsigned char ms5611::m_i2c_write(unsigned char data) { - int twst = _i2c.write(data); +uint8_t ms5611::m_i2c_write(uint8_t data) { + uint8_t twst = _i2c.write(data); return(twst); } @@ -90,8 +90,8 @@ //! @return read byte //******************************************************** -unsigned char ms5611::m_i2c_readAck(void) { - int twst = _i2c.read(1); +uint8_t ms5611::m_i2c_readAck() { + uint8_t twst = _i2c.read(1); return(twst); } @@ -101,8 +101,8 @@ //! @return read byte //******************************************************** -unsigned char ms5611::m_i2c_readNak(void) { - int twst = _i2c.read(0); +uint8_t ms5611::m_i2c_readNak() { + uint8_t twst = _i2c.read(0); return(twst); } @@ -112,8 +112,8 @@ //! @return none //******************************************************** -void ms5611::m_i2c_send(char cmd) { - unsigned char ret; +void ms5611::m_i2c_send(uint8_t cmd) { + uint8_t ret; ret = m_i2c_start(false); if(!(ret)) { m_i2c_stop(); @@ -133,7 +133,6 @@ #if defined MS5611i2cLOWLEVEL m_i2c_send(MS5611_CMD_RESET); #else - char cobuf[1]; cobuf[0] = MS5611_CMD_RESET; _i2c.write(_i2cWAddr, cobuf, 1, false); #endif @@ -147,16 +146,14 @@ //! @return 24bit result //******************************************************** -unsigned long ms5611::cmd_adc(char cmd) { - char cobuf[3]; +uint64_t ms5611::cmd_adc(uint8_t cmd) { + uint64_t temp = 0; +#if defined MS5611i2cLOWLEVEL + m_i2c_send(MS5611_CMD_ADC_CONV + cmd); +#else cobuf[0] = 0; cobuf[1] = 0; cobuf[2] = 0; - unsigned int ret; - unsigned long temp = 0; -#if defined MS5611i2cLOWLEVEL - m_i2c_send(MS5611_CMD_ADC_CONV + cmd); -#else cobuf[0] = MS5611_CMD_ADC_CONV + cmd; _i2c.write(_i2cWAddr, cobuf, 1, false); #endif @@ -169,14 +166,18 @@ } #if defined MS5611i2cLOWLEVEL m_i2c_send(MS5611_CMD_ADC_READ); + m_i2c_start(true); + temp = m_i2c_readAck(); + temp = (temp << 8) | m_i2c_readAck(); + temp = (temp << 8) | m_i2c_readNak(); + m_i2c_stop(); #else cobuf[0] = MS5611_CMD_ADC_READ; _i2c.write(_i2cWAddr, cobuf, 1, true); cobuf[0] = 0; + _i2c.read(_i2cRAddr, cobuf, 3, false); + temp = (cobuf[0] << 16) | (cobuf[1] << 8) | cobuf[2]; #endif - ret = _i2c.read(_i2cRAddr, cobuf, 3, false); - //if(ret) printf("\n*** ms5611 ADC Read Error "); - temp = (cobuf[0] << 16) + (cobuf[1] << 8) + cobuf[2]; return temp; } @@ -186,22 +187,23 @@ //! @return coefficient //******************************************************** -unsigned int ms5611::cmd_prom(char coef_num) { - char cobuf[2]; - unsigned int ret; - unsigned int rC = 0; +uint32_t ms5611::cmd_prom(uint8_t coef_num) { + uint32_t rC = 0; +#if defined MS5611i2cLOWLEVEL + m_i2c_send(MS5611_CMD_PROM_RD + coef_num * 2); // send PROM READ command + m_i2c_start(true); + rC = m_i2c_readAck(); + rC = (rC << 8) | m_i2c_readNak(); + m_i2c_stop(); +#else cobuf[0] = 0; cobuf[1] = 0; -#if defined MS5611i2cLOWLEVEL - m_i2c_send(MS5611_CMD_PROM_RD + coef_num * 2); // send PROM READ command -#else cobuf[0] = MS5611_CMD_PROM_RD + coef_num * 2; _i2c.write(_i2cWAddr, cobuf, 1, true); cobuf[0] = 0; + _i2c.read(_i2cRAddr, cobuf, 2, false); + rC = (cobuf[0] << 8) | cobuf[1]; #endif - ret = _i2c.read(_i2cRAddr, cobuf, 2, false); - //if(ret) printf("\n*** ms5611 PROM Read Error "); - rC = cobuf[0] * 256 + cobuf[1]; return rC; } @@ -211,18 +213,18 @@ //! @return crc code //******************************************************** -unsigned char ms5611::crc4(unsigned int n_prom[]) { - unsigned int n_rem; - unsigned int crc_read; - unsigned char n_bit; +uint8_t ms5611::crc4(uint32_t n_prom[]) { + uint32_t n_rem; + uint32_t crc_read; + uint8_t n_bit; n_rem = 0x00; 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); + n_rem ^= (uint16_t) ((n_prom[cnt>>1]) & 0x00FF); } else { - n_rem ^= (unsigned short) (n_prom[cnt>>1]>>8); + n_rem ^= (uint16_t) (n_prom[cnt>>1]>>8); } for (n_bit = 8; n_bit > 0; n_bit--) { if (n_rem & (0x8000)) { @@ -243,7 +245,7 @@ with the CRC calculation itself: n_prom[7]=(0xFF00 & (n_prom[7])); //CRC byte is replaced by 0 As a simple test of the CRC code, the following coefficient table could be used: -unsigned int nprom[] = {0x3132,0x3334,0x3536,0x3738,0x3940,0x4142,0x4344,0x4500}; +uint32_t nprom[] = {0x3132,0x3334,0x3536,0x3738,0x3940,0x4142,0x4344,0x4500}; the resulting calculated CRC should be 0xB. DB 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 @@ -278,14 +280,11 @@ //******************************************************** void ms5611::loadCoefs() { - //printf(" - ms5611 coeffs\r\n"); for (int i = 0; i < 8; i++){ wait_ms(50); C[i] = cmd_prom(i); - //printf(" - C[%d] = 0x%04x\r\n", i, C[i]); } - unsigned char n_crc = crc4(C); - //printf(" - crc = 0x%02x\r\n", n_crc); + uint8_t n_crc = crc4(C); } //******************************************************** @@ -300,25 +299,23 @@ int64_t dT = D2 - ((uint64_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 = (float)(2000 + (((uint64_t)dT * C[6]) / (float)(1 << 23))) / 100.0; int32_t TEMP = 2000 + (int64_t)dT * (int64_t)C[6] / (int64_t)(1 << 23); + T = (double) TEMP / 100.0; - if(TEMP < 2000) { // if temperature lower than 20 Celsius - float T1 = ((float)TEMP - 2000.0) * ((float)TEMP - 2000.0); - int64_t OFF1 = (5 * (int64_t)T1) >> 1; - int64_t SENS1 = (5 * (int64_t)T1) >> 2; + if(TEMP < 2000) { // if temperature lower than +20 Celsius + int64_t T1 = ((int64_t)TEMP - 2000) * ((int64_t)TEMP - 2000); + int64_t OFF1 = (5 * T1) >> 1; + int64_t SENS1 = (5 * T1) >> 2; if(TEMP < -1500) { // if temperature lower than -15 Celsius - T1 = ((float)TEMP + 1500.0) * ((float)TEMP + 1500.0); - OFF1 += 7 * (int64_t)T1; - SENS1 += 11 * (int64_t)T1 >> 1; + T1 = ((int64_t)TEMP + 1500) * ((int64_t)TEMP + 1500); + OFF1 += 7 * T1; + SENS1 += 11 * T1 >> 1; } OFF -= OFF1; SENS -= SENS1; - T = (float)TEMP / 100.0; } -// int64_t P1 = ((((int64_t)D1 * SENS) >> 21) - OFF) >> 15; - P = (float)(((((int64_t)D1 * SENS ) >> 21) - OFF) / (double) (1 << 15)) / 100.0; + P = (double)(((((int64_t)D1 * SENS ) >> 21) - OFF) / (double) (1 << 15)) / 100.0; } //********************************************************