Glad to hear you are getting some good reads, I am assuming you are pulling the pin low as you are reading Ground. If it was my project, I would for sure include some sort of time criteria as well, or take 100 samples per second and then use the average to eliminate false positives. Even better, use both. I would not rely one single readings, sorry of I was not clear enough
In my current sensor we are reading as many readings as possible each second, calculate average and then post the data.
Quick observation is that he seems to be pulling the pin HIGH rather than low. Tis might make more sense if you are reading low values even with only one pin submerged. If you pull it HIGH you should be able to easily discount any single value <2000 for example.
I am writing exams ons Friday, but will do my best to set up similar test on the weekend and report my finings.
I used it for 6 months and I did not have any false positives. I then used the hardware for another project and decommissioned it. I think thanks to this discussion I will put it back in service!
No extra hardware required (with Proton at least)
With 100k resister between A1 and ground. Use 2 wires from +3.3 and A1
analogRead(A1) = around 37, touching both wires gives around 140, clean tap water = 1800
pinMode(A1, INPUT);
water = analogRead(A1);
if (water > 500) // make this value lower for more sensitive or higher for less sensitive.
{ // water, water, everywhere!}
I use a plastic bottle cap sitting on a paper towel to monitor my basement floor.
I did something similar last year, but using an Arduino (Tiny85) to read the digital state, which would then power on the Argon to send an alarm.
Once the Tiny85 powers on the Argon via the EN Pin, you can have the argon do what ever you want, after running your code, you can then set a digital pin on the Argon High, which the Tiny85 reads to power the Argon off by setting the EN Pin low.
#include <avr/sleep.h>
#include <avr/interrupt.h>
const int PARTICLE_EN_OFF = 0; // Particle D6 connected to Tiny85 PB0
const int PARTICLE_EN_ON = 1; // Tiny85 PB1 connected to Particle EN
const int ALARM_INPUT = 2; // Tiny85 Digital Input to power on Particle and Publish Alarm
const int ALARM_OUTPUT = 3; // Tiny85 Digital Output Alarm Status - High or Low
void setup() {
ADCSRA &= ~_BV(ADEN); // Disable ADC
pinMode(ALARM_INPUT, INPUT);
digitalWrite(ALARM_INPUT, LOW); // When first powered on set Alarm Input Low
pinMode(ALARM_OUTPUT, OUTPUT);
digitalWrite(ALARM_OUTPUT,LOW); // When first powered on set Alarm Output(Status)Low
pinMode(PARTICLE_EN_ON, OUTPUT);
digitalWrite(PARTICLE_EN_ON, LOW); // Pulls Particle EN Low to Power Off on startup
pinMode(PARTICLE_EN_OFF, INPUT); // Input to read when to power off Particle
}
void sleep() {
GIMSK |= _BV(PCIE); // Enable Pin Change Interrupts
PCMSK |= _BV(PCINT2); // Use PB2 as interrupt pin - Powers on Particle when Alarm Input goes High
PCMSK |= _BV(PCINT0); // Use PB0 as interrupt pin - Powers off Particle when Particle D6 goes High
//ADCSRA &= ~_BV(ADEN); // ADC off
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // replaces above statement
sleep_enable(); // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
sei(); // Enable interrupts
sleep_cpu(); // sleep
cli(); // Disable interrupts
PCMSK &= ~_BV(PCINT2); // Turn off PB2 as interrupt pin
PCMSK &= ~_BV(PCINT0); // Turn off PB0 as interrupt pin
sleep_disable(); // Clear SE bit
//ADCSRA |= _BV(ADEN); // ADC on
sei(); // Enable interrupts
} // sleep
ISR(PCINT0_vect) { // This is called when the interrupt occurs
/*
*
*
*/
int ALARM_STATUS = digitalRead(ALARM_INPUT);
int READ_PARTICLE = digitalRead(PARTICLE_EN_OFF);
if (ALARM_STATUS == HIGH) {
digitalWrite(PARTICLE_EN_ON, HIGH);
digitalWrite(ALARM_OUTPUT, HIGH);
}
else digitalWrite(ALARM_OUTPUT, LOW);
if (READ_PARTICLE == HIGH && ALARM_STATUS == LOW) {
digitalWrite(PARTICLE_EN_ON, LOW);
}
}
void loop() {
sleep();
}
analogRead(A1) = around 37, touching both wires gives around 140, clean tap water = 1800
I might be misunderstanding something. How are you getting 140 when touching both wires? Shouldn't that be > 4000 and the clean tap water >37 but <4000?
I’d assume “touching” to mean skin contact/touching with fingers (“dry skin” resistance is higher than in water) not having the wires touch eachother (that would be difficult with the contacts shown in the photo)
I’m not sure if I’m doing something wrong or I have a bad chip.
I tried @ron7136 solution with two wires and the Argon on a breadboard. Wires are not touching and the values fluctuate low/high.
Here is the code:
int analogPin = A1;
int val = 0;
void setup()
{
pinMode(analogPin, INPUT);
Particle.variable("Volt", val);
}
void loop()
{
val = analogRead(analogPin); // read the input pin
Particle.publish ("val", String(val));
delay(1000);
}
My experience with the Proton says this is true when configuring the pin as “INPUT” but the “INPUT_PULLDOWN” does work but in my testing the 100k made it more sensitive.
Looking into the nRF52840 GPIO/Analog inputs, I discovered a couple of things:
The (digital) GPIO pull-up or pull-down resistance is “stronger” at 13K (typical) as opposed to the “weaker” 40K for the Photon.
Though there is no mention I could find of any pull-up or pull-down resistor for the Analog input mode, there are “pull-up” and “pull-down” LADDER resistors which are controlled via configuration registers:
These resistors have a typical value of 160K. However, I am not sure if these are activated in the DeviceOS as there is no mechanism in the commands to specify a pull direction. It seems to me that with a value of 160K, these are there to specifically allow the user to prevent the input from floating.
The GPIO and SAAC (analog input) configuration register are different and I doubt declaring a pin as digital input with pull-down will work when the pin is reconfigured for analog input mode.