Home AutomationProjects

Water Softener Salt Level Monitor (and more)

Living in a hard water area is a pain, so several years ago we had a water softener installed which has really helped. Unfortunately with it being tucked away in the garage, checking the salt level is very much hit and miss. It tends to be that I notice the signs of the water hardness increasing before I remember to go and check the level and top it up.

I’ve already got a large number of appliances, devices and sensors hooked up to my Home Automation system (https://www.home-assistant.io/) so adding something to alert me when the salt needs topping up seems like something I should have tackled long ago.

Having recently been experimenting with the Wemos D1 Mini (ESP8226 Dev board) with my Broadband Utilisation Display project I turned again to thinking how I could use a Wemos D1 Mini to solve this problem. However, this time rather than needing to write my own code for this, I don’t need to as other people have already solved this problem for me.

I’ve already flashed a number of Sonoff devices with the Tasmota firmware. Tasmota is an alternative firmware for ESP8266 which is what is used in the Sonoff (and many other) devices. It enables devices to be controlled and sensor information shared via MQTT (a lightweight messaging protocol often used in IOT projects) to my Home Assistant instance. This time instead of repurposing a Sonoff I took a Wemos D1 Mini and flashed it with Tasmota, bingo, the device creates a WiFi hotspot which you connect to provide it with your wireless network details and it’s ready to be configured.


Whilst on my workbench I decided that solving the salt level issue is one useful capability it would be easy to add some other sensors too, creating a multi-sensor for my garage and replacing some separate sensors. But we’ll come on to this later, first, the primary problem to solve is detecting when the salt level in the water softener is low.

Salt Level Measurement

Our Water Softener (Tapworks AD11) uses salt tablets that are poured into the body of the water softener, nightly it runs a cycle dissolving some of the salt, slowly lowering the level of salt.

Monitoring could be done by measuring the weight of the unit, but a simpler approach would be to measure the distance from the lid to the salt tablets in the body. For this measurement, there are a number of potential sensors which can be used.

SensorDistanceVoltageAmazon UK
Sharp GP2Y0A21YK0F
10-80cm5V£7.99Sharp GP2Y0A21YK0F IR Proximity Sensor
Pololu Carrier with Sharp GP2Y0A60SZLF
(more info from Pololu)
10-150cm3V or 5V£26.99Pololu Carrier with sharp GP2Y0A60SZLF IR proximity sensor
2-500cm5V£1.60 (£7.99 for 5)HC-SR05 Ultrasonic Distance Sensor

Sharp Proximity Sensors

All three sensors are designed for proximity/distance measurement. With the sharp sensors using infra-red light reflection and HC-SR04 ultrasonic sound pulses.

A key difference when considering integrating these sensors is that the Sharp IR sensors are analog, with the voltage output changing based on the distance to the object. The voltage change is most rapid at closer ranges, with Sharp making variations of the sensor tailored for different distances.

Sharp GP2Y0A21YK0F Output voltage vs distance graph

HC-SR04 Ultrasonic Distance Sensor

The HC-SR04 is a digital sensor which uses Time to represent the distance from the object, rather than voltage. The microcontroller sends a 10µS pulse to trigger the HC-SR04, which then emits a burst of 8 pulses at 40KHz. At the same time sending the Echo pin high for up to 38ms if nothing is detected in range. However, if the pulses are reflected back the pin is taken low sooner, the distance can be calculated based on the duration the pin was high.

Distance = Speed x Time
– Where speed is 340 m/s (the speed of sound), or 0.034cm/µS
– Time is the duration of the echo pulse received
– As the measure is the time to send and receive, the result of the above calculation needs to be divided by 2
For example, a pulse lasting 2000µS would give: (0.034 x 2000) / 2 = 34cm

The LastMinuteEngineers.com has a great post explaining more about this sensor.

Sensor Decision

There are typically only a couple of analog inputs on microcontrollers, so a digital signal is preferred, and analog signals can be more susceptible to noise, as I found with my PetDoor project. The HC-SR04 does require 2 GPIO pins compared to one, but I have plenty of spare GPIO available. Finally, at a price of < £2ea (assuming you don’t have one already from some other project), the ultrasonic sensor seems great value for money.

Adding More Sensors

As previously mentioned, once I had the distance measuring sensor working, I determined I could also replace a couple of other sensors I had currently running in the garage.

Hot Water Temperature

My garage houses the boiler and hot water storage tank in addition to the water softener. I’d recently hooked up a repurposed Sonoff TH16 running Tasmota to measure the hot water tank temperature via a DS18B20 waterproof temperature sensor pushed into the tank insulation, it was part of a project I’ve started to try and make my Nest Controller hot water system better (or even replace it) by understanding water usage and time required to heat water.

With the Wemos D1 mini running Tasmota for this project, I could reclaim the Sonoff and instead hook the temperature sensor up to the the Wemos D1 Mini and retain the same functionality.

Presence Detection for Light Control

Having given up nagging various members of the household to turn off the garage light, I installed a Zigbee PIR sensor so that after a period of no movement being detected, the light would be turned off automatically. This is a battery powered sensor and now with a mains powered Wemos D1 mini available it seems light a good time to try out combining PIR sensor into this project too.

Again during the PetDoor project, I experimented with some PIR sensors and didn’t find them all that reliable. The HC-SR501 would be candidate for this current project, but the way the sensor operates with gaps in motion detection time and some false positives, had me looking for something better. Around this time Andreas Spiess released a video which included a new Panasonic sensor the EKMC1603111 (datasheet) which is available from CPC Farnell for around £10. This is an expensive alternative to the HC-SR501, where you can pick up 10 of these for around £13, however so far my experience with this sensor has been great, it just works!

Completed Multisensor

I don’t have a 3D printer to create a custom enclosure and having looked at a variety of project boxes, I determined I could make use of something from my local Screwfix.com store. For just £1.53 I could adapt this Schneider junction box, at just 65x65x45mm it was ideally suited to house the project.

Using a cone drill I made a large opening in the lid of the box for the PIR and used hot glue to secure it. I fitted some standoffs to mount the Wemos D1 Mini securely within the enclosure and fed the connections sensors and USB power cables out through one of the cable grommets.

A cable leads to the water softener where after drilling a small hole the HC-SR04 ultrasonic sensor is secured to the underside again using hot melt glue. The glue is mainly around the connector, so should the sensor fail, it’s simple to unplug and plug in another one.

Data pins are connected to the Wemos D1 Mini via header pins. In order to power the various sensors the 5V power feed is taken to a couple of Wago 221 connectors for ease of installation (and expansion).

Tasmota Configuration

Once Tasmota is flashed to the Wemos D1 Mini and connected up to the WiFi, it needs to be configured to define the different sensors connected to the GPIO.

First set the Module Type to Generic (18) then Save and restart.

HC-SR04 ultrasonic sensor:

  • D7 – Trigger – SR04 Tri/TX (73)
  • D8 – Echo – SR04 Ech/Rx (74)

DS18B20 waterproof temperature sensor:

  • D4 – DS18x20 (4)

EKMC1603111 – PIR detector:

  • D5 – Switch 1n (82)
    • I’d connected a pulldown resistor to the sensor. The ‘n’ setting disables the internal pull-up resistor that is normally set.
  • In the tasmota web console some additional commands are performed to correctly configured, per: https://tasmota.github.io/docs/PIR-Motion-Sensors/
SwitchMode1 1
SwitchTopic 0
Rule1 on Switch1#state=1 do publish stat/%topic%/PIR1 ON endon on Switch1#state=0 do Publish stat/%topic%/PIR1 OFF endon
Rule1 1

Once configured Tasmota will show the distance and temperature sensor measurements, but not the PIR state.

Assuming you’ve configured MQTT these sensor values will be published periodically (per your telemetry period). When the PIR senses movement it sends a message immediately.

Different PIR models behave differently, the Panasonic sensor sends an ON event only when it senses the movement and quickly sends a PIR OFF message when movement isn’t detected. Other sensors may keep the value ON for longer periods. I prefer a fast-acting sensor so I can determine the behaviour I want via software.

Home Assistant

The configuration for this sensor in Home Assistant can be seen via the source in my GitHub repository.

The PIR is defined as an MQTT binary_sensor with the temperature and distance sensors as MQTT sensor the values of which are extracted via a JSON template.

As I only want to know when there hasn’t been any movement for 15 minutes, I use an input_select which is set to motion each time the PIR sends an ON event. With an automation script which changes it back to idle if there hasn’t been activity for 15 mins.

If there hasn’t been activity for 15 mins and the garage light is on, it will turn it off and send me a notification.

The salt level is monitored by Home Assistant and will send a notification when the distance increases to the point it needs refilling. This may need some fine tuning, but currently set to 42cm. I’m also logging this data into an influxDB and plotting via Grafana so that I can get a better feel for the rate of usage so I can predict the usage rate.

Parts List

PartPrice (UK)Source
Wemos D1 mini microcontroller (v3.1)£5.99eBay
HC-SR04 ultrasonic distance sensor£1.60 (£7.99 – 5 pack)Amazon
Panasonic EKMC1603111 PIR senor£9.48CPC Farnell
DS18B20 waterproof temperature sensor£2.12 (£10.59 – 5 pack)Amazon
Schneider Electric junction box£1.53Screwfix.com
USB power supply£5 (£9.99 – 2 pack)Amazon
Misc cables and connectors

Note: Amazon links included are affiliate links.

19 thoughts on “Water Softener Salt Level Monitor (and more)

  • Hi Martin.

    This is a great post. Thank you.

    I am looking to do something similar to measure water levels in a tank.

    Has there been any problems with corrosion of the sensor from the moisture / salt?

    • Not yet, but its early days will need to monitor it over the long term. However, the sensor is fairly cheap and easily replaceable, so if it turns out there is an issue with corrosion I can swap it out, or if a necessary swap to a Sharp IR distance sensor

  • By default for how long does EKMC1603111 stays on ?

    and is there any way to add delay to sensor ?
    like we do with HC-SR501

    • The EKMC1603111 doesn’t stay on, it sends a short pulse each time it detects motion, if there is continuous motion then you will receive a series of pulses. Assuming you are connecting the sensor to a microcontroller of some form you can then decide how to handle the pulses. For example you could configure an output on your controller into a specific state for a software-controlled duration, a time period that could be constantly reset as new pulses come in. If you aren’t planning on using a microcontroller, then there are various ways you could create a hardware controlled delay, like using a 555 monostable per: https://electronicsclub.info/555monostable.htm

  • Great stuff. I’ve been wanting to find a way to detect when I need to fill my water softener and this looks ideal as I already have Home Assistant running.

    I’ve ordered a Wemos D1 and HC-SR04 from eBay and will pick up a junction box next time I am passing Screwfix.

    Hopefully I can figure out what I need to do without all the other sensors you have added, as this will be my first time doing something like that

    • Glad you found it useful. If you need any help, feel free to get in touch.

  • Hi Martin

    I have acquired all the bits to make your water softener salt level monitor. I’ve flashed the Wemos D1 Mini with Tasmota, have configured the the wireless network, and can access the Tasmota web front end. So all good so far 🙂

    I’ve connected the HC-SR04 ultrasonic sensor to the pins on the right-hand side of the Wemos D1 Mini as follows:

    5V -> VCC
    GND -> GND
    D4 -> Trig (Rx)
    D5 -> Echo (Tx)

    Is that correct? When I try to configure the sensor in Tasmota, I don’t see the SR04 options in the dropdowns, and don’t seem to be able to get the sensor to work.

    I found this link that seems to suggest I need to do something a bit more complicated with the wiring:

    It says I need to connecting the echo pin via a voltage divider to divide the 5V to 3.3V, which is the operating voltage of an ESP8266. Is this something you needed to do, and what exactly do I need to do here?

    Many thanks

    • Hi Paul, did you download the tasmota.bin or the tasmota-sensors.bin, you’ll need the latter as it includes more sensor support

      • Ah, that’s what I’ve done. Many thanks Martin. Will re-flash with tasmota-sensors.bin and see if that fixes it

      • I’ve got it working now, thanks Martin, and it have it set to notify me via the Home Automation app when the salt level is low.

        I can’t figure out how to get the data into Grafana though. I am everything on an Unraid server and have installed a Grafana, Influxdb, Telegraf, Loki and Promtail Docker stack. The stack came with a dashboard to monitor my server and that is working fine.

        But I cannot figure out how to get data from the sensor into Influxdb and then into Grafana. I’ve installed and played around with Node-Red as well but don’t really know what I’m doing. Any hints would be appreciated.

        • Glad you’ve got it working Paul.
          In terms of getting the data from HA into Grafana. 1st you need to configure Home Assistant with the details of your influx database, per: https://www.home-assistant.io/integrations/influxdb/ for example:

          host: !secret influx_host
          - sensor.water_softner_salt_level

          Then once the data is in getting to influx you can create a graph using a query like:
          SELECT mean("value") FROM "cm" WHERE ("entity_id" = 'water_softner_salt_level') AND time >= now() - 6h GROUP BY time(20s) fill(null)

  • Excellent, many thanks Martin. I’ve got it all working now

  • Hi Martin
    For some reason my salt level monitor has started going haywire. It works for a bit, and then starts reporting random incorrect values that are much larger than the actual distance.
    Any idea what could be going wrong? This is the output from the Tasmota console (the actual distance is currently around 15cm:

    16:09:23 MQT: tele/saltlevel/SENSOR = {“Time”:”2021-01-03T16:09:23″,”SR04″:{“Distance”:34.053}}

    34cm is well past the maximum it could be even if the softener had no salt in it at all. Could the sensor be faulty do you think? I’ve got a Sharp IR sensor so I might swap it out and try that.

    • Hey Paul,
      I bought a pack of 5 sensors just in case: https://amzn.to/3hCCg2p
      So if you can, try swapping sensors to see if that helps. I had an odd issue last week where my results became erratic, I changed the sensor and it didn’t help. I then just moved the salt pellets around a little and that fixed it, odd.

      When my tank is near empty it’s about 45cm and 11cm when full of new salt pellets. Hopefully, yours isn’t too close that the sensor is getting contaminated when it regenerates?

      I also recently had an issue with false triggering from the Sharp IR sensor I used for my pet door, swapped that out for a different one and that’s fixed that problem. So all these sensors can fail, the joys of home automation. Good Luck!

  • Thank you detailed write-up , which pulldown resistor you used ?
    how you connected it ? data to gnd ?
    also D0 supports pull-down resistor why didn’t you used that ?

    • It’s been a while since I created this project, so I can’t recall all the details for doing what I did. However, I believe as was using Tasmota I couldn’t configure the internal pull-down resistor. Tasmota actually recommends using a pull-up resistor, which I believe would have allowed switch 1 to be used instead of switch 1n. But the end result is the same. The PIR I mounted to a small piece of stripboard to make connections easier and connected a 10k resistor between Data and Ground pins on that board.

  • Hi Martin,

    I have wrong measures when the water level is above my salt level, because the ultrasonic sensor measures the water surface. Do you have the same issue? Do you think the Sharp IR would solve this problem?

    Thank you

    • I use the sensor hooked up to HomeAssistant, and alert when the salt is low (distance to sensor is above a threshold). If the water level causes the salt to appear closer then this wouldn’t be an issue, however, I do get occasional readings that would trip my alert, so the automation is set to only trigger when the distance is above my threshold for 1 hour. Maybe that can work for you too?

    • Hi Rafael,

      Did you find a solution for this problem?
      I also have a softener where the water is above the salt level.




Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.