An ultrasonic sensor sends a sound pulse that bounces off the oil and returns to the sensor. The amount of time that it takes can be measured and based on the speed of sound you can figure out the distance. Neat. It's nothing as grand as the pic above, I'm just measuring the levels in my 275 gallon tank at home. I once caught the oil guy filling my tank and he was impressed when I guessed within 2 gallons of his fill reading.
I'm using micropython with an ESP32, MQTT, and Zabbix to keep historical data though I recently switched to InfluxDB.
- ESP32 Mini
- HC-SR04 Ultrasonic Sensor
- OLED Display - 0.91 Inch I2C SSD1306 (Optional, could be added later w/o much trouble)
- Soldering iron
- Dupont wires
- Rubber packing sheet (1/16" - holds and seals the ultrasonic sensor)
- PVC parts: male threaded adapter (bottom), cleanout adapter (top) for whatever size your tank needs. Mine was 2".
- PVC Cement
- Pipe Thread Sealant
When you purchase through links on this site, I may earn an affiliate commission.
Getting Started With Micropython
Grab mqtt_as/mqtt_as.py and mqtt_as/mqtt_local.py and upload them to the root of the ESP32 without the subdirs. We'll need to tweak mqtt_local.py with your WiFi and MQTT broker settings.
Grab hcsr04.py and upload it.
micropython-ssd1306 (optional if not using display)
Grab ssd1306.py and upload it.
micropython-nano-gui (optional if not using display)
Grab drivers/boolpalette.py and gui/core/writer.py and upload them to the root of your ESP32 without the subdirs.
This project's code
I have a old Zabbix server which has a couple years of oil data but I'm moving to InfluxDB and Telegraf for new projects. In the images above you can see a sample of each.
A dashboard with the outside temperature, thermostat call history, and oil tank levels can be very interesting to look at. Or maybe after your teenager just took a 45 minute shower you can take a peek at how much that just cost 🤦.
See my Laundry's Done post for some notification options.
An obvious notification would be when your tank meets some low level threshold and it's time to order a fill. A fun one could be a fill notification maybe using InfluxDB to detect a large increase over a short time. Or a more frightening large decrease over a short time!
The ultrasonic sensor is mounted face down on a rubber disc with the transmitter and receiver pushed through holes in the disc. The rubber disc is inserted into the lower adapter and the cleanout adapter is cemented on top to form the enclosure. The ESP32 will be inside the cleanout and the whole thing will be screwed into an available spot in the top of the tank. The top plug will allow easy access to the ESP32 and the rubber disc isolates the oil from the majority of the electronics. Mine's been running non-stop for more than 3 years now.
- Use the inside of the wide end of the lower adapter as a template (probably about 2.375") and cut a circle out of the rubber sheet. The goal is to have a rubber disc that can fit nicely inside the lower adapter.
- Using the ultrasonic sensor as a template, center it on the newly cut rubber disc and mark a circle for the transmitter and one for the receiver. Cut those circles and insert the sensor into the holes. To give yourself more room you could change out the sensor pins so they point straight out the back of the sensor.
- Connect your dupont wires to the sensor and insert the disc into the lower adapter as far down as it will go. Maybe use some thread sealant around the edge of the rubber disc if it isn't making a good seal.
- Cement the cleanout adapter to the upper side of the lower adapter. I added some duct tape around the 2 pieces for some added elegance.
- Drill a hole below the threads of the cleanout adapter so you can run the power wiring. I made a hole big enough to fit a micro USB cable through.
- Remove a plug from the top of the oil tank, put some pipe thread sealant around the threads of the lower adapter of the enclosure and screw it on the tank.
- Estimate how far the ultrasonic sensor is from the top of the inside of the tank and save that number for SENSOR_OFFSET in main.py.
Display mount (optional if not using display)
- Figure out which side you want the power wiring to exit and drill another hole where you'd like the display.
- You can 3D print the display mount that I modified if you like or come up with some other mount. You can grab it below.
- My tank is an upright 275 gallon tank that's pretty common for residential use in the US. The inches_to_gallons.py contains a dictionary of oil height in 0.1 inch increments to the number of gallons of oil that represents. If you're tank is different you'll have to create your own dictionary and also tweak MAX_INCHES in main.py which is used to detect bad readings. And of course rename stuff if you're using cm and liters, etc. You also don't need to go that crazy with the precision as long as you round the measurement to a value in the inches_to_gallons dictionary.
- I've included some code to detect readings that seem off and do a retry. That seems to work well for my setup but you could change that to averaging multiple readings or whatever you think would work better.