Do you have a tank whose fluid level you want to keep track of? Even if not, you may have an idea for an IoT project, or a solar-powered project, or a Particle Photon project. This Instructable includes many useful details and photos that will teach you (among other things):

How to choose and use ultrasonic rangefinders

How to measure small bidirectional DC currents with an Arduino (battery charging and discharging)

How to log and share sensor data in the cloud

How to charge your outdoor IoT project with a solar panel

How to deal with varying or unmatched voltages

Debugging. Not bugs in software, but actual bugs!

I describe here a system that will send your phone and computers a Pushbullet warning if the tank needs filling. It includes data logging in the ThingSpeak cloud to monitor and share usage and other data. We have a 1000-litre kerosene tank outside our house that supplies heating oil to our boiler, which in turn distributes the hot water to radiators around the house. Unfortunately, these oil tanks are opaque and there is no easy way to know how much kerosene is left until the boiler stops working on a cold day :( Traditionally, people here in Ireland periodically poke a pole down the filling hole, an improvised dip-stick, to see how much oil is left. A fancy tank may have a sight-glass, but that still requires you to brave the cold to check it regularly. With my Oilwatcher, you can check oil levels with any phone or computer. My Instructable project was inspired by the similar one by Ventz (who was very helpful), but because I don't have power near my tank, I had to figure out how to make mine solar powered. I also completely re-wrote the code to log various diagnostic and weather data. I have been using this setup since February 2018, and for the past few months, it has been very reliable and useful. I will describe how I built it, some of the problems I had, and the solutions I came up with. The cost to build your own would be between $100 and $200. Recently, commercial solutions have been developed, e.g. the Apollo Smart oil monitor in Europe or the Smart Oil Gauge in the US, but if you want the fun and flexibility of a homemade hackable smart IoT system with automated alerts, data logging and sharing, read on! (NOTE: Many of my photos have captions. Click on an image to start the slideshow and look for rectangle overlays. When you mouse over them, the caption appears.) This Instructable is entered in the Electronics Tips & Tricks Contest...Please vote for it if you like it!

Step 2: Ultrasonic Rangefinders - US-100 Wins!

The theory of operation for this approach to tank level monitoring is pretty straightforward: bounce sound pulses off the fluid surface, and by measuring the echo's delay, calculate how far down in the tank the level is. In practice, it was not at all straightforward. Thankfully, there are lots of cheap ultrasonic rangefinders used for hobby robots that will do an OK job. I originally used the HC-SR04. This device outputs a TTL pulse whose length corresponds to the distance, and the Arduino (or in my case, Photon) has to measure its length accurately. This proved to be very tricky and fraught with noise problems. It had poor accuracy (repeatability results vary by ~2cm), poor precision (best possible is 1 cm using NewPing library), and poor reliability (some data were completely wrong).

Thanks to Andreas Spiess, I discovered the US-100 ultrasonic rangefinder, which can be found for less than €3 and has a digital mode that responds with the distance to the target in mm (not cm, as with other digital ultrasonic rangefinders). It does the conversion from echo delay to distance internally, not in the Arduino, unlike most analog ultrasonic rangefinders. I found that the HC-SR04 was susceptible to noise on the line between it and the Photon. A digital signal is less prone to noise problems. The US-100 also includes a temperature sensor it uses to correct for changes in the speed of sound with temperature. Another benefit is that it can be used at 3.3V, unlike most ultrasonic rangefinders which need 5V to work well. To allow it to survive the elements of an all-weather application like this, I soldered the connecting wires and encased the circuit board in 5-minute epoxy. Pictured is my tank's vent cap with the sensor held in place with hot glue. Kerosene (heating oil) is not nearly as volatile or easy to ignite as gasoline, so there is little or no danger of explosions from this type of device. (Obviously, if you are measuring a more flammable liquid, you would need to carefully isolate any electronics from the vapour)

Banana Robotics sells the US-100 for $5 and has the best description I could find for how to use it in its digital (Serial Data) and analog (Pulse Width) modes, which you select with a jumper. If you scan my code at the end of this Instructable, you will see you just need to send the US-100 a command (0x55 or 0x50) via the Photon's TX line to query the sensor and it replies in a few ms via the RX line with either the distance in mm or the temperature in degrees celsius.

Step 3: False Echo Problems -- Bugs Fixed!

As you can see in the photo, my tank has a lot of internal structure to its shape that caused me lots of problems with false echoes that were not coming from the oil surface. Oil consumption would seem to cease at some point, even when the boiler was working away burning up oil. The false echo problems don't get revealed until the oil level goes down, exposing internal tank structures. I had some success focusing the ultrasonic beam with 10cm of heat shrink tubing applied to the sending and receiving transducers (see photo). But this approach was very sensitive to exactly how I put the cap back onto the tank. Better than the small heat shrink tubes, I came up with an idea that, it turns out, has been invented long ago for this purpose, called a "stilling tube". Mine is a PVC pipe that extends from the very bottom of the tank to the top and the ultrasonic transponder is placed inside its top end. At its bottom end are a couple notches to allow oil to easily pour into and out of the pipe from below so the level inside the pipe is always the same as the rest of the tank. It is called a stilling tube because the level inside will be relatively flat and calm even during filling. (That was important during calibration.) And because the inside surface of the pipe is quite smooth, there are no false echoes to worry about. Except for the earwigs! I was getting odd readings at random, rarely. When I took the cap off to investigate, I saw about 5 squirmy bugs run away, and one headed down the PVC pipe! I thought it was hilarious that the errors in my data were not due to a bug in my code, but an actual bug in my tank! Now I have closed up the vent cap a bit more securely with a nitrile glove and some silicone rubber to "debug" it and discourage earwigs and spiders from setting up shop in there. It is not a perfect seal, to allow for expansion and contraction of the air in the tank.

Step 4: The Particle Photon Is and Is NOT an Arduino

This IoT project requires a microprocessor with Wifi. I chose the Particle Photon because that is what Ventz used for his tank monitor.

If I were starting this project now, I would probably use one of the WiFi-enabled Arduinos available from Arduino.cc, such as the Arduino MKR WiFi 1010 . I am not unhappy with the Particle Photon, but they have basically created their own parallel Arduino-like universe instead of just making their products usable with the Arduino IDE. Their Web IDE is very much like the Arduino IDE, but each library you might want to use has to be imported and verified by them to be able to easily add it to your sketch. Something as simple as reprogramming the Photon via USB or even using a serial monitor for debugging is difficult because it requires layers upon layers of software to be installed (Homebrew, dfu-util, NPM, Xcode, etc etc) and to learn a command line interface (CLI). They expect you to reprogram it over the air (OTA) but that is not always possible because the device is offline and sleeping most of the time. It was difficult to install Particle's CLI due to MacOS X High Sierra's overzealous security changes. Although Particle's online documentation is generally pretty good, navigating it and finding things is unduly complicated. I usually just give up and use a Google search instead. On the plus side, Particle's customer service is excellent, and questions get detailed replies from tech support in a day or less. Another option would be to use an ESP32, which now seems to have pretty good functionality in the Arduino IDE, and less overall power consumption.

The Photon is a 3.3V device powered by microUSB (5V) or 3.6-5.5V on its Vin pin. Its digital inputs are all 5V tolerant ("FT") but its Analog pins are NOT. Be sure NOT to apply more than 3.3V to them.

Step 5: Battery: Sealed Lead-acid Gel Cell

I first tried using a LiPo battery, but soon found out that it was pretty worthless when the temperature fell below freezing. This is why electric cars need battery heaters to get a reasonable range in the winter. As I know from starting old-fashioned gasoline/petrol cars on cold winter mornings, lead-acid batteries work well in the cold. A LiPo can be quickly ruined by charging it in freezing conditions.

The electronics I used draw about 80 mA when active, probably a lot of that being used for the WiFi connection.

So in theory, this battery should be able to power the system for a couple days with no sun. Since there may well be more than a couple overcast days here in Ireland, I usually put my Photon to sleep for 5-10 min at the end of each loop, like so:

System.sleep(WAKEPIN, RISING, SleepSecs);

and the WAKEPIN is connected to a momentary switch (to pull up the line from 0 to 3.3V) that I can use to help re-program the Photon without opening the box, if it is sleeping. I also added a delay of about 10 seconds in the loop, so that if I time it right, I can re-flash the Photon OTA (over the air) via WiFi before it goes to sleep.

These lead-acid batteries are "sealed" but have a vent that can emit flammable hydrogen gas when charged rapidly so it is probably best to make sure there is some sort of rainproof vent on your enclosure.

Step 6: Oilwatcher Schematic Diagram

Here I have sketched the wiring diagram for my entire project. It went through many versions and upgrades, all scattered through my maker notebooks. So I took it down, opened the box, and retraced everything as it is right now. It is not perfect, but it works!... See the Calibration step for info about setting the trim pots.

I welcome your suggestions and ideas for improvement. If you make a version for yourself, please tell us about it in the comments or better yet, write your own Instructable!

Step 7: Solar Power and Mounting

I soldered two solar panels in series to charge the "6V" lead acid battery, through a low-dropout adjustable voltage regulator (MIC29302). The panels are rated as 5V 500mA 2.5W, and are 13 x 15cm each. They have absolutely no circuitry in them, just solar cells, so I set the adjustable voltage regulator to 7.3V, which the battery says on its front is a good charging voltage. I found out that solar panels when dimly lit become a great way to discharge batteries. I had invented a Solar Panel Defrosting System! So I included a diode in series to make sure current only flows from them into the battery, not out. Make sure it is a beefy diode, as charging currents may be up to 1A. Be sure to weatherproof all connections with epoxy or silicone rubber to avoid corrosion. And unlike my rat's nest, insulate all exposed PCB leads, solder, wires, etc. to prevent letting out the magic smoke that keeps it all working. For my Outside DS18B20 temperature sensor, I sprung for the more expensive water-tight version.

To power the Photon, I connected the battery to the Verter Buck/boost converter from Adafruit . This can take a wide range of DC voltages (3-12VDC) and turn them into the 5VDC that the Photon takes via its micro USB port. Thus, my Oilwatcher keeps working in the dark until the lead-acid battery is really dead. Unlike LiPo batteries, Lead-acid gel-cell batteries are not ruined by completely discharging them.

I mounted the solar panels with a couple metal brackets and some strong weatherproof epoxy paste (PC-7) to an old computer monitor stand. I have several of those stands from my Artificial Window Instructable project. You should locate and point your solar panels carefully, to avoid shadows and collect the most sunshine, especially on shorter winter days. For that reason, I aim them at the height of the noon sun on a winter day, and have one panel angled to catch more morning sun and one to catch more afternoon sun. By monitoring charging current you can optimize this. There are apps and websites that can also help with this, based on your latitude. You should mount the panels solidly to withstand wind and other outside hazards. Mine is on a 4x4 wood post that used to hold up a fence around our tank.

Step 8: Calibration: Volumes and Voltages

Tank mm to L calibration

To make a useful device for measuring how many litres (or gallons) you have left in your tank, you need to convert the rangefinder's signal, in mm (or cm), to litres. If the tank were a vertical cylinder or a perfect rectangular prism, this would be a simple matter of measuring the tank's dimensions and doing a little math. But as you see, my tank is a bulging oval shape, with two voids in the middle, and various ridges and whatnot. This suggested to me that 1 cm of echo distance change would represent a varying amount of litres at different levels. To measure directly how the volume changes as a function of oil level, I wrote a sketch to collect data as rapidly as possible during tank refilling (given the limitations of the Particle Photon's cloud service, about every 2 seconds). I assume that the truck that fills the tank has a pump that pumps at a constant flow rate, which the driver sets with a big lever. And the truck is carefully metering the volume delivered (1000 L total). I was surprised to see in the attached graph of the transponder data collected during filling, that the curve is quite linear across the entire range! Perhaps the tank designers adjusted the voids in the centre of the tank to compensate for the increased width at its centre. I converted the time axis to litres, and measured a conversion factor using a linear fit to the curve: 1.10 L/mm. I also took note of the transponder reading when the tank is empty, meaning when the spigot sucks air and the boiler quits. This turns out to be 1304 mm for my tank. This is important for setting a useful alarm; you need to know when the boiler quits, not when the tank is dry. (The spigot is not low enough to drain the tank dry.)

Voltage and current calibration

The other thing I wanted to calibrate, to predict when the battery would die if there were too many cloudy days in a row, is the electrical current drawn by the whole system, and the battery voltage. To do this, I made a crude "high-side" bidirectional current sensor using a 1-ohm shunt resistor in series with the (+) power from the battery. I measure the voltages on each side ("tap") of this resistor relative to ground. The difference between the two measured voltages, or voltage drop across that resistor, is proportional to the current through it (Ohm's Law, I=V/R). With R=1 ohm, I=V, so 80mV is 80mA. I divide each tapped voltage by a known amount (~factor of 7/3 to bring 7.2V down to ~3.3V) with voltage dividers (10k trim pots, see schematic diagram later in this Instructable) to prevent exceeding the 3.3V max of the Photon's analog inputs. So I used two of the Photon's analog input lines to measure this voltage drop (and another to measure Vbatt). To calibrate this setup, I powered the whole device from a digital benchtop power supply with a good current readout, and got current measurements under various conditions: WiFi connected and Photon active (~90 mA) and sleeping (~1-4mA). Because the voltage drop across a 1-ohm resistor, especially after the voltage dividers, is really tiny (and the photon's A/D lines are only 12 bits= 4096 levels), I needed to average 100 measurements to get a reasonably noise-free current value. These can be collected quite rapidly. Ideally, I should have made a differential amplifier to boost that current signal, but this simple averaging approach works pretty well for measuring bidirectional current flow (charging and discharging). I tried using a 10-ohm shunt to increase the signal, but the Photon couldn't get enough juice through it to work. It got stuck in brown-out mode. I could have used trim pots of less than 10k for better noise immunity but at the expense of wasting the battery heating the trim pots. 1k would be 7mA wasted per trim pot.

So with the analog lines giving me digital units from 0-4095, and with current and voltage measurements from the benchtop power supply, I was able to put conversion factors into my sketch (see my code in the last step). Obviously, you would need to calibrate your setup yourself to get good data.

I realize that I don't really need to measure Vbatt with a separate analog input line, and its own voltage divider, but I kept that because it is conceptually clearer and because the current monitor taps have to be located symmetrically right next to the 1 ohm resistor. (I already had the voltage monitor in there on a separate board before I added the current measuring system.)

Step 9: Using Pushbullet to Send Alarms

Pushbullet is a cross-platform alerting and messaging service. Your Photon's sketch will include some "alert" messages that will be "published" to Particle's cloud, e.g., when the oil level gets below some threshold. Install the Pushbullet app on your phone and it will echo any alerts, notifications, and messages you may wish to all your other devices. Thus, once you have it set up properly, it will be hard to miss the important "Oil is low!" alert that your Oilwatcher device will initiate.

He also includes a description of how to get started with the Particle Photon. And lots of screenshots of the process are in his Instructable. He mentions that he moved to Pushover instead of Pushbullet, so there are some options for exactly how to implement getting alerts on your phone.

Step 10: Using ThingSpeak to Log and Share Your Data

If you just want to live in the moment and forget about your heating oil until it runs out, you can skip this section.

For those like me who are interested in all the scientific and geeky details of how much oil you use at different times of year, or how much sunshine or cold happened, ThingSpeak is for you! With the solar panels as a sun sensor, and the temperature sensors I included in my project, I am slowly building a proper weather station! Thingspeak is a place to collect and analyze data of any type, using lots of graphs and if you wish, complicated math. It was created by The MathWorks, who also created Matlab, a favourite among scientists like me for dealing with Big Data. "The open IoT platform with MATLAB analytics" is their tagline. You can keep it all private, or share your data with the whole world, as I have done here. You can have your Photon sketch write up to 8 different variables to "Fields" in your Channel at their cloud every few seconds. After you have created an account at ThingSpeak, create a Channel as a place to collect and work with your data. Note its channel number. Set up the Channel with Field names and note their Field numbers. Then you can get an API Key from the API Keys tab. Use this in your Oilwatcher sketch setup:

Then in your Channel's Private and/or Public view tab, create visualizations (charts) of your data and they will be updated automatically each time a new set of data is broadcasted by your sketch.

Step 11: The Oilwatcher Sketch

Attached is the .ino file that is my Oilwatcher code AKA the Photon's firmware. The .zip file also includes the library called RunningMedian by Rob Tillaart, not yet on Particle's web IDE. I got the latest version of that library here:

The other libraries included at the top are in Particle's libraries, but don't forget to actually #include them in your project to get the code to compile properly.

If you do decide to use all the bells and whistles I included, like the current monitoring, ThingSpeak etc., there will be some constants in the header of the sketch you must personalize. And of course, the oil level at which the code sends out an alarm must be carefully set for your tank.

Toys Contest

First Time Author

PCB Contest

9 Discussions

Nice project and well done instructable. However, it would be suitable to measure levels of some non-flammable liquids, while for kerosene it poses potential hazard of ignition. The circuit which is exposed to tank inner atmosphere can deliver enough energy to ignite vapours that will build up in the tank. Unless the energy to the US sensor is limited by a barrier or the device is sealed to prevent contact with explosive gases.For more on this read about explosion protection - https://en.wikipedia.org/wiki/Electrical_equipment...Your device should typically be Ex i - intrinsically safe or Ex d - flame proof. Some other types of protection can be found it that wiky.Be safe ;)

Yes, safety first! I and also Ventz addressed the safety issues in our Instructables. Ultrasonic probes do not generate any sparks (no relays or switches) or have hot components, but if you were to connect or disconnect wires from the sensor you might get a spark, one of the reasons I soldered my cable to the sensor.

Definitely wise thing to do to solder wires and to remove connector contacts as a potential source of spark. I would be also afraid of other modes of failure - it is exposed piece of electronics in flammable atmosphere (permanently - zone 0), connected with wires to external circuit (sounds almost like description of a detonator to me). Your CPU board can fail, you can send higher voltage during manipulation with external circuit, wireless can do things, PSU can fail - R&D would typically perform FMEA and address resulting risks. This problem drives whole industry behind Intrinsic safety.

I defer to Ventz who addresses this in his Instructable: https://www.instructables.com/id/Monitor-Heating-...He says: SAFETY INFORMATION: In case anyone wants to know if "this is safe to build/install" -- I have taken this to 2 different Oil companies for feedback/safety considerations, and I have run this by the fire department's Fire Prevention Deputy Chief. Per all 3 - the device is considered completely safe with no risk of fire or explosion. That said, I cannot control your individual environment/what you do with it, so please assume your own risk when installing it. Per the oil companies - electric sparks/open flames will not ignite the oil, so there is no possibility of catching fire/explosion/etc. Nothing compresses/creates a vacuum/creates air pressure to cause an explosion. My favorite quote was "even if you flick lit matches in your oil tank, it will not catch on fire."

Thumbs up to Ventz, he went far to make sure his design was safe. Fair message to anyone following this design for hazardous liquids is to check his/her application specifics and consider eventual risks.Stevempotter, thanks for great instructable.

Its inside diameter is just big enough to accommodate the transducers of the ultrasonic rangefinder. I did not measure it but I don't think it matters too much, as long as it is bigger than the transducers and fits in the opening of the tank.