Custom ESPHome component for the MS5837-series pressure and temperature sensor. Allows easy integration of the sensor into Home Assistant. Perfect for measuring water tank or home sump levels.
Pull-up resistor and decoupling capacitor values will depend on your installation. I've succesfully used a 15' cable with 4.7kΩ and 1 uF.Save the source MS5837_Component.h to your Home Assistant config/esphome folder.
Add into the "esphome" section at the top of the project yaml file.
esphome:
libraries:
- "Arduino"
- "Wire"
- "SPI"
includes:
- MS5837_Component.h
Tell esphome which pins to use for I2C.
i2c:
sda: 21
scl: 22
scan: true
sensor:
- platform: custom
lambda: |-
auto MS5837 = new MS5837_Component(60000, MS5837_MODE_ALTITUDE, MS5837_OSR_1024);
MS5837->SetUnits(MS5837_UNITS_TEMP_F, MS5837_UNITS_PRESS_INHG, MS5837_UNITS_ALT_FT);
MS5837->SetOffsets(0, 1.7f);
MS5837->SetResultsAvgCount(3);
MS5837->SubscribeToPressureState("sensor.weather_station_pressure", MS5837_UNITS_PRESS_INHG);
App.register_component(MS5837);
return {MS5837->temperature_sensor, MS5837->pressure_sensor, MS5837->altitude_sensor};
sensors:
- name: "MS5837 Temperature"
unit_of_measurement: °F
accuracy_decimals: 1
- name: "MS5837 Pressure"
unit_of_measurement: inHg
accuracy_decimals: 3
- name: "MS5837 Altitude"
unit_of_measurement: ft
accuracy_decimals: 1
First instantiate the component and supply basic parameters. All of these parameters are optional if you wish to use the defaults.
auto MS5837 = new MS5837_Component(60000, MS5837_MODE_ALTITUDE, MS5837_OSR_1024);
The first parameter is the update frequency, in ms. In this case it will update every 60 seconds.
Next is the operating mode. There are 3 choices:
- MS5837_MODE_RAW - Report only temperature and pressure (default)
- MS5837_MODE_ALTITUDE - Report either true altitude or pressure altitude depending on if sea level pressure is supplied later
- MS5837_MODE_DEPTH - Report depth. Needs ambient pressure for accurate results (see service "update_pressure")
Finally is the resolution. Higher resolutions give more precise results but take longer to compute. There are 6 choices:
- MS5837_OSR_8192 - 36ms (default)
- MS5837_OSR_4096 - 18ms
- MS5837_OSR_2048 - 10ms
- MS5837_OSR_1024 - 6ms
- MS5837_OSR_512 - 4ms
- MS5837_OSR_256 - 2ms
Decide which units to report in (optional). Altitude/Depth units may be left out if using MS5837_MODE_RAW.
MS5837->SetUnits(MS5837_UNITS_TEMP_F, MS5837_UNITS_PRESS_INHG, MS5837_UNITS_ALT_FT);
Temperature units
- MS5837_UNITS_TEMP_C - Celsius (default)
- MS5837_UNITS_TEMP_F - Fahrenheit
- MS5837_UNITS_TEMP_K - Kelvin
- MS5837_UNITS_TEMP_R - Rankine
Pressure units
- MS5837_UNITS_PRESS_HPA - HectoPascals (default)
- MS5837_UNITS_PRESS_PA - Pascals
- MS5837_UNITS_PRESS_KPA - KiloPascals
- MS5837_UNITS_PRESS_INHG - Inches of Mercury
Altitude/Depth units
- MS5837_UNITS_ALT_M - Meters (default)
- MS5837_UNITS_ALT_FT - Feet
- MS5837_UNITS_ALT_CM - Centimeters
- MS5837_UNITS_ALT_IN - Inches
An offset may be applied to temperature and pressure based on a known value. For example, pressure reads low compared to an accurate weather station.
MS5837->SetOffsets(0, 1.7f);
- Temperature: °C
- Pressure: hPa
If desired, the component will request multiple readings of the sensor values and average the results. This should help to smooth out any noise in the sensor. Simply tell it how many readings you would like to average. If this line is not included, it defaults to a single reading (no smoothing). Note that at higher OSR values this can add significant time.
MS5837->SetResultsAvgCount(3);
If using MS5837_MODE_RAW, only 2 values will be returned
return {MS5837->temperature_sensor, MS5837->pressure_sensor};
If using MS5837_MODE_ALTITUDE or MS5837_MODE_DEPTH, 3 values will be returned
return {MS5837->temperature_sensor, MS5837->pressure_sensor, MS5837->altitude_sensor};
Declare the entities shown in Home Assistant and name them as you prefer. Units here are only what are displayed in Home Assistant, the actual conversion is done above. If using MS5837_MODE_RAW, leave out the third entity (Altitude/Depth).
sensors:
- name: "MS5837 Temperature"
unit_of_measurement: °F
accuracy_decimals: 1
- name: "MS5837 Pressure"
unit_of_measurement: inHg
accuracy_decimals: 3
- name: "MS5837 Altitude"
unit_of_measurement: ft
accuracy_decimals: 1
There are two ways to update the ambient/sea level pressure: via a Home Assistant service or by subscribing to a Home Assistant entity.
The component exposes a service to Home Assistant: "_update_pressure". It is used in either MS5837_MODE_ALTITUDE or MS5837_MODE_DEPTH. The new pressure must be reported in hPa.
This could be done from a Home Assistant automation, such as:
trigger:
- platform: state
entity_id:
- sensor.weather_station_pressure
condition: []
action:
- service: esphome.tank_level_update_pressure
data:
New Pressure (hPa): >-
{{ (states('sensor.weather_station_pressure') | float) * 33.86388640341 }}
Note the conversion from the weather station's inHg to hPa.
Sea Level Pressure may be optionally supplied.
- If not supplied, the altitude calculation is based on an ISA sea level pressure of 1013.25. This results in the component reporting pressure altitude.
- If sea level pressure is supplied, the altitude calculation is based on this pressure. This mean the component reports true altitude.
Ambient pressure needs to be supplied to accurately calculate depth. This could be supplied from another sensor above water or a weather station. If neither are available, calculating the standard pressure should get you close though you will see variations as the ambient pressure changes. If not supplied, it assumes your location is at sea level and the depth reading will be inaccurate.
Subscribing to a Home Assistant entity requires no external setup. Simply supply the entity identifier and whenever the entity updates the component will automatically read the new value. On startup the processing of altitude/depth calculations will be delayed until a valid pressure is received, so as to avoid incorrect values. Pressure may be supplied in any of the valid units.
MS5837->SubscribeToPressureState("sensor.weather_station_pressure", MS5837_UNITS_PRESS_INHG);
Initially based on BlueRobotics' MS5837 Arduino library.