SkillAgentSearch skills...

MS5837

Arduino library for MS5837 temperature and pressure sensor.

Install / Use

/learn @RobTillaart/MS5837
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Arduino CI Arduino-lint JSON check GitHub issues

License: MIT GitHub release PlatformIO Registry

MS5837

Arduino library for the MS5837 temperature and pressure sensor and compatibles.

Description

Experimental

The MS5837 is a waterproof device to measure temperature and pressure to a high level of accuracy. Note only the sensor not the PCB is waterproof.

From the measured pressure one can calculate the depth or the altitude of the sensor to some extend.

  • The MS5837_30 can go to depth of about 300 meter (under water) as it can measure up to 30 Bar.
  • The MS5837_02 is meant for altitude measurements as it can as low as 300 mBar, -20°C
  • The MS5803_01 is meant for altitude measurements as it can as low as 10 mBar, -40°C

The library only supports the I2C based sensors, fixed address 0x76 for the MS5837 and address 0x76 or 0x77 for the MS5803.

This library does not use the partially 64 bit integer math as described in the datasheet. Instead it uses float math. This choice reduces footprint on e.g. AVR and increases the math performance. This will however have an effect on the accuracy of the results, although this effect is expected to be relative small as the 32 bit floats have 6-7 digits accuracy.

The library (.cpp) has a 2nd order compensation which is not tested. This needs reference devices and equipment to verify which I do not have. Feedback is welcome.

0.2.0

The library is tested with hardware, the MS5837-02 (mathMode 1) works. This resulted in fixing several bugs in read() and the 0.2.0 version. So pre 0.2.0 version are obsolete.

Feedback as always is welcome.

Compatibles

See mathType notes below.

| Sensor | mathMode | Celsius °C | pressure mBar | Notes | |:------------|:--------:|:------------:|:---------------:|:--------| | MS5837-30 | 0 | -20 to +85 | 0 to 30000 | for depth (under water). | MS5837-02 | 1 | -20 to +85 | 300 to 1200 | for altitude | MS5803-01 | 2 | -40 to +85 | 10 to 1300 | for altitude

Pressure mathType

There are MS5837 compatibles for which the math for the pressure is different. See AN520__004: C-code example for MS56xx, MS57xx (except analog sensor), and MS58xx series pressure sensors The difference is in the constants (mostly powers of 2) used to calculate the pressure.

The library implements reset(uint8_t mathMode = 0) to select the mathMode.

  • mathMode = 0 ==> datasheet MS5837_30 page 7

  • mathMode = 1 ==> datasheet MS5837_02 page 7

  • mathMode = 2 ==> datasheet MS5803_01 page 7

  • other values will act as 0 (until new math pops up).

Tests

The MS5837 library uses similar code as the tested MS5611 library.

The library is tested with the Arduino UNO R3 for version 0.2.0:

| BOARD | Sensor | mathMode | Notes | |:--------:|:------------|:--------:|:--------| | UNO R3 | MS5837-30 | 0 | works | UNO R3 | MS5837-02 | 1 | works | UNO R3 | MS5803-01 | 2 | not tested

The MS5803 will be tested when I the hardware.

Please let me know of other working platforms / processors (and failing ones!).

I2C

User has to call Wire.begin() (or equivalent) and optional set the I2C pins before calling MS5837.begin(mathMode).

Performance

The maximum I2C speed is 400 kHz according to the datasheet.

The read() call has two blocking delays to read two ADC values. THerefore the I2C speed is not a parameter to be tuned.

Address

| Device | Address | Notes | |:-----------:|:--------------:|:--------| | MS5837-02 | 0x76 | single fixed | MS5839-30 | 0x76 | single fixed | MS5803-01 | 0x76 or 0x77 | to be set with CSB pin.

The MS5837 class has a fixed address of 0x76, the MS5803 class allows to select address 0x77.

I2C multiplexing

Sometimes you need to control more devices than possible with the default address range the device provides. This is possible with an I2C multiplexer e.g. TCA9548 which creates up to eight channels (think of it as I2C subnets) which can use the complete address range of the device.

Drawback of using a multiplexer is that it takes more administration in your code e.g. which device is on which channel. This will slow down the access, which must be taken into account when deciding which devices are on which channel. Also note that switching between channels will slow down other devices too if they are behind the multiplexer.

  • https://github.com/RobTillaart/TCA9548

Related libraries

  • https://github.com/RobTillaart/pressure - pressure conversions
  • https://github.com/RobTillaart/Temperature - temperature conversions
  • https://github.com/RobTillaart/MS5837 - temperature pressure sensor
  • https://github.com/RobTillaart/MS5611
  • https://github.com/RobTillaart/MS5611_SPI
  • https://github.com/RobTillaart/MSP300 - industrial pressure transducer
  • https://swharden.com/blog/2017-04-29-precision-pressure-meter-project/
  • https://github.com/Zakrzewiaczek/ms5611-stm32 - derived library for STM32 boards.
  • https://www.usgs.gov/special-topics/water-science-school/science/water-density
  • https://www.mide.com/air-pressure-at-altitude-calculator

See also .h file

Interface MS5837

#include MS5837.h

Constructor

  • MS5837(TwoWire * wire = &Wire) constructor, optional I2C bus.
  • bool begin(uint8_t mathMode) initializes the library.
  • bool isConnected() returns true if device visible on I2C bus.
  • bool reset(uint8_t mathMode) resets the sensor and reads its configuration. The mathMode must match the type of sensor, see table above.
  • uint8_t getType() type indicates max pressure. Returns 30 or 2 or zero if unknown.
  • uint8_t getAddress() returns 0x76 as this is a fixed address.

Temperature and Pressure

  • int read(uint8_t bits = 8) the actual reading of the sensor. The bits determines the oversampling rate (OSR), see table below. Returns 0 upon success, a negative number on failure (debug info). The call will block for 3 to 40 milliseconds, depending upon number of bits.

| type | bits read() | millis | notes | |:-----------:|:-------------:|:--------:|:--------| | MS5837_30 | 8..13 | 5-40 | | MS5837_02 | 8..13 | 5-40 | | MS5803_01 | 8..12 | | not tested

  • uint32_t lastRead() returns the timestamp of the last call to read() in milliseconds since start. It does not take into account if the read call is successful or not.
  • float getTemperature() returns temperature in degrees Celsius. Multiple calls will return the same value until read() is called again.
  • float getPressure() returns pressure in mBar. Multiple calls will return the same value until read() is called again.
  • float getPressurePascal() returns pressure in Pascal (SI-unit). Multiple calls will return the same value until read() is called again.

Altitude

  • float getAltitude(float airPressure = 1013.25) calculates the altitude, based upon actual pressure measured and the current pressure at sea level (parameter airPressure). Returns the altitude in meters (SI-unit). Multiple calls will return the same altitude until a new pressure is read().
  • float getAltitudeFeet(float airPressure = 1013.25) calculates the altitude, based upon actual pressure measured and the current pressure at sea level (parameter airPressure). Returns the altitude in feet. Multiple calls will return the same altitude until a new pressure is read().
  • float getSeaLevelPressure(float pressure, float altitude) inverse function of getAltitude(). This function can be used to determine a reference air pressure for the getAltitude() function when you are at a defined altitude and you measured the local pressure with getPressure(). So think of it as calibration-tool for the reference pressure in getAltitude().

Experimental note.

getAltitude() might even work in caves below sea level, as the sensors can measure up to 1200/1300 hPa. See air pressure table below. This assumption is not confirmed yet.

Depth

For MS5837_30 only.

Depth calculation depends on the air pressure at sea level, and the density of the liquid you are submerged in. The density might not be a constant value and may vary over time. It depends e.g. on the salinity (sea water) and temperature.

The pressure is in fact the sum of the air pressure and the weight of the liquid above the sensor. If the density of the is larger than water the maximum depth at which the sensor will work will decrease. Denser liquids give more pressure.

  • void setDensity(float density = 0.99802) set liquid density. density water 20°C = 0.99802
  • float getDensity() returns set liquid density.
  • float getDepth(float airPressure = 1013.25) calculates the depth, based upon actual pressure and the pressure at sea level. Returns depth in meters (SI-unit). One can compensate for the actual air pressure at sea level. Multiple calls will return the same value until r

Related Skills

View on GitHub
GitHub Stars5
CategoryDevelopment
Updated4mo ago
Forks0

Languages

C++

Security Score

82/100

Audited on Nov 21, 2025

No findings