11//
22// FILE: MS5837.cpp
33// AUTHOR: Rob Tillaart
4- // VERSION: 0.1.1
4+ // VERSION: 0.2.0
55// DATE: 2023-11-12
66// PURPOSE: Arduino library for MS5837 temperature and pressure sensor.
77// URL: https://github.com/RobTillaart/MS5837
1313#define MS5837_CMD_READ_ADC 0x00
1414#define MS5837_CMD_READ_PROM 0xA0
1515#define MS5837_CMD_RESET 0x1E
16- #define MS5837_CMD_CONVERT_D1 0x4A // differs from MS5611
17- #define MS5837_CMD_CONVERT_D2 0x5A // differs from MS5611
16+ #define MS5837_CMD_CONVERT_D1 0x40
17+ #define MS5837_CMD_CONVERT_D2 0x50
1818
1919
2020// CONSTRUCTOR
@@ -34,12 +34,17 @@ bool MS5837::begin(uint8_t mathMode)
3434bool MS5837::isConnected ()
3535{
3636 _wire->beginTransmission (_address);
37- return ( _wire->endTransmission () == 0 );
37+ _error = _wire->endTransmission ();
38+ return ( _error == MS5837_OK);
3839}
3940
4041bool MS5837::reset (uint8_t mathMode)
4142{
4243 command (MS5837_CMD_RESET);
44+ if (_error != MS5837_OK)
45+ {
46+ return false ;
47+ }
4348 uint32_t start = millis ();
4449 // while loop prevents blocking RTOS
4550 while (micros () - start < 10 )
@@ -49,7 +54,10 @@ bool MS5837::reset(uint8_t mathMode)
4954 }
5055
5156 initConstants (mathMode);
52-
57+ if (_error != MS5837_OK)
58+ {
59+ return false ;
60+ }
5361 // SKIP CRC check (for now)
5462
5563 // derive the type from mathMode instead of the other way around.
@@ -77,9 +85,12 @@ uint8_t MS5837::getAddress()
7785//
7886// datasheet page 7
7987// bits determines OSR => nr of samples => accuracy etc
80- bool MS5837::read (uint8_t bits)
88+ int MS5837::read (uint8_t bits)
8189{
82- if (isConnected () == false ) return false ;
90+ if (isConnected () == false )
91+ {
92+ return -1 ;
93+ }
8394
8495 int OSR = constrain (bits, 8 , 13 );
8596 OSR -= 8 ;
@@ -92,71 +103,127 @@ bool MS5837::read(uint8_t bits)
92103 // datasheet page 7 adjust command byte based on OSR
93104 _wire->write (MS5837_CMD_CONVERT_D1 + OSR * 2 );
94105 _error = _wire->endTransmission ();
95- if (_error != 0 )
106+ if (_error != MS5837_OK )
96107 {
97- // _error = MS5837_I2C_ERROR ?
98- return false ;
108+ // _error = twoWire specific.
109+ return - 2 ;
99110 }
100111
101112 uint32_t start = millis ();
102113
103114 // while loop prevents blocking RTOS
104- while (micros () - start < wait)
115+ while (millis () - start < wait)
105116 {
106117 yield ();
107118 delay (1 );
108119 }
109120 // NOTE: names D1 and D2 are reserved in MBED (NANO BLE)
110121 uint32_t _D1 = readADC ();
122+ if (_error != MS5837_OK)
123+ {
124+ // _error = twoWire specific.
125+ return -3 ;
126+ }
111127
112128 // D2 conversion
113129 _wire->beginTransmission (_address);
114130 // datasheet page 7 adjust command byte based on OSR
115131 _wire->write (MS5837_CMD_CONVERT_D2 + OSR * 2 );
116132 _error = _wire->endTransmission ();
117- if (_error != 0 )
133+ if (_error != MS5837_OK )
118134 {
119- // _error = MS5837_I2C_ERROR ?
120- return false ;
135+ // _error = twoWire specific.
136+ return - 4 ;
121137 }
122138
123139 start = millis ();
124140 // while loop prevents blocking RTOS
125- while (micros () - start < wait)
141+ while (millis () - start < wait)
126142 {
127143 yield ();
128144 delay (1 );
129145 }
130146
131147 // NOTE: names D1 and D2 are reserved in MBED (NANO BLE)
132148 uint32_t _D2 = readADC ();
149+ if (_error != MS5837_OK)
150+ {
151+ // _error = twoWire specific.
152+ return -5 ;
153+ }
133154
155+ // determine temperature
134156 float dT = _D2 - C[5 ];
135157 _temperature = 2000 + dT * C[6 ];
136158
159+ // determine pressure
137160 float offset = C[2 ] + dT * C[4 ];
138161 float sens = C[1 ] + dT * C[3 ];
139162 _pressure = _D1 * sens + offset;
140163
141164
142165 // Second order compensation
143- if (_temperature < 20 )
166+ // Comment to save footprint (trade accuracy)
167+ if ((_temperature * 0.01 ) < 20 )
144168 {
145- float ti = dT * dT * (11 * 2.91038304567E-11 ); // 1 / 2^35
146- float t = (_temperature - 2000 ) * (_temperature - 2000 );
147- float offset2 = t * (31 * 0.125 ); // 1 / 2^3
148- float sens2 = t * (63 * 0.03125 ); // 1 / 2^5
149-
169+ float ti = 0 , offset2 = 0 , sens2 = 0 ;
170+ float t2 = (_temperature - 2000 ) * (_temperature - 2000 );
171+ // Math mode 0 Page 12
172+ if (_type == MS5837_TYPE_30)
173+ {
174+ ti = dT * dT * (3 * 1.164153218269E-10 ); // 1 / 2^33
175+ offset2 = t2 * (3 * 0.5 ); // 1 / 2^1
176+ sens2 = t2 * (5 * 0.125 ); // 1 / 2^3
177+ if ((_temperature * 0.01 ) < -15 )
178+ {
179+ t2 = (_temperature + 1500 ) * (_temperature + 1500 );
180+ offset2 += 7 * t2;
181+ sens2 += 4 * t2;
182+ }
183+ }
184+ // math mode 1
185+ if (_type == MS5837_TYPE_02)
186+ {
187+ ti = dT * dT * (11 * 2.91038304567E-11 ); // 1 / 2^35
188+ offset2 = t2 * (31 * 0.125 ); // 1 / 2^3
189+ sens2 = t2 * (63 * 0.03125 ); // 1 / 2^5
190+ }
191+ // math mode 2
192+ if (_type == MS5803_TYPE_01)
193+ {
194+ ti = dT * dT * (3 * 4.656612873077E-10 ); // 1 / 2^31
195+ offset2 = t2 * (3 * 1.0 ); // 1 / 2^0
196+ sens2 = t2 * (7 * 0.125 ); // 1 / 2^3
197+ if ((_temperature * 0.01 ) < -15 )
198+ {
199+ t2 = (_temperature + 1500 ) * (_temperature + 1500 );
200+ sens2 += 2 * t2;
201+ }
202+ }
203+ else
204+ {
205+ // temperature > 20C MS5803 only
206+ if ((_type == MS5803_TYPE_01) && ( (_temperature * 0.01 ) > 45 ))
207+ {
208+ t2 = (_temperature - 4500 ) * (_temperature - 4500 );
209+ sens2 -= t2 * 0.125 ; // 1/2^3
210+ }
211+ }
150212 offset -= offset2;
151213 sens -= sens2;
152214 _temperature -= ti;
153215 }
216+
217+
154218 // 1 / 2^21 C[7] / 100
155219 _pressure = (_D1 * sens * 4.76837158203E-7 - offset) * C[7 ] * 0.01 ;
220+ if (_type == MS5837_TYPE_30) _pressure *= 10 ;
221+
156222 _temperature *= 0.01 ;
157223
158224 _lastRead = millis ();
159- return true ;
225+ _error = MS5837_OK;
226+ return 0 ;
160227}
161228
162229uint32_t MS5837::lastRead ()
@@ -183,7 +250,7 @@ float MS5837::getTemperature()
183250float MS5837::getAltitude (float airPressure)
184251{
185252 float ratio = _pressure / airPressure;
186- return 44330 * (1 - pow (ratio, 0.190294957 ));
253+ return 44307.694 * (1 - pow (ratio, 0.190284 ));
187254}
188255
189256
@@ -225,6 +292,36 @@ int MS5837::getLastError()
225292}
226293
227294
295+ // ////////////////////////////////////////////////////////////////////
296+ //
297+ // PROM zero - meta info
298+ //
299+ uint16_t MS5837::getCRC ()
300+ {
301+ uint16_t value = C[0 ];
302+ return value >> 12 ;
303+ }
304+
305+ uint16_t MS5837::getProduct ()
306+ {
307+ uint16_t value = C[0 ];
308+ return (value >> 5 ) & 0x007F ;
309+ }
310+
311+ uint16_t MS5837::getFactorySettings ()
312+ {
313+ uint16_t value = C[0 ];
314+ return value & 0x001F ;
315+ }
316+
317+
318+ uint16_t MS5837::getPromZero ()
319+ {
320+ uint16_t value = C[0 ];
321+ return value;
322+ }
323+
324+
228325// ////////////////////////////////////////////////////////////////////
229326//
230327// PROTECTED
@@ -234,8 +331,8 @@ int MS5837::command(uint8_t cmd)
234331 yield ();
235332 _wire->beginTransmission (_address);
236333 _wire->write (cmd);
237- _result = _wire->endTransmission ();
238- return _result ;
334+ _error = _wire->endTransmission ();
335+ return _error ;
239336}
240337
241338
@@ -254,7 +351,7 @@ void MS5837::initConstants(uint8_t mathMode)
254351 C[4 ] = 7.8125E-3 ; // TCO = C[4] / 2^7 | / 2^6 | / 2^7 |
255352 C[5 ] = 256 ; // Tref = C[5] * 2^8 | * 2^8 | * 2^8 |
256353 C[6 ] = 1.1920928955E-7 ; // TEMPSENS = C[6] / 2^23 | / 2^23 | / 2^23 |
257- C[7 ] = 1.220703125E-4 ; // compensate uses / 2^13 | / 2^15 | / 2^15 |
354+ C[7 ] = 1.220703125E-4 ; // compensate uses / 2^13 | / 2^15 | / 2^15 | Pressure math (P)
258355
259356 // App note version for pressure.
260357 // adjustments for MS5837_02
@@ -278,33 +375,42 @@ void MS5837::initConstants(uint8_t mathMode)
278375 {
279376 _wire->beginTransmission (_address);
280377 _wire->write (MS5837_CMD_READ_PROM + i + i);
281- _wire->endTransmission ();
378+ _error = _wire->endTransmission ();
379+ if (_error != MS5837_OK)
380+ {
381+ return ;
382+ }
282383 uint8_t length = 2 ;
283- _wire->requestFrom (_address, length);
384+ if (_wire->requestFrom (_address, length) != length)
385+ {
386+ _error = MS5837_ERROR_REQUEST;
387+ return ;
388+ }
284389 uint16_t tmp = _wire->read () << 8 ;
285390 tmp |= _wire->read ();
286391 C[i] *= tmp;
287392 }
393+ _error = MS5837_OK;
288394}
289395
290396
291397uint32_t MS5837::readADC ()
292398{
293399 command (MS5837_CMD_READ_ADC);
294- if (_result == 0 )
400+ if (_error != MS5837_OK )
295401 {
296- uint8_t length = 3 ;
297- int bytes = _wire->requestFrom (_address, length);
298- if (bytes >= length)
299- {
300- uint32_t value = _wire->read () * 65536UL ;
301- value += _wire->read () * 256UL ;
302- value += _wire->read ();
303- return value;
304- }
305402 return 0UL ;
306403 }
307- return 0UL ;
404+ uint8_t length = 3 ;
405+ if (_wire->requestFrom (_address, length) != length)
406+ {
407+ _error = MS5837_ERROR_REQUEST;
408+ return 0UL ;
409+ }
410+ uint32_t value = _wire->read () * 65536UL ;
411+ value += _wire->read () * 256UL ;
412+ value += _wire->read ();
413+ return value;
308414}
309415
310416
@@ -317,7 +423,7 @@ uint32_t MS5837::readADC()
317423//
318424// MS5803
319425//
320- MS5803::MS5803 (TwoWire *wire): MS5837(wire)
426+ MS5803::MS5803 (TwoWire *wire) : MS5837(wire)
321427{
322428}
323429
0 commit comments