heating oil tank level sensor – JSN-SR04T version

38 Responses

  1. Ash says:

    Excellent write up. Thank you for taking the time to do this. It has helped with my own, very similar, project.

    One thing I am experiencing is timeouts. I see this in the log:

    [09:08:13][D][ultrasonic.sensor:025]: ‘Oil level in cm’ – Distance measurement timed out!
    [09:08:13][D][sensor:092]: ‘Oil level in cm’: Sending state nan cm with 0 decimals of accuracy

    This results in a ‘non-numeric’ error in Home Assistant. Have you experienced this? Any idea of the cause or a solution?

    • roger says:

      I have seen this error. At times I thought I had two many sensors on board so I slimmed down the code; at others I changed the ESP pins used or the ESP itself. Ultimately it seemed to be related to the strained connection of the sensor plug and the board. It went away so I took care not to touch the thing again.

      Generally errors happen everywhere – eg when trying to upload the firmware – so it’s easy to be discouraged. My tips would be a) experiment a lot b) take notes in a book c) buy two of everything if that’s affordable.

  2. Graham says:

    As an avid user of Home Assistant, this is a fantastic help guide for monitoring an oil tank here in the UK, thank you. To save hacking up a USB cable, would something like this board work for the ESP module https://tinyurl.com/vj6x9wd ? Can you recommend a housing for the ESP and the sensor board?

    • roger says:

      Cheers Graham. Thank you for reminding that some ESP32’s have a USB socket.

      For a housing on this occasion I used a £4 (electronics) project box from ebay. There are dozens in all sizes, with see-through lids and waterproofness. Since then I’ve bought (from Screwfix or Toolstation) electrician’s junction / connection boxes also called chocboxes. This one fits an ESP32-CAM at £1; others are larger and waterproof https://www.toolstation.com/junction-box-ip20/p59791

  3. Dan says:

    This is excellent. Do you have the plans for the oil cap that you custom printed? I’d love to order one like yours.

    • Douglas Telford says:

      I am just starting a similar project on my oil tank having managed to run out of oil on the coldest days. I don’t have access to a 3D printer and so have been trying to find a housing for the sensor to fit on the tank top pipe. I have found on my 600 Gallon tank a Sunpat Peanut butter jar lid fits the top rather well and will just need to have a hole cut to size for the sensor. I have yet to do this!

      • roger says:

        Sorry to hear this Dan but your/this project is worthwhile. It helps that my sensor cannot be displaced. For sure there’s a jar lid somewhere to suit. I’ve now updated the post with a hint to check the calibration and watch the graph as I now get a graph plateau at 0.72 m from the top. The actual reading therefore can mislead. As 760 litres was the trigger for ordering more oil the issue was never spotted – but something may have changed in the tank/sensor. I’ll investigate that as well as use collected data to somehow predict when oil might need a visual check. In the meantime thanks for reminding on a vital issue. (And while I ordered oil ahead of disaster last week, suppliers were offering dates three weeks ahead so an emergency delivery had to be bought).

  4. Dan says:

    Regarding the non-numeric issue that Ash inquired about; the fix is to add a filter to your code that ignores non-numeric readings. I added it after the lambda, so the code in your demo would be:
    – lambda: return x * 1053;
    – filter_out: nan

    • roger says:

      Oh thank you so much! I wish I’d known about that (– filter_out: nan) as a way to remove non-zero readings should they occur.

      There’s another need for a filter in my TRAIN TIMES* project. The Home Assistant overview shows (something like “Non-numeric” or “Not available”) after midnight when there are no local times. A filter is probably the answer.

      I’m currently posting projects on using unmodified Sonoff devices; using RFlink and 433MHz sensors. Pop back should these be of value. Thank you again Dan.

      * https://www.rogerfrost.com/when-is-the-next-train-from-the-local-station/

  5. sooty says:

    Hi Roger – Sincere thanks for posting this!

    I’ve now got a cost effective remote Oil Monitoring system for my overseas vacation home. In the past I have always been somewhat concerned not being able to see how much oil remains in the tank as we go through the cold winter months…

    • roger says:

      Thank you too for your feedback Lance and best wishes from here. Wow … measuring oil levels remotely offers a big gain. Thinking about the oil tank level as you’ll realise is an unnecessary worry. Even ordering oil is easier when you know you use say, 100 litres in a week. I will soon be posting a very easy project to constantly display the oil level on a TTGO T-Display.

  6. Youtube Mr12v says:

    Hi Roger. Thanks for the great write up on the oil level sensor. I have replaced my broken Apollo sensor with this setup so I can integrate it into my home assistant. I just thought I’d share here about the calibration that I used to convert the distance reading of the sensor to approximate oil in litres. ESPHome has a calibrate_linear function. Doing it this way let me calibrate better to my cylindrical shaped tank (1800 litres) and have a countdown of litres remaining instead of counting oil used. This would obviously work on a square tank too with much easier values! I have 1000 litres of oil coming next week so I’ll be able to test to see how accurate the readings are and adjust accordingly. The filters code for the sensor is below:

    filters:
    – lambda: return x * 100;
    – filter_out: nan
    – sliding_window_moving_average:
    send_first_at: 7
    window_size: 7
    send_every: 7
    – calibrate_linear:
    # # Map 0.0 (from sensor) to 0.0 (true value)
    – 110 -> 0
    – 95 -> 204
    – 75 -> 544
    – 55 -> 900
    – 35 -> 1320
    – 15 -> 1660
    – 0 -> 1800

    I hope this provides some use to the readers of this blog! Keep up the good work!
    Best regards
    Kev

    • roger says:

      Thank you. That’s a brilliant use of a feature that I couldn’t quite get myself. I see your need for a calibration table. I’ll guess that you’ve worked that from the volume of a regular cylinder while my tank was a steel box. As an obsessive measurer I’m stuck on this *** do please let’s know if you find a solution!
      o Keep your eye on the oil graph and if the readings plateaux, as mine seemed to, investigate the range of this sensor.
      o Take oil and average temperature readings each night for a spreadsheet using IFTT
      o Create a daily oil use (in litres per day) graph (still working on this) ***
      o Use an hour meter or electric monitoring smart plug to monitor boiler burning time

  7. Hi Roger,
    As its been a while I thought I would just update you with how things are going. My oil sensor has been working well for most of the year now, I’ve made some changes to the code to move from “litres left” to a percentage figure. Because temperature affects the results and also that actual litres dont really matter I simplified it down to a reading maxing at 100 (percent). This has ironed out a significant number of spikes and dips in the resulting figure. Also to add that my oil tank is located away from the house so I had to utilise a battery pack and keep the ESP device sleeping for much of the time. It wakes up every 3 hours and takes a reading and then goes back to sleep again. I power it from a USB battery bank which has proved to last roughly 3 months although I’m sure with the colder weather coming that will decrease but its perfectly useable at that. I’ve attached my most recent code below which is very similar to that above. Hope all ok with your projects, please share anything else cool that you have done! Kind Regards, Kev

    sensor:
    – platform: ultrasonic
    trigger_pin: GPIO4
    echo_pin: GPIO12
    name: “oil level”
    accuracy_decimals: 0
    pulse_time: 20us
    update_interval: 2s
    state_class: measurement
    unit_of_measurement: “Percent”
    filters:
    – lambda: return x * 100;
    – filter_out: nan
    – sliding_window_moving_average:
    send_first_at: 7
    window_size: 14
    send_every: 7
    – calibrate_linear:
    # Map 0.0 (from sensor) to 0.0 (true value)
    – 95 -> 0
    – 75 -> 25
    – 55 -> 55
    – 35 -> 75
    – 15 -> 100

    • roger says:

      Hi again Kev and congratulations … especially for the attending to troublesome remote uses / battery operation / waterproofing needs.
      Two things, although you’ve probably been there: in another post I’ve been making battery banks (aliexpress etc) using 3 x 18650’s but note there are banks with six cells. The other thing was that Andries Spiess on YTube compares ESP32 boards for power use.
      I’m really happy with this project (I’m less happy with oil deliveries taking up to three weeks). Home Assistant sends an email daily with the tank level (it reassures me HA is working anyway). But now I am experimenting with tricky date calculations – the idea being to take say, yesterday’s oil use, the amount remaining in the tank and calculate the date when I ought to order. In your case a template sensor would get you back to litres. Anyway all the best there RF

  8. mike says:

    Hi sir, excellent effort for this so i am trying to make your project and following this guide but i have stuck at the programing the esp32. Can you analyze every step more detailed and clearly to follow it because i am not so familiar with those? Thank you

    • roger says:

      Thank you for writing Mike. You’re right, this post should be clearer. I will do that.
      If you’re having an issue with the flash process it’ll be a little while before that post is complete.
      Do please tell us of your success too.

  9. Scott says:

    Hi, just wanted to say thank you for this information. I came across this site when searching for DIY oil level sensors after seeing the price for an off the shelf version! Currently have an old Watchman sensor which uses a battery tube and sends a signal to a plug in receiver with a small lcd on showing numbers 1-9 as a level indicator. After recently getting into Home Assistant I’m keen to get a better insight as to current level and usage, so I’ve ordered the necessary hardware. Need to check the plastic oil tank to see what sort of holder/cap I can use, and figure out a battery pack that will give sufficient duration. I did wonder about using zigbee rather than WiFi for power reasons – had anyone gone down that route?

    • roger says:

      Hello Scott, thanks for writing in … my thoughts

    • A regular plumbers shop will find some tank fitting for you, and a blanking plug, when your stuff arrives. Several 18650 batteries ought to last months. See my post on battery packs or see Kev – Mr12volt’s note above on using batteries (he’s at https://www.youtube.com/c/Mr12v).
    • I prefer cheap electrician’s boxes instead of electronics project boxes.
    • Sugru may find a use here!
    • The low power ways to crack this might use 433MHz like the Watchman or Zigbee. I don’t know how to send over Zigbee but your suggestion is good. For the present I’d keep the Watchman running in parallel as it’s low power, sends over 433MHz and potentially hackable. For example my search for ‘watchman oil tank github’ found that the Watchman readings sent via 433MHz have been ‘intercepted’ and decoded (Manchester decoding). In short you’d need an something like the RF gateway I made adding the software that could do that. Just now this looks a bit hard but in time I’d be clever enough for it.
    • All the best for your project. It will improve on the Watchman. The battery changing inconvenience is just for six months of the year and frankly meeting this need is quite happy making. I hope to hear more.
      RF

  • Scott says:

    Hi Roger, thanks very much for your detailed response and the very useful links within! I hadn’t even considered attempting to read/hack my current Watchman setup as it is pretty old and basic, however I’m now going to investigate this option 🙂 I’ve read your post about setting up RFLink which was really informative. I’ve no idea what sort of data is being transmitted by the Watchman sensor mounted to the tank, sonwill head over to github shortly! The mains socket receiver in the garage just shows a number from 1-9 to indicate how ‘full’ tank is. I have a plastic 1300 litre tank and the Watchman transmitter has a battery tube which holds 6 AAA batteries. I do have a handful of spare 18650 batteries which I could potentially use instead though.
    I’ll see if I can read the sticker on my transmitter to see if there is a model or any useful info, but I suppose the only way to see if it will be readable by RFLink will be to try! A bit more reading and I should be able to make a start. I’ll post back with progress…

    • roger says:

      Good to hear back from you Scott. Finding a way to decode the Watchman/Apollo data pops up in at least a few places. The devices seem to use similar hardware but then knowing which RF receiver software to use was unclear and is worth some questions to the posters. I’d first pursue the known world – ie the project on this page will get to a result. Some research into waking / sleeping improves the power use. For the record, in power terms you have 750mAh per disposable AAA cell and around 2300 mAh per 18650 cell.

  • Geert says:

    mmm what I don’t get is how I convert the measurement in meter to a percentage. My full tank measures 0,26m but how do I say that this is 100percent?

    • roger says:

      Very good question. You know that 100% is 0.26 You need to know the 0% distance at the bottom level. You can also measure 50% if you like.
      Please adjust my indentation (see link below) and use the following as untested.

      – unit_of_measurement: “%”
      filters:
      – multiply: 1
      # the number above is a guess
      – calibrate_linear:
      # # Map 0.0 (reading from sensor) to 0.0 (true value). Indent more spaces than shown – see https://esphome.io/components/sensor/index.html?highlight=filter
      – 0.26 -> 0
      – 0.40 -> 50
      – 0.8 -> 100

      My personal preference is to know how much oil I used and how much oil is required to fill the tank.

  • Phreak87 says:

    hey! you can also try this one: https://github.com/Phreak87/OilMeter

    • roger says:

      Wow. This link is for a fabulous project to measure OIL CONSUMPTION. Very good Markus and thank you. BTW are you able to keep track of the oil you need to order?

  • Phreak87 says:

    Hey!

    Thank you for that compliment! meanwhile i developed more and more features for the project – so now water level monitoring (for rain water) via jsn/hs-sr04 is included too and more sensors
    like laser, weight, radar, pressure are coming.
    with the oil consumption i also track the actual tank volume in liter and percent – so if the esp was running all the time the value should give a nearly exact value how much liter you need to
    fill up completely. if you like to be part of the project you are very welcome!

    • roger says:

      Cheers and all the best. I’ll be following your progress as the burner monitoring was remarkable.

      I changed my oil and water level sensors and my oil reordering is now spot on. The time of flight sensor is however noisy. This issue I am not yet understanding – e.g. it might be due to vibration as the liquid surface vibrates. My solution to a noisy trace uses averaging which slows the response time – which in itself is not a problem.

      https://www.rogerfrost.com/oil-tank-level-sensor-vl53l0x-time-of-flight-sensor/

  • Mike says:

    Hi Roger,
    I had the same Idea, using the ToF sensor for surveilling my oil levels and was glad finding soneone having done this before. There are several things I‘ve already noticed. 2 of my sensors died for unknown reasons. Have you switched ranges for your project? My oil tanks require a range of 1.5 metres, beyond the accurate range, why I was switching frequently. I was surprised about the sensor heating up to 50C and hesitate using it inside of the oil tanks. How is your long term experience with the sensor? How often do you measure your oil levels.

    Kind regards
    Mike

    • Roger says:

      THIS COMMENT BELONGS ON THIS PAGE: https://www.rogerfrost.com/oil-tank-level-sensor-vl53l0x-time-of-flight-sensor/

      My three sensors have now run well for two years. One of them has failed – due to water or condensation inside my sensor box. The box is in a loft hence not easily visited to see that there’s rust in there (The error was ‘Component vl53l0x.sensor is marked FAILED’). As you see I take readings continuously and average these readings as shown in my config. I now can predict a date when I must reorder oil. It’s very useful!
      The range and config of my Vl53L0X sensor is correct for a range of 1.5 metres
      For more experience I must point to the discussion on my page link above

      Please provide your information source for the 50’C heating effect. It’s hard to ignite Diesel with a flame never mind this little sensor.

  • Mike says:

    Is your sensor swithing accuracy and high range beyond 1200cm? I was coding the on the esp8266 for better understanding the sensors instead of using esphome yet. My sensors are off by a couple of cm, which might result in an extra calibration loop first. As for the noise you‘ve noticed too, I considered averaging it before sending it to any backend, which leads to quite accurate results (50 single gauges averaged with a std. deviation of less than 1% at 1.6 metres). One sensor once got very hot and I was actually surprised, but it must have been an wiring issue back then. It just made me hesitate and reconsider electronic parts inside of diesel tanks.

    • Roger says:

      Hello Mike,
      Yes as shown on the diagram the VL5310x range is up to 2000cm – go to this page https://www.rogerfrost.com/oil-tank-level-sensor-vl53l0x-time-of-flight-sensor/
      If my tank level was 1200mm I’d need to order oil anyway!
      I suggest to use use ESP32 and ESPHome. The accuracy, testing it on the floor impressed me.
      The KALMAN smoothing suits the kind of noise I found – better than averaging.
      Fair point about diesel but I checked here for you, my sensor is not hot.
      Best wishes
      rgr

  • Jaap says:

    Hi Roger, i apologise in advance for a probably stupid question. I have the rtl_433 (next) add on and corresponding auto doscover add-on runniong and am licking up my airgap entity “sensor.oil_sonicsmart_679311502_depth”. (from the watchman Alarm) and “sensor.oil_sonicstd_16915_depth” from the Apollo unit.

    I not e the code below to translate teh airgap to litres in the tank but am at a loss at where to add that code. I guess it creates a custom sensor which manipulates the “sensor.oil_sonicsmart_679311502_depth” wich the litres at certain levels (I have taht data form teh manufacturers (2 tanks both horizontal cylinders). Woudl you be able to point me in the right direction please?

    many thanks!!
    Jaap

    • Roger says:

      Congratulations if you have entities. Do you have some ‘value pairs’ to share so that we can do some calibration*? For example you need both ‘sensor.oil_sonicsmart_679311502_depth’ and also the actual air gap in cm (or better, the volume this depth represents). When you’ve got a pair you make a Template sensor. (Settings > Helpers > Template a Sensor). The syntax is tricky but if your value pair indicates that you multiply the depth by (say) -4.5 to get the volume then the Template would be
      {{ states (‘sensor.oil_sonicsmart_679311502_depth’) | float(0) * -4.5 }}
      You’ll have to tweak this but you’ll be further forward than now!
      *The maths on my (oil sensor) page is for Esphome.

  • Sean says:

    Hi. This looks neat & others have clearly got it to work well.
    I’m stuck at the assembly stage. im using the SN-SR04T & ESP32 Development Board,ESP32 WROOM Expansion Board Kit,ESP32 Breakout Board, Not any type of engineer & not used this type of thing before, but have 2 M5stack bluetooth proxies working in ESPhome builder in Home assistant. Essentially I try to work out which instructions to follow.
    I can flash the code to the esp32, via usb from the pi running HA & that looks ok & the device connects to wifi, & I can ping it & look at the logs. it times out on the sensor as nothing comes back.
    However when I connect the USmodule to 5v & gnd the esp32 won’t boot. instead it loops with
    22:04:38]rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH�ets Jul 29 2019 12:21:46
    [22:04:38]
    [22:04:38]rst:0x1 (POWERON_RESET)|P����Y�����0x13 (SPI_FAST_FLASH_BOOT)
    [22:04:38]flash read err, 988
    [22:04:38]ets_main.c 384
    [22:04:38]ets Jul 29 2019 12:21:46

    I read that it can be power hungry so tried kit in a 2.4A psi rather than pi or MacBook usb – no difference.

    also I’m using gpis 33 & 32 as 12 produced a strapping warning message in the complier log & it seemed best to avoid.

    I can’t see a ‘water level’ sensor in HA when the esp is running, which surprises me as I would have expected the successful installation to have produced a sensor.

    any suggestions gratefully received

    S

    • roger says:

      I’ve updated some of the code on my page since ESPHome has changed a few details. I don’t now use a manual sef-assigned IP. I used the mdns line these days.

      However your code wouldn’t have compiled if yours was terribly wrong. I’d recommend a manual download of the bin followed by uploading via the web.esphome website

      Your ESP32 pins for trigger and echo are fine on 33 and 32. If you have a sensor section in your code the Home Assistant Esphome dashboard, the initial part of the log will show if the sensor has or not been set up. If yes this will be followed by periodic sensor updates in the logs. If no, there’s a message to look up before trying anything else.

      IF the above logging shows yes, a sensor exists and you’ve added the ESPHome device to the integration then somethings up. Delete the device in HA, reboot and add it again.

      Just occasionally you’ll get a duff ESP32. I feel there’s too much advice on this point. I found mostly it works or half works and then you fix the code.

      • Seán says:

        Thanks for the quick & comprehensive response. It was the PSU; I took the 5v from the esp32 & it clearly wasn’t up to the job. a separate usb lead supplying the SN-SR04T fixed it.

        • roger says:

          Great. It worked that’s the main thing. I’m guessing as to your setup ..I’d expect one USB psu to power the ESP32 and borrow from it’s 5v pin to power the sensor. BTW I’ve project pages for several sensors of this kind including one from DFROBOT.

  • Leave a Reply

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