I apologise for the long post but I’ve noticed that there are so many threads on water level sensors so I’m not quite sure which one I should post my questions to, hence the new topic. I was wondering if someone could assist me.
As per the diagram below, I’m planning on installing a DF Robot Analog Pressure Sensor on the lower outlet pipe of our 2400 L water storage tank.
The tanks dimensions are Height: 1700mm. Diameter: 1420mm
NodeMCU V3 LUA ESP8266 and connecting the signal cable of the pressure sensor to the ADC0/A0 Pin.
The tank is currently empty so I would like to try and calibrate it every 100L as I have a flow gauge on the garden hose which I plan to use to fill the tank. I’m planning on initially using the code below to get the Voltage reading every 100L until the tank is full.
Once I have these readings, I’d like to use this as my main code to display Liters as well as a % of how full the tank is (I’ll update the voltages and water levels from the readings obtained above):
Please could you kindly confirm if I need to add in an additional filter to account for the voltage divider which this board apparently has but I’m not sure if this is necessary as I’m powering the sensor from a separate power supply or am I totally confused?
sensor:
- platform: adc
filters:
- multiply: 3.3
If so, do I need to use this to obtain the initial Voltage reading and then again for my main code?
I’m happy to use any other suggestions that you may have but I really appreciate you reading this
Hi there,
This was a terrible solution as there were too many inaccuracies and variations for no apparent reason.
Please see post of mine with details of what I’m currently using:
Some of the other ESP32 + sensor solutions which I’ve tried and given up on:
Waterproof ultrasonic sensor - difficult to implement as the minimum distance between the sensor and the water level is ±20CM if I recall correctly. This meant that I would need to 3D print a cone to raise the ultrasonic sensor and cut a large hole in the Jojo Tank. Plus the issues of condensation on the sensor.
Analog water pressure sensor - this was attached to the bottom of the outlet of the tank. The readings were all over the place and I’d see random drops for no apparent reason so I gave up on this.
Throw in pressure sensor + ADS1115 A/D Module + voltage regulation - this was probably the longest standing solution that I had in place. The results were very erratic and I’d see random fluctuations for no apparent reason. Landed up having to re-calibrate multiple times - definitely something was wrong.
After advice from others on the Home Assistant Forum, I tried a solution which was suggested by others and it’s been spot on and much easier to implement!
2: when the sensor was in the tank and the tank was full (manual float switch had stopped filling).
As seen in the code below:
float full_voltage = 0.00092; // Voltage at full condition
float empty_voltage = 0.00042; // Voltage at empty condition
&
float max_full_reading = 9.2; // Adjust the maximum reading at full water level
float min_empty_reading = 4.2; // Adjust the minimum reading at empty water level
As there are 2 tanks and only 1 sensor, the total volume is multiplied by 2.
Both tank levels equalize when they’re full and are thus same.
YAML:
captive_portal:
i2c:
sda: 21
scl: 22
sensor:
- platform: ina219
address: 0x40
shunt_resistance: 0.1 ohm
current:
name: "INA219 Current"
id: ina_current
accuracy_decimals: 5
filters:
- multiply: 1000 #convert from Amps to mA
unit_of_measurement: "mA"
power:
name: "INA219 Power"
accuracy_decimals: 5
bus_voltage:
name: "INA219 Bus Voltage"
accuracy_decimals: 2
shunt_voltage:
name: "INA219 Shunt Voltage"
id: ina219_shunt_voltage
accuracy_decimals: 5
max_voltage: 32.0V
max_current: 400mA
update_interval: 10s
- platform: template
name: "Water Level"
id: water_level
unit_of_measurement: 'm'
accuracy_decimals: 3
update_interval: 60s
lambda: |-
float shunt_voltage = id(ina219_shunt_voltage).state;
float full_voltage = 0.00092; // Voltage at full condition
float empty_voltage = 0.00042; // Voltage at empty condition
float max_height = 1.570; // Adjust the max height as needed
// Calculate water level based on calibration
float slope = (max_height - 0.0) / (full_voltage - empty_voltage);
float intercept = max_height - slope * full_voltage;
float water_level = slope * shunt_voltage + intercept;
// Ensure water level is within bounds
water_level = water_level < 0.0 ? 0.0 : water_level;
water_level = water_level > max_height ? max_height : water_level;
ESP_LOGD("custom", "Shunt Voltage: %.5f V", id(ina219_shunt_voltage).state);
ESP_LOGD("custom", "Water Level: %.5f m", water_level);
return water_level;
- platform: template
name: "Current Full Percentage"
id: current_full_percentage
unit_of_measurement: '%'
accuracy_decimals: 1
update_interval: 60s
lambda: |-
float max_full_reading = 9.2; // Adjust the maximum reading at full water level
float min_empty_reading = 4.2; // Adjust the minimum reading at empty water level
float current_reading = id(ina_current).state;
if (current_reading <= min_empty_reading) {
return 0.0;
} else if (current_reading >= max_full_reading) {
return 100.0;
} else {
float current_full_percentage = 100 * (current_reading - min_empty_reading) / (max_full_reading - min_empty_reading);
return current_full_percentage;
}
- platform: template
name: "Tank Volume"
id: tank_volume
unit_of_measurement: "litres"
lambda: |-
float tank_radius = 0.71; // Adjust the tank radius as needed
float max_height = 1.57; // Adjust the max height as needed
float total_volume_single_tank = 3.14159265 * tank_radius * tank_radius * max_height * 1000;
float percentage_full = id(current_full_percentage).state;
float water_level = max_height * (percentage_full / 100.0);
float current_volume_single_tank = 3.14159265 * tank_radius * tank_radius * water_level * 1000;
float total_volume_both_tanks = 2 * current_volume_single_tank;
return total_volume_both_tanks;
We had a water outage today so I had an opportunity to test the sensor value (height) vs the actual height with a tape measure and I was off by 5mm, so I’ll take this as a success.