Simple water detection circuit for picaxe

mrm

Well-known member
Hello,

There are many complex solutions to water detection on the forum including alternating current options to prevent corrosion but a simple voltage divider technique which uses zero addition components apart from 2 pieces of wire and works well on Arduino type boards but does not seem to work on the picaxe.

The circuit is as follows on the Arduino:

GND ------------------------------------> Water

+5v -----1Meg-ohm resistor-----------> Water
|
ADC Pin <----------------------

The solution on the Arduino needs tuning as the value of the ADC pin when water is detected varies depending on cabling thickness and distance, type of electrodes in the water etc. and can drift with time but the technique has proved sufficiently reliable for actual use.

But it would be so much nicer if the Arduino board (even micro ones or cheap clones) could be replaced by one small chip (such as a picaxe 08m2), a capacitor and two resistors and perhaps a simple interface to set the ADC value that corresponds to water detection.

Thank you for any ideas
 

oracacle

Senior Member
I used something similar to detect a water balloon burst.
My apparatus has a 2M resistor from an analogue pin to ground and the wires between 5v and the analogue pin. Then a comparator interrupt is set to detect a small change in the ADC value.

You may also want to experiment it something like an atTiny85, it can be programmed from the Arduino environment too. I used one not nlong back to modify an xbox one controller.
 

MGU

Senior Member
Hello

try a capacitive detection

Code:
MM 04/01/2018 fuite eau
#picaxe 08M2
#no_data
    do
        touch16 C.4, w13        ;mesure de capacité
        serout C.1,T2400, (254,128,"w13= ", #W13,"    ") ;visu valeur retournée sur LCD
        if w13>10000 then        ;seuil allumage LED
            high C.0                ; on allume
        else
            low C.0                ;on éteint
        endif
        pause 200                ; pour se reposer un peu
    loop                            ;on boucle
23820

MM
 

AllyCat

Senior Member
Hi,

I don't understand your diagram with the ADC input pin connected to +5 volts?! However, measuring the "resistance" of water has numerous issues:

Firstly, "pure" water is almost an insulator, so you are dependent on the presence of (unknown) impurities. Secondly, the PICaxe ADC has a "capacitive" input, but uses a sample-and-hold stage, so Microchip recommends a source resistance to the input of less than 10k ohms. The water (and that 1 Mohm resistor) are likely to be much higher than 10k ! That said, the (Microchip) PICaxe ADC and the (Atmel) Arduino ADC should be broadly similar, so I would expect the PICaxe to work as well as the Arduino, if appropriate optimisations are applied.

However, the PICaxe "Touch" capacitive sensing module (CPS) should be able to give much better performance with simpler and more reliable hardware. Water has a high (but complex) "dielectric constant" (which determines the change in capacitance). Note that the sensing conductor MUST be insulated (which will also assist corrosion issues) and you will need to use the TOUCH16 instruction, or even direct SFR commands. For better reliability, you also might need "Wet" and "Dry" probes to compensate for temperature and voltage variations, etc., but note that the PICaxe Touch channels are still not completely "balanced".

Cheers, Alan.
 

Aries

New Member
I don't understand your diagram with the ADC input pin connected to +5 volts?!
I thought the same - however, if you cut and paste the original "diagram", the ADC connection is on the water side of the resistor. When it is posted, the position of the connection moves to the left. If you embed it in CODE, the connection goes far to the right!

Code:
GND ------------------------------------> Water

+5v -----1Meg-ohm resistor-----------> Water
                                              |
ADC Pin <----------------------
 

hippy

Senior Member
I think it's intended to be something like this ...
Code:
5V >----.
       .|.
       |_| 1M
        |
ADC <---^--------.     .------.
                 |     |      |
             |  _|_    |   |  |
             |---------|---|  |
       Water |         O   |  |
             `-------------'  |
                              |
0V >--------------------------'
 

mrm

Well-known member
I used something similar to detect a water balloon burst.
My apparatus has a 2M resistor from an analogue pin to ground and the wires between 5v and the analogue pin. Then a comparator interrupt is set to detect a small change in the ADC value.

You may also want to experiment it something like an atTiny85, it can be programmed from the Arduino environment too. I used one not nlong back to modify an xbox one controller.
I think it's intended to be something like this ...
Code:
5V >----.
       .|.
       |_| 1M
        |
ADC <---^--------.     .------.
                 |     |      |
             |  _|_    |   |  |
             |---------|---|  |
       Water |         O   |  |
             `-------------'  |
                              |
0V >--------------------------'
Much nicer! In fact they are topologically the same had the vertical bar not slipped to the beginning of the line but thank you for the diagram which I will copy into the code.
 

mrm

Well-known member
I thought the same - however, if you cut and paste the original "diagram", the ADC connection is on the water side of the resistor. When it is posted, the position of the connection moves to the left. If you embed it in CODE, the connection goes far to the right!

Code:
GND ------------------------------------> Water

+5v -----1Meg-ohm resistor-----------> Water
                                              |
ADC Pin <----------------------
Hippy's diagram formats correctly and displays the working version of the circuit used on the working Arduino application.
 

mrm

Well-known member
Hi,

I don't understand your diagram with the ADC input pin connected to +5 volts?! However, measuring the "resistance" of water has numerous issues:

Firstly, "pure" water is almost an insulator, so you are dependent on the presence of (unknown) impurities. Secondly, the PICaxe ADC has a "capacitive" input, but uses a sample-and-hold stage, so Microchip recommends a source resistance to the input of less than 10k ohms. The water (and that 1 Mohm resistor) are likely to be much higher than 10k ! That said, the (Microchip) PICaxe ADC and the (Atmel) Arduino ADC should be broadly similar, so I would expect the PICaxe to work as well as the Arduino, if appropriate optimisations are applied.

However, the PICaxe "Touch" capacitive sensing module (CPS) should be able to give much better performance with simpler and more reliable hardware. Water has a high (but complex) "dielectric constant" (which determines the change in capacitance). Note that the sensing conductor MUST be insulated (which will also assist corrosion issues) and you will need to use the TOUCH16 instruction, or even direct SFR commands. For better reliability, you also might need "Wet" and "Dry" probes to compensate for temperature and voltage variations, etc., but note that the PICaxe Touch channels are still not completely "balanced".

Cheers, Alan.
Hippy's diagram is the better one as the vertical bar connecting to the ADC pin does not come out in the correct position and so the circuit makes no sense.

In fact in the working version of the setup (the Arduino controls a relay) the detection point does drift and needs re-tuning from time to time. I guess the answer is in the resistance requirements.
 

mrm

Well-known member
I used something similar to detect a water balloon burst.
My apparatus has a 2M resistor from an analogue pin to ground and the wires between 5v and the analogue pin. Then a comparator interrupt is set to detect a small change in the ADC value.

You may also want to experiment it something like an atTiny85, it can be programmed from the Arduino environment too. I used one not nlong back to modify an xbox one controller.
I had considered the atTiny85 and have one already setup to replace the full size Arduino. The reason for favouring the picaxe was that atTinys and i2c never seem to work for me whereas the picaxe plays very nicely with i2c and the code to setup the the tuning parameters using an i2c rotary encoder has already been written and proven for the picaxe.

Does your working apparatus use a picaxe or atTiny?
 

mrm

Well-known member
Hello

try a capacitive detection

Code:
MM 04/01/2018 fuite eau
#picaxe 08M2
#no_data
    do
        touch16 C.4, w13        ;mesure de capacité
        serout C.1,T2400, (254,128,"w13= ", #W13,"    ") ;visu valeur retournée sur LCD
        if w13>10000 then        ;seuil allumage LED
            high C.0                ; on allume
        else
            low C.0                ;on éteint
        endif
        pause 200                ; pour se reposer un peu
    loop                            ;on boucle
View attachment 23820

MM
Interesting. Based on information from Allycat it looks like a resistive solution is never going to work so the capacitive route is the only one to take (or use an atTiny85 as suggested by oracacle).

Thank you for this code and the excellent circuit diagram which I will try out.
 

AllyCat

Senior Member
Hi,
... it looks like a resistive solution is never going to work
IMHO a resistive method is not going to work reliably (so I would use a capacitive method), but you should be able to get something from it. In what way doesn't the PICaxe ADC work, what (voltage) value(s) is it reporting?

The Microchip data sheet does say that you can use a source resistance of higher than 10k ohms (which you clearly have) by connecting a capacitor from the ADC input pin to Ground (but it doesn't indicate how much higher a resistance is acceptable). A capacitor of around 100 nF would probably be best, avoiding electrolytics which can be "leaky".

Cheers, Alan.
 

inglewoodpete

Senior Member
A few points:
  • I don't think the so-called capacitive solution will work with water. In my experience using the "Touch" command, the input pin must have DC isolation. The "Touch" command might only work when the electrode was within a few millimeters of the water and would stop working as soon as it touched the water.
  • I don't understand why a 1 Mohm resistor is necessary. I would experiment with two 316 stainless steel electrodes. Alternatively, try several stepped electrodes.
  • Has anyone tried ultrasonic distance measuring with liquids?
 

AllyCat

Senior Member
Hi,
Water has a high (but complex) "dielectric constant" (which determines the change in capacitance). Note that the sensing conductor MUST be insulated (which will also assist corrosion issues)
1. Yes, as I wrote in #3 (perhaps I should have specifically said "insulated from the water"). Ceratinly, I'm thinking in terms of an insulated wire dropped into a metal tank (earthed), or two insulated wires / rods with carefully controlled spacing (anyone remember the old "balanced 300 Ohm" aerial (antenna) cable used for FM radios ?) .

2. Are you referring to 1 Mohm in a resistive or capacitive approach? The 1 Mohms is in the top of a potential divider (formed with the "resistance" of the water) that the ADC reads. I don't see what the PICaxe ADC could read without a voltage applied.

3. Yes ultrasonic level sensors have been discussed (even) on this forum. I think one of the issues is that it's probably being used in a (small) "enclosure" (e.g. a tank) so reflections (echos) can cause complications. Particularly in the case of a well, I believe that a LOW frequency audio solution was more successful, the column of air was set into resonance, like an Organ pipe, and the frequency measured.

Cheers, Alan.
 

The bear

Senior Member
@mrm,
Perhaps I've missed something? Is the object to detect water, or the lack of it.
I was thinking along the lines of a water level sensor, float or opto. distortion perhaps.
What does industry use?
Bear..
 

BillBWann

Member
I’ve simply used the chip’s pullup resistors in the past which has worked well for me. Besides simplifying the circuit, it also has the advantage that you can switch the current off when not actually taking a reading and so reduce corrosion of the probe.

Try out the following with your water detector probe connected to pin c.1 and note the change in value when the probe touches the water. As Alan says, pure water is an insulator but in my experience even rain water contains enough salt to give a significant change in the ADC value.

Code:
#picaxe 08m2
#no_data

do
    pullup %00000010
    readadc c.1, b0
    pullup %00000000
    sertxd (#b0,cr,lf)
    pause 1000
loop
 
  • Like
Reactions: mrm

mrm

Well-known member
A few points:
  • I don't think the so-called capacitive solution will work with water. In my experience using the "Touch" command, the input pin must have DC isolation. The "Touch" command might only work when the electrode was within a few millimeters of the water and would stop working as soon as it touched the water.
  • I don't understand why a 1 Mohm resistor is necessary. I would experiment with two 316 stainless steel electrodes. Alternatively, try several stepped electrodes.
  • Has anyone tried ultrasonic distance measuring with liquids?
The 1Mohm circuit is taken from something that works with the Arduino family of processors and seems to work on both SAMD and 328 series boards.

In practice it is reliable but the trigger value needs tuning based on the wiring setup, electrode type (which are marine grade 316 SS bolts) and initially was an emergency jury-rig to replace the commercial switch on a pump.

But the Arduino system actually works better that the original (I think ultrasonic) switch and subsequently another pump fitted with the same type of switch (cost about 60 Euros) has also started showing anomalous behaviour requiring something to watch over it.
 

mrm

Well-known member
I’ve simply used the chip’s pullup resistors in the past which has worked well for me. Besides simplifying the circuit, it also has the advantage that you can switch the current off when not actually taking a reading and so reduce corrosion of the probe.

Try out the following with your water detector probe connected to pin c.1 and note the change in value when the probe touches the water. As Alan says, pure water is an insulator but in my experience even rain water contains enough salt to give a significant change in the ADC value.

Code:
#picaxe 08m2
#no_data

do
    pullup %00000010
    readadc c.1, b0
    pullup %00000000
    sertxd (#b0,cr,lf)
    pause 1000
loop
Thank you for this idea.

It seems bizarre that something that works well on the Arduino (both Samd and 328) would not work on a picaxe although perhaps the electrical characteristics of the chip are different.

I have tried a range of resistors from 100k to 10M with no success. Allycat has provided a reason as to why this may not work.
The circuit can also be replicated using a simple multimeter and in practice the circuit will never encounter distilled water.

Will try this out when time permits and report back.
 

mrm

Well-known member
@mrm,
Perhaps I've missed something? Is the object to detect water, or the lack of it.
I was thinking along the lines of a water level sensor, float or opto. distortion perhaps.
What does industry use?
Bear..
The Arduino circuit was a jury-rig repair to replace a commercial ultrasonic switch.
But the Arduino system works so well that it has become permanent. But it seems a shame to have a full sized Arduino or even a micro sized board tied up when all that is needed is one adc pin on a 8pin chip which can be mounted on a small board and fit within the existing waterproof electrical control box. It is also not very convenient to have to reprogram the Arduino if the trigger value drifts which it does.
 

oracacle

Senior Member
It may be of some assistance if you can post pics or links with Arduino code to the project so we can better understand what the outcome needs to be.
There maybe something in the Arduino code that has been missed, say some hysteresis or something.
IIRC uno defaults to 10 bit ADC so maybe picking up very small changes that aren't seen on an 8 bit ADC.

As for signal drift. just a second ADC to compare the water measurement to. The water changes, then tweak a potentiometer to match.

another thing that has just popped into my head, is are the Arduino pins schmitt triggers, it that is the case, it may not even be using the ADC but the Schmitt characteristics of the input pin.
 

mrm

Well-known member
I’ve simply used the chip’s pullup resistors in the past which has worked well for me. Besides simplifying the circuit, it also has the advantage that you can switch the current off when not actually taking a reading and so reduce corrosion of the probe.

Try out the following with your water detector probe connected to pin c.1 and note the change in value when the probe touches the water. As Alan says, pure water is an insulator but in my experience even rain water contains enough salt to give a significant change in the ADC value.

Code:
#picaxe 08m2
#no_data

do
    pullup %00000010
    readadc c.1, b0
    pullup %00000000
    sertxd (#b0,cr,lf)
    pause 1000
loop
Yes this works well and is as simple as I expected it to be. Many thanks for this suggested solution.

On the Arduino version the program takes about 10 samples over 200 milliseconds and averages them to get a more stable reading. On the picaxe 08m2 this technique produces a very different ADC value than from taking a single reading.

However your solution certainly works and the single adc reading for the picaxe is not too dissimilar to the average reading from the Arduino given the same wiring and electrode configuration. Possibly the picaxe is already averaging over a period of time to arrive at its adc value.

Is there any reason why you use C.1as C.2 and C.4 are also shown as ADC pins?

Regards.
 

inglewoodpete

Senior Member
However your solution certainly works and the single adc reading for the picaxe is not too dissimilar to the average reading from the Arduino given the same wiring and electrode configuration. Possibly the picaxe is already averaging over a period of time to arrive at its adc value.
No. The PICAXE does a single read of the ADC channel. It happens in a few microseconds. so no time for multiple reads.
 
  • Like
Reactions: mrm

BillBWann

Member
Is there any reason why you use C.1as C.2 and C.4 are also shown as ADC pins?
Yes, you can use any pin with an ADC facility. Of course, if you want to make use of the pullup feature (and so not require the 1Mohm resistor), your selected pin needs to have that feature also - but that not a problem with the 08M2 as all those pins have both those features.

On the Arduino version the program takes about 10 samples over 200 milliseconds and averages them to get a more stable reading.
I don't see a need to average a number of readings but maybe you could take a second reading a few milliseconds later just to confirm your first reading wasn't a glitch of some sort. Unless you're dealing with extremely pure water, the difference in ADC value when the probe makes contact with the water is so great, that precise ADC readings just aren't required.

The resistance through the water can be further reduced (and so lower the flooded probe ADC reading even more) by increasing the wetted surface area of the probes. I've not ever required this but if you happen to have very pure water, the bottom of the probe could be bent at right angles so that it's parallel with the water surface. Then when the water level rises, it immediately covers a long section of probe and not just the tip.

On the picaxe 08m2 this technique produces a very different ADC value than from taking a single reading.
I don't see any reason why that should be the case for the 08M2 and suggest that you post your code for doing that.

Regards
 

Aries

New Member
On the picaxe 08m2 this technique produces a very different ADC value than from taking a single reading.
I don't see any reason why that should be the case for the 08M2 and suggest that you post your code for doing that.
The classic reason for this is using a byte variable to hold the total (of 8-bit ADC values) - it will almost certainly overflow if there are more than a few values.
 

mrm

Well-known member
Yes, you can use any pin with an ADC facility. Of course, if you want to make use of the pullup feature (and so not require the 1Mohm resistor), your selected pin needs to have that feature also - but that not a problem with the 08M2 as all those pins have both those features.



I don't see a need to average a number of readings but maybe you could take a second reading a few milliseconds later just to confirm your first reading wasn't a glitch of some sort. Unless you're dealing with extremely pure water, the difference in ADC value when the probe makes contact with the water is so great, that precise ADC readings just aren't required.

The resistance through the water can be further reduced (and so lower the flooded probe ADC reading even more) by increasing the wetted surface area of the probes. I've not ever required this but if you happen to have very pure water, the bottom of the probe could be bent at right angles so that it's parallel with the water surface. Then when the water level rises, it immediately covers a long section of probe and not just the tip.



I don't see any reason why that should be the case for the 08M2 and suggest that you post your code for doing that.

Regards
With the Arduino it is definitely necessary to average several readings but with the picaxe a single reading gives a quite stable result.

Your original code used readadc which I changed to readadc10 with word variables but readadc gives sufficient precision.

I note your observations on the electrodes. The ones used in the working arduino version are 316 stainless steel washers mounted horizontally and positioned to detect rising water so perhaps this is the reason why it is necessary to average the reading over a short period of time rather than an instabilty of the adc readings.

Given that your concept seems essentially proven the next stage will be to make up a circuit board to test function and reliability over several weeks.
 

mrm

Well-known member
It may be of some assistance if you can post pics or links with Arduino code to the project so we can better understand what the outcome needs to be.
There maybe something in the Arduino code that has been missed, say some hysteresis or something.
IIRC uno defaults to 10 bit ADC so maybe picking up very small changes that aren't seen on an 8 bit ADC.

As for signal drift. just a second ADC to compare the water measurement to. The water changes, then tweak a potentiometer to match.

another thing that has just popped into my head, is are the Arduino pins schmitt triggers, it that is the case, it may not even be using the ADC but the Schmitt characteristics of the input pin.
Thank you for these helpful suggestions.

In fact with the help of the forum members the solution seems to be essentially found.

Not sure how to post a round of beers to all the forum members who have helped on this but I now have a very happy consignment of picaxe 08m2's which can be put to work.
 

hippy

Senior Member
The main reason I could see for taking multiple readings and averaging is if the water were sloshing about and one wanted to be more certain the tank were filled to level rather than just being sloshed around.

Also, with a 1M pull-up and the high resistance of water, charging the internal sampling cap could be slow and consecutive readings will make that a more accurate reading of how things are. The author might not have appreciated that but found that averaging resolves the issue.
 

BillBWann

Member
The ones used in the working arduino version are 316 stainless steel washers mounted horizontally and positioned to detect rising water.........
By using the pullup command and restricting readings to every few seconds, I’ve found that fancy stainless steel probes aren’t required. Some years ago as part of a domestic water use study, I used this technique to count the number of times that toilets were flushed. For that project, the units were powered by a single AA sized LiFePO4 battery and simply used a pair of twisted wire wrap wires hung over the side of the toilet cistern with bared ends placed a couple of inches below the top water level of the cistern. The 08M2 spent most of its time sleeping and simply woke to check if the water level had dropped below the ends of the wires and if so increment a counter. These very thin wires showed no visible signs of corrosion after being in place under the water for more than a year.
 

lbenson

Senior Member
simply used a pair of twisted wire wrap wires hung over the side of the toilet cistern
Now there's a thought. I have wanted to put a DS18B20 in a freezer, but worried that the wires would disturb the seal. The tiny wire wrap wires I have should not cause a problem.
 

mrm

Well-known member
By using the pullup command and restricting readings to every few seconds, I’ve found that fancy stainless steel probes aren’t required. Some years ago as part of a domestic water use study, I used this technique to count the number of times that toilets were flushed. For that project, the units were powered by a single AA sized LiFePO4 battery and simply used a pair of twisted wire wrap wires hung over the side of the toilet cistern with bared ends placed a couple of inches below the top water level of the cistern. The 08M2 spent most of its time sleeping and simply woke to check if the water level had dropped below the ends of the wires and if so increment a counter. These very thin wires showed no visible signs of corrosion after being in place under the water for more than a year.
The reason for using thicker wires was based on the Arduino variant of the project where it was noted that thin wires did not work very well as the sensing electrodes were about 1.5 metres away from the Arduino board since they had to run through a specific path using a pre-existing cable track and holes.

The picaxe version does seem to give more or less the same result with thinner wires although I cannot test it in an exactly equivalent environment at the moment but after a few days of test running your solution is working well and giving consistent results with a single readadc so it seems that the 'simple water detection circuit for picaxe' problem is solved.

Unfortunately the project is not completely finished as pin C.0 is refusing to behave nicely and flash an led properly with water detection successfully moved to C.4 and C.1 / C.2 used for i2c. There is an antique forum post on this topic (https://picaxeforum.co.uk/threads/picaxe-08m2-and-c-0-out.19980/) but this does not obviously answer a periodic weak blinking with a led on C.0 although the led blinks at full strength when expected. This occurs even with the programming circuit removed. Did your own finished project encounter any such issues?
 

mrm

Well-known member
Post your code. Are you using SERTXD? That uses pin C.0, and if interspersed, will confound your settings of the LED.
Yes sertxd is there to report the value from readadc.

I thought it was coming from resetting the pullup but sertxd is the most likely cause and this can be easily tested.

Otherwise the code functions well as is and is already at work as a stand-in for a float switch which cannot be obtained due to the current restrictions.

The code is as BillBWann's original post:

#picaxe 08m2
#no_data

do
pullup %00000010
readadc c.1, b0
pullup %00000000
sertxd (#b0,cr,lf)
pause 1000
loop

with the addition of a loop counter and a switch detection on pin C.3 to end the loop gracefully and then do a reconnect so that a hard reset is not necessary for subsequent reprogramming. There is also a LED driven from pin C.4 which is normally low unless no water is detected.
 

mrm

Well-known member
Post your code. Are you using SERTXD? That uses pin C.0, and if interspersed, will confound your settings of the LED.
Thank you for your helpful input. Unfortunately I cannot access the computer and code right now and have reverted to BillBWann's original code except as described in my longer post.

His solution is now doing a real life field test due to an unexpected failure of a float switch since my initial post and query.
 

mrm

Well-known member
Post your code. Are you using SERTXD? That uses pin C.0, and if interspersed, will confound your settings of the LED.
Have now tried removing the sertxd and everything works exactly as expected. Thank you for this useful tip which is also a valuable piece of knowledge for any future projects.
 
Top