Liquid level sensor


I am using this sensor just to notify me when the water in a tank is low and to not allow the pump to run dry. The photon will only wake up 2 times a day and check the water level those two time. With this small duty cycle, do you think I will still have noticeable issues with corrosion?


I doubt it, consider it an anecdote.
However I would be tempted in your use case to put the float switch independent of whatever the photon does so that the pump is stopped even if the photon goes nuts. Other may have other opinions…


These sensors work very well:

Connect + to the Photon 3.3volt supply, - to ground and S to an analog input pin. You can measure the water level based upon the height to the water up the sensor face or just threshold the analog signal to create an “alarm” or other signal at the proper water level.

I am currently developing a water lead detector using a Photon. What I have works very well. There is more to this project than just the sensor and detector code, but here is a (temporary) link to Photon code that thresholds the sensor value and integrates it over a number of readings to filter out noise. This procedure is extremely reliable against false alarms:

This code supports two sensors and IFTTT integration to send you notifications or SMS texts. It also supports flashing an LED indicator and beeping a buzzer for local notification of a water level alarm. You can strip out any of these features that you don’t need.

P.S. The final project includes a DHT11 temperature and humidity sensor and a servo meter for local reading of temp/RH and a Blynk app for leak notification and for reading out temp/RH remotely. The status is that the project is developed and working except that we are improving the Blynk integration and documenting the packaging and assembly. The final documentation will be published at: sometime this summer.


Can that sensor be fully submerged without being damaged? I guess you could put some silicon over the electronics to waterproof them if not, but it might still be exposed to corrosion over time. A sensor like this is meant more as a water detector and/or max threshold detector. I’m not convinced it’s supposed to be used as a minimum water detector, whereas a float switch can be used for either, can be fully submerged, and should be fully corrosion resistant.

Nevertheless, these can be useful sensors :slight_smile:


@Moors7: The electronics should not be submerged. This part of the sensor (plus the connections to the pins) would need to be encased is silicone or otherwise waterproofed if the water level is expected to get this high. I agree that a float switch might be a good alternative in this case; also the idea of an ultrasonic distance sensor is also interesting, albeit I haven’t tested this.


Simple - Reed relay with a magnet, don’t worry about fancy code, sound waves, etc. We used them in the Navy and does not matter if the fluid is water, fuel, chemicals, etc.

They are used quite extensively in automotive applications for all the fluid levels, brake, oil, transmissions.

More info here


i have used the following sensors for water depth detection:


Your requirement reminds me of my sump pump alarm. The alarm box plugs into an outlet on the wall near the sump. A 2-conductor cord runs down into the sump. That cord terminates with a tilt-switch sealed inside a plastic float. To install the alarm, we run the cord to the bottom of the sump so that it rises back up as we hold the float at the height where the alarm should sound. A wire-tie is then used to lash the cord to the pipe that rises from the sump pump. That wire-tie is about 8" below the float. When all is well, the weight of the float causes the cord to flop over, and the tilt-switch opens. If the water rises too high, the orientation of the float changes and the tilt-switch closes.

Another simple idea would be to use a small hinge to mount a lever to the top of the bucket/barrel and to use that lever to depress a microswitch so that it remains high and dry. You could then use a light nylon line or cord to hang a float from the end of the lever. The float needs to be attached to a weight with enough mass to pull down on the lever with enough force to depress the microswitch … but not so much mass that the float does not float. I’d suggest a toilet float because they have a threaded opening where a metal rod attaches.This would make it very easy to attach the weight and the cord to the float.


I suggest you to have an eye to my green garden Project, Jon: I check my water tank with an Ultrasonic Echo.
Its based on Arduino as controlling device, but will work on a photon, too.
Link to my project.
My 50ct.


We use a pressure transducer to determine the water level in our RV fresh water and waste tanks. This was not my idea and I don’t want to take credit for something a very smart guy put together as a demonstration and training class at a Heavy Duty Truck Rally. Nuke-E did a basic setup. I did some work to it and put it in my RV which was destroyed in a wreck soon thereafter.

This is a write-up for the system. We use a 0-5 p.s.i. transducer readily available on the internet.

For power I will be using the YwRobot 545043 breadboard power supply with an input from the RV’s 12V system. A good functional
description is here:
Grounds need to be common to all components: Photon, LCD, pressure transducers, alarm
RX to Photon TX
Vin – YwRobot +5V. Must be a minimum of 5V. Don’t parallel off Photon, it works but LCD is barely readable.
GND – from common ground source.
Power via micro-usb port from YwRobot USB port
Pin D0 – to alarm. I was going to use a single relay but have found a controllable buzzer. If it is loud enough I will use it.
A0 – bathroom gray tank pressure sensor
A1 – kitchen gray tank pressure sensor
A2 – black tank sensor
A3- fresh water tank sensor
Ground – Common tie to LCD ground and alarm (or relay control ground if a relay is used.
Pressure Transducer
Red – YwRobot +5v
Ground – YwRobot Negative common to all components
Blue – Input to appropriate Photon Analog pin (A0 through A3)
Vin – YwRobot +5v
Ground – common ground
Input – Photon pin D0

Code is a whole lot more than you will need for one tank but here it is:

Tank Level Indicator (TLI) app by Chet Myrick
Credits:  Thanks to David Dixon for doing the preliminary setup for this app and
getting a bunch of us started at the East Coast Heavy Duty Truck Rally in 
Crossville, TN.  The serial graphic library was courtesy of Sparkfun.

This is a Tank Level Indicator for 4 tanks on my RV.  The tank levels will be
displayed on a 128 x 64 SparkFun Serial Graphic Display which can be found at 

A tank level alarm is incorporated to sound off when the waste tanks are getting 
full and when the fresh water tank is either nearing full (to assist in filling) 
or empty. A relay is used to send 12V DC to a sonalert.

Warning:  If you just copy/paste this app into the Particle IDE, it will 
fail verification.  You must copy it into the IDE and then comment out the #include
statement.  Then go to the built-in Library and find the
SERIAL_LCD_SPARKFUN library, it will not work with this LCD.
// This #include statement was automatically added by the Particle IDE.
#include "SparkFun_Serial_Graphic_LCD/SparkFun_Serial_Graphic_LCD.h"

#define maxX 127
#define maxY 63
//Each maximum value is one less than the stated value to account for position 0,0
//Thus, position 127 is actually the 128th pixel.

//Create an instance of the LCD class named LCD. We will use this instance to call all the
//subsequent LCD functions
//Establish some variables
int tnklvlalarm = D0; //Sounds alarm at 85% full (waste) or 20% (fresh) and 95% (fresh)

//Bathroom Tank
int bath = A0;
int bathempty = 003;
int bathfull = 4092;
int bathdiff = bathfull - bathempty; //Precalculate difference between bath empty and full values
//Kitchen Tank
int kit = A1;
int kitempty = 003;
int kitfull = 4092;
int kitdiff = kitfull - kitempty; //Precalculate difference between kit empty and full values
//Black Tank
int black = A2;
int blackempty = 003;
int blackfull =4092;
int blackdiff = blackfull - blackempty; //Precalculate difference between black empty and full values
//Fresh water tank
int fresh = A3; //Fresh water TLI input.
int freshempty = 003;  //The 12 bit message from the sensor when empty
int freshfull = 4092;  //The 12-bit message from the sensor when full as seen by the Photon.
int freshdiff = freshfull - freshempty; //Precalculate difference between tank empty and full values

//String variable that will store the text uploaded to Particle servers.
char resultstr[64];
void setup()
  pinMode(tnklvlalarm, OUTPUT);
  pinMode(bath, INPUT); // setup A0 as analog input for bath gray water tank
  pinMode(kit, INPUT); // setup A1 as analog input for kitchen gray water tank
  pinMode(black, INPUT); // setup A2 as analog input for black tank
  pinMode(fresh, INPUT); // setup A3 as analog input for fresh water tank

    Serial1.begin(115200); //Set the baud rate for the LCD serial connection.
    delay(1200);///wait for the one second spalsh screen before anything is sent to the LCD.
    LCD.setHome();//set the cursor back to 0,0.
    LCD.clearScreen();//clear anything that may have been previously printed to the screen.

void loop()
    int data1 = analogRead(bath);   //data1 is what the current bath gray tank level is reading.
    double bathpctfull = float(data1 - bathempty)/float(bathdiff)*100.0;  //Calculate the percent full by using values established above.
    float bathtnklevel = data1 - bathempty;  //Calculate difference between the voltage the sensor sees vs. the voltage when the tank is empty.
    int data2 = analogRead(kit);   //data2 is what the current kit gray tank level is reading.
    double kitpctfull = float(data2 - kitempty)/float(kitdiff)*100.0;  //Calculate the percent full by using values established above.
    float kittnklevel = data2 - kitempty;  //Calculate difference between the voltage the sensor sees vs. the voltage when the tank is empty. 
    int data3 = analogRead(black);   //data3 is what the current black gray tank level is reading.
    double blackpctfull = float(data3 - blackempty)/float(blackdiff)*100.0;  //Calculate the percent full by using values established above.
    float blacktnklevel = data3 - blackempty;  //Calculate difference between the voltage the sensor sees vs. the voltage when the tank is empty.
    int data4 = analogRead(fresh);   //data4 is what the current fresh water tank level is reading.
    double freshpctfull = float(data4 - freshempty)/float(freshdiff)*100.0;  //Calculate the percent full by using values established above.
    float freshtnklevel = data4 - freshempty;  //Calculate difference between the voltage the sensor sees vs. the voltage when the tank is empty.
      float bathGray = bathpctfull; 
      float kitGray = kitpctfull;
      float blackT = blackpctfull;
      float freshT = freshpctfull;
 //The following statements are used to read what the pressure sensor is sending to the Photon.  
 //The values will be displayed on the LCD at the bottom.
 //They should be commented out after calibration is complete.
      float bathData = data1;
      float kitData = data2;
      float blackData = data3;
      float freshData = data4;
  //The following routine runs to see if the gray and black tanks are at or above 85% full 
  //and if the fresh water tank is either less than 20% full or over 95% full.
    if (bathpctfull > 85) // bath gray is > 85% full
        digitalWrite(tnklvlalarm, HIGH);
        digitalWrite(tnklvlalarm, LOW);
    else if (kitpctfull > 85) // kitchen gray is > 85% full
        digitalWrite(tnklvlalarm, HIGH);
        digitalWrite(tnklvlalarm, LOW);
    else if (blackpctfull > 85) // black tank is > 85% full
        digitalWrite(tnklvlalarm, HIGH);
        digitalWrite(tnklvlalarm, LOW);
    else  if (freshpctfull < 20 || freshpctfull > 95) // fresh to alarm if it has less than 20% or more than 95%
        digitalWrite(tnklvlalarm, HIGH);
        digitalWrite(tnklvlalarm, LOW);

//The following routine will display the tank status on the LCD screen.
    Serial1.println("Tank Level Indicator");  
//Display the Bathroom Gray Tank level.
    Serial1.print("Bathroom Gray = ");
 //Display the Kitchen Gray Tank.
    Serial1.print("Kitchen Gray  = ");
//Display the Black Tank.
    Serial1.print("Black Tank    = ");
//Display the Fresh Water Tank.
    Serial1.print("Fresh Water   = ");
//These entries are only to permit calibration.  They will read the input coming from the pressure sensors
//for each tank and display the data on the bottom two lines of the LCD screen.  
//This section can be commented out after calibration.
    Serial1.print("  Kit:");
    Serial1.print("  Fresh:");
//Leave this delay in if/when the above is commented out.

//And do it again!


+1 for postler’s appproach of using an ultrasonic sensor.

I use this for measuring depth in a water tank in my attic (with an arduino running it, as far as I recall, but a Photon would work perfectly fine too)

they are rather cheap, you’ll find them on ebay for less then $2 each. They are mass produced for parking bay sensors so they are super cheap these days …


There are some videos online of this. The problem is with DC electricity, the wires corrode.
(A lot of comments mention this as an issue)

I think the better solution is using a sound (ultrasonic) sensor. It works very well to bounce off the top of the water. I did this recently to measure the water level of a guinea pig water bottle. It worked really well.

This one is pretty good and cheap:

Here’s a video:

Here is my code btw:

#include "HC_SR04/HC_SR04.h"
double inches = 0.0;

int trigPin = D5;
int echoPin = D6;

Connect an HC-SR04 Range finder as follows:
Spark   HC-SR04
5V      VCC
D5     Trig
D6      Echo

The default usable rangefinder is 10cm to 250cm. Outside of that range -1 is returned as the distance.

You can change this range by supplying two extra parameters to the constructor of minCM and maxCM, like this:

HC_SR04 rangefinder = HC_SR04(trigPin, echoPin, 5.0, 300.0);


HC_SR04 rangefinder = HC_SR04(trigPin, echoPin);

void loop() {
    inches = rangefinder.getDistanceInch();
    Particle.publish("distance", String(inches));


Depending on the size and shape of the tank, ultrasonic sensors can be difficult to use in enclosed spaces. The ‘return echo’ can bounce off the sides of a tank, etc.

I second the recommendation of the Adafruit VL53L0X distance sensor (that, or the VL6180X version). Much more narrow area of measurement which avoids echoes from the sides, etc. Super easy to use with a Photon or Electron.

Of course, there’s always the trust liquid level sensor: that comes in either 8" or 12" length, and in either water or chemical (teflon-coated) versions. Those, too are dead-easy to use.


Though I admire all the complex solutions for distance sensors, water height sensors, etc… Aren’t we complicating the situation a bit? It’s not relevant how high the water actually is, the only thing that’s needed is to know if it went below a fixed point. That’s a boolean situation, where distance sensors, capacitive sensors et all, mostly make things harder than they need to be. A float switch does everything that’s needed in this case, doesn’t it? No libraries, or complex code required, just a simple digitalread. KISS.


I translated my arduino project into a photon case here including optional Blynk-Services. My Cucumbers grows :wink:


Replying a bit late to this, but I’ve been doing this to measure the level (and calculate gallons remaining) of our oil tank, and it works incredibly well.

Here is the code + I have an instructubles on the hardware design:

(this post actually made me create a dedicated thread for the oil checker:


Sorry for bumping up an old question but I’m in the same boat of requirement.

And to my surprise there are quite a few new sensors in town:

This one has 2 transducers instead of 1 therefore has less minimum detection distance as compared to JSN SR04T. It is also completely sealed and waterproof.

Before finalizing on this I had bought another one which was a waterproof modified version of HC-SR04 from here

The 1st one is much more rugged and waterproof as compared to the latter one.