Water Leak Detector Two Wires

I trying to setup a simple water detection sensor using two wires and particle.

I’m using the code below. It works fine when I touch the two wires together but when both wires a placed in water nothing happens. Is there any other way of doing this without buying extra parts? Is the 3.3 volts not sufficient?

Simple Script to monitor 2 wires instead of a float Switch for High Water Alarm   
INSTRUCTIONS:   Connect 1 wire to Ground and the other wire to Digital Pin 6.  You're Done!  Place both wires in the Container (say 1" apart).  Alarm condition when water reaches both wires.

#define alarm_delay        2000    
unsigned long previousMillis;
unsigned int lastAlarm = 0;  
int Water = D4;   // 2 wire "Switch" will be connected to Ground and Digital Pin 4
int Switch = 1;   // Set to HIGH for startup (High Signal means the Switch is hanging in air- "no water".  We dont want a false alarm at system startup.

void setup() {
    pinMode(Water, INPUT_PULLUP);   // Bring the pin HIGH. The circuit will be grounded when the Switch CLOSES (when water reaches the 2-Wires) and pull D6 LOW.
void loop()  { 
    Switch = digitalRead(Water);
    if (Switch == 0)  { // 0 is LOW, so the circuit was grounded by the 2-Wire float switch (HIGH WATER Condition)
        unsigned long now = millis();
        if ((now - lastAlarm) > alarm_delay)  {
            Particle.publish("ALARM", "HIGHWATER"); // Water has reached the 2 wires.
            lastAlarm = now;

Clean water is not actually that good of a conductor :wink:
Hence moisture sensors do feature some extra components that make it possible to measure that little current you get flowing with 3.3V or even 5V.

Have a play with analogRead() instead of digitalRead() (which requires a considerable change to flip from HIGH to LOW) and also try adding some salt to your water to see the change in conductivity.

1 Like

Thanks. I tried the A1 same result.
Added salt it worked.

Is there any way to make the pin reads “more sensitive” so it can work in “clean water”?

Hi @oraclerouter -

Referring to the advice from @ScruffR;

Instead of working with pin HIGH of LOW, rather make use of analogRead() which should be much more sensitive. You will be able to obtain many more readings/values (4095) as apposed to simple HIGH or LOW on digitalRead();

Something along these lines.

int analogPin = A1;     // sensor connected to analog pin A3
int val = 0;           // variable to store the value read

void setup()

Serial.begin(9600);          //  setup serial

void loop()
  val = analogRead(analogPin);    // read the input pin
  Serial.println(val);             // debug value

You can then use the value obtained form the analog read to set criteria in essence simulating HIGH or LOW according to your own set of parameters.

Hope tis makes sense.


1 Like

Hi @oraclerouter,

Some time ago I did the same as you until I read from this guy what @ScruffR just said above.

Then inspired on that circuit above and this one I developed the following one:

Which is the one I use in my home sensor these days.

The transistor is an MPSA13 transistor (Darlington pair):

You can check the section THE 3rd GENERATION WATER LEAK SENSOR here for code if you wanted some.


Thanks @gusgonnet.
Great project! Thanks for the info. Quick question, do I still need the resistors marked in red? Sorry, I’m still learning the electronics components.


Hi, I don’t know enough to answer your question, so I would leave them there.
Perhaps in the original arduino thread you may find your answer and why they should be there?

@gusgonnet, @oraclerouter, the 1K ohm resistor is there to limit current to the base of the transistor should the sensor leads be shorted. The 1M ohm resistor provides a weak pull-down for the transistor gate so it doesn’t float and conduct accidentally. The large resistance will not affect the weak current which will flow through the fluid and trigger the transistor.


thank you PK!!!

1 Like

HI @oraclerouter -

The resistors are needed as @peekay123 mentioned yes. Especially if you are going to need output voltages in certain ranges later to, in example, trigger relays. I learned this not too long ago :smile: after couple of days looking through my code as to why relay is not triggering. I used this utility to help me determine resistor sizes. Not that easy to figure out, but once you do, it is very helpful!

* Circuit calculator

Hope this helps.
Regards, Friedl.

1 Like

@friedl_1977 @peekay123 Thanks guys.

1 Like

@friedl_1977 just a follow up. I was thinking about the use of analogRead() comapred to Darlington pair transistor. In this applications, which one do you think would be a better option (less false positives, possibly?)

EDIT: Pondered about it for couple of minutes, haha.

Well first, the EC value of the water will greatly determine what sort of readings you will get on the analog Pin so it would be good to know (if possible) what sort of water you will be monitoring. Off the top of my head, I would probably go with analog read to start, here is my reasoning:

Lets say you are testing for leaks in clean water systems. You will get a much lower reading on your Analog pin due to smaller EC rating in cleaner water. Using Analog read, it is simply a matter of changing code to determine when you want for example the LED to light up signalling conductivity is happening or not i.e

IF AnalogRead > 2000 for >20s then LEDpin HIGH
else If AnalogRead <2000 >20s LEDpin LOW

Also, fewer components :slight_smile:

Of course you will have to do some basic benchmark tests to see what sort of values you get. The alternative, to cater for them all, would be to monitor the reading you get on the Analog pin with no connection (so no water). Lets say you get a reading of 200… It is safe to assume anything greater than 250 for an extended period of time, would mean there is some sort of electrical current being conducted.

I have used similar though process in a solution utilising an ACS722 current sensor. The client wanted to know whether machine is on or not. Simply put, the ACS detected a value of ±500 with no current flowing. It was therefor safe to assume any value above i.e ±700 would indicate the machine is running as even the smallest of currents had a significant increase in the reading on the Analog pin. Been in use for a year… no false positives that we know of :slight_smile:

Neither way is wrong, depends on your preference. Hope it helps!!

And the reliability of either solutions :wink:

1 Like

Hi @peekay123 -

Is my suggestion not reliable? :see_no_evil: :flushed:


@friedl_1977, absolutely though it is dependent on the EC of the water, the electrodes and other factors. What I mean by reliable is the solution that has the most repeatable, most trustworthy results. This will need to be judged based on testing. Both solutions are viable but not necessarily reliable.


@peekay123 -

pheewww… would hate to steer someone in the wrong direction. I have learned that what seems to be the bets idea on paper, might not always be the winning idea in practice depending on external factors. I agree 100%…

1 Like

@friedl_1977 @peekay123 you guys rock! Thanks for the info!


I did some testing with the analog pin, here are the results:

  • Pin wire & GND wire not touching and out of water - val value read every 1s results 220 - 400
  • Pin wire submerged in water & GND wire out of water - val value read every 1s results 0 - 3000 (sporadic drops to 0 occur, few spikes to 3000 when initially placed pin wire into water )
  • Pin wire submerged in water & GND wire submerged in water - val value read every 1s results constant 0

With some tweaking this may be a good solution.

@gusgonnet with your setup have you encountered any false positives?