Skip to content

Commit b3fac7f

Browse files
committed
0.2.0 MS5837
1 parent c458fc3 commit b3fac7f

File tree

13 files changed

+568
-99
lines changed

13 files changed

+568
-99
lines changed

libraries/MS5837/CHANGELOG.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,22 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
66
and this project adheres to [Semantic Versioning](http://semver.org/).
77

88

9+
## [0.2.0] - 2025-06-13
10+
- fix #4, read() error after test with hardware
11+
- change API to **int read()** for better debugability
12+
- improve demo sketch - add getLastError()
13+
- redo getAltitude() formula
14+
- add sketch MS5837_performance.ino
15+
- redo 2nd order compensation
16+
- improve error handling
17+
- add getCRC(), getProduct(), getFactorySettings(), getPromZero()
18+
- add sketch MS5837_demo_meta_data.ino
19+
- update readme.md
20+
- update keywords
21+
- minor edits
22+
23+
----
24+
925
## [0.1.1] - 2025-04-07
1026
- update GitHub actions
1127
- update readme.md
@@ -14,7 +30,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1430
- add derived class **MS5803** to be able to set address.
1531
- minor edits
1632

17-
1833
## [0.1.0] - 2023-12-24
1934
- initial release
2035

libraries/MS5837/MS5837.cpp

Lines changed: 146 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
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
@@ -13,8 +13,8 @@
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)
3434
bool MS5837::isConnected()
3535
{
3636
_wire->beginTransmission(_address);
37-
return ( _wire->endTransmission() == 0);
37+
_error = _wire->endTransmission();
38+
return ( _error == MS5837_OK);
3839
}
3940

4041
bool 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

162229
uint32_t MS5837::lastRead()
@@ -183,7 +250,7 @@ float MS5837::getTemperature()
183250
float 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

291397
uint32_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

Comments
 (0)