Arduino nano interrupts problem

Hello to everyone!

I write this post, as a last chance, after days and hours of struggling with a problem I can't find a solution for, and I don't know how to fix it (even if I found similar problems on this forum, none of them works, or fits to my particular situation.

I've attached a rain gauge (bassicaly a reed relay) to an Arduino pin2, to detect rain, using interrupts.
The problem is that, all this setup, is near (30-40 cm) to a watterpump (hydrofore) and when this pumps turns on or off, sometimes (but not all the times) false interrupts triggers.

Now, I will write the test that I've made:

  1. First of all to eliminate the possibility of noisy power supply, I powered the arduino from a 5V externall battery pack.
  2. With cable from rain gauge, disconnected, the problem dissapear. (Even if i put the PCB with the arduino directly on the chasis of that waterpump. This means that, the rain gauge wire gets some sort of noise that triggers the interrupt.
  3. After this, I changed the unshielded cable from rain gauge, to a shielded one (not twisted pair), grounded the shield to earth, but the problem still remains.
  4. Tried lots of other position of the arduino / and the wire from rain gauge, as far as I can from waterpump, some with better results, some not, but the problem its still there.
  5. Tried to wire pullups resistors of many values, and a 0,01uF capacitor to pin2 but none of them helped.

I will show you the two schematics I've tryed so far, and the code for the interrupt routine.
I even try this with an ESP32 dev board, interrupt pin 34, but with the same results.

I found a sketch here, that basically "filters" the noise from software...but, it runs very fast in the loop, and the MCU should listen to that all the time.... not applicable to me, sincer I run other things in the loop (I use Blynk app, and the loop has about 1.5 sec). Thats why interrupts are for..no?

Bellow I will show you the code (the ISR routine, I I need to, I can show all the code, but I think it is irelevant) and the rain gauge schematics.

#define Bucket_Size 0.3          // rain bucket size  (0.3mm)
#define RainSensorPin 2            

void setup()
{
       attachInterrupt(digitalPinToInterrupt(RainSensorPin), isr_rg, FALLING);
}

void isr_rg() {

 if((millis() - contactTime) > 30 ) { // debounce of sensor signal - I also tryed here many values from 30 to 800.
    tipCount1h++;
    tipCount24h++;
    contactTime = millis(); 
  }
  }

Thanks in advance for any help.
Adrian.

Why are you using ultra-fast interrupts for a slow rain gauge switch. That's asking for trouble.

Use a 100n ceramic capacitor from pin to ground (to kill RF and reed bouncing) near the Arduino pin,
use twisted pair between Arduino and gauge (cat-5/6),
and read the pin with every loop (polling), and count the pin changes (for double the precision).
Leo..

I've attached a rain gauge (bassicaly a reed relay) to an Arduino pin2, to detect rain, using interrupts.

Why use an interrupt for this when you could do it by polling the input pin and use debouncing code to eleiminate any false inputs for a short period ?

Hello!

Thanks for your really fast response.
I used interrupts since in this way I saw many sketchs involving arduino weather station, that rain is read in this manner.

I am not sure what you mean by reading the pin with every loop... like a classical read of pin using digitalRead(2)? with no use of interrupts anymore? If this is the case, tell me what happens if rain gauge triggers in a moment where arduino is not listening to the input ? It will be a missed catch ... or not????

A piece of code for this and for debounce will help me to try your sugestion asap!

Thank you!

The loop takes (should take) milliseconds to complete (and start again).
If you expect your rain gauge to flip thousands of times per second, then yes, you need interrupts.

Just look for changes to the state of the pin with every loop.
There might be thousands, or even millions of loops before the pin changes.
Then increase a counter and remember the new state.

Study the StateChangeDetection example in the IDE.
Leo..

Maybe you didn't catch it, but I mentioned that my loop takes about 1.5seconds to complete, since I am using Blynk. So there is plenty of time where the MCU can't catch the pin change...

How often is this bucket tipping.
Do you really have to catch the pin changing, or just when that pin has changed.

1.5sec loops seems very slow.
Leo..

No, I don't want to catch when the pin changed, (it is not important when) but it is very important to catch IF the pin changed, (EVEN IF the MCU is busy doing other jobs) and IF so, I want to increment two variables. Thats it!. Sounds simple! So is this possible without interrupts ?
Could it be done that easy, and I spent days and hours with interrupt noise? I can't believe it!!!

So ?

PS: The rain gauge triggers often only when I turn a glass of watter on it (that trigger the reed relay once about 1-2 sec) but this scenario is not intended to happen. God forbid of that amount of rain. It is impossible. So, it triggers preety rare, but when it does, it is important the MCU to know that.

Thanks!
Adrian

If the loop is shorter than the interval of that bucket tipping, then you have got nothing to worry about.
Leo..

No, it is not... the loop has about 1,5 sec.. the tipping happens very quick...
So, there is no technique to make arduino knows IF a pin changed, if the MCU is not reading that pin right in that moment of tipping?

adiculiniute:
No, it is not... the loop has about 1,5 sec.. the tipping happens very quick...

Not sure if you understand.
What is important is the time between two bucket tips.
That has to be longer than the loop time.
Leo..

ohh!!

The time between two bucket tips is much much longer than loop time. It depends on how heavy the rain is, but as I said before, It's impossible to rain that much, it has to rain more than 0.3 L/second, which is out of discussion.

So, give me a starting point for this... how should the code looks like? How can I count that change of pin ? or how exactly the code should work for this?

Thanks.

adiculiniute:
So, give me a starting point for this... how should the code looks like?

I did.
Last line of post#4.
Leo..

Ok, let me give you more precise info about this rain gauge, Ilustrated in the link bellow:
Rain Gauge

So, the principle is simple. It has just one switch (reed relay). Everytime the lever switches the position (in the left, or in the right, doesen't matter) the switch triggers, and arduino must count, 1 trigger means 1 tipp * 0.3 L/square meters. If I miss a tipp, the measurement is not accurate anymore.

So, you still claim that this can be done without interrupts, KNOWING that I have a slow loop(). ???

Maybe now the problem is more clarified.
Thanks.

I would use a low value pull up or pull down resistor ( 1k?) on your interrupt pin or use an opto coupler on it to reduce noise .
I take it the 0v line of the Arduino is connected to the other side of the reed switch . Connect your screen to the 0v at one end only .

Try altering the interrupt condition to LOW to see if it makes a difference ? ( clutching at straws and might require some code changes )

Always detect the two states/positions, or the two changes.
That doubles the resolution.

A lower pull up resistor value certainly helps, but it also uses more (battery) power.
This is a slooooow switch (for a processor), so a 100n ceramic capacitor from pin to ground, close to the pin, should be the better solution.
Leo..

Tried with 1k resistor already, and the 100n is soldered on the PCB near the PIN, but unfortunately this does not resolv my problem.

I want to try "hammy" suggestion for using a optocuplor, but since I am let's say, "newbie" in electronics, I understant a lot, but this kept me awake this night... beeing unable to wire it correctly ( I guess)

I will draw a schematic, right away, and please tell me where I am wrong.

Thanks!

I am attaching the schematic with opto.

So, my logic is simple.. you tell me where I am wrong.

The GND from arduino is interrupted by the rain gauge. When the rain gauge switches, it will complete the circuit, so the opto gets power and send the signal from ping 3 (emitter) to pin 4 collector (wired to pin 2 to get an interrupt).

So this does not work. I did not get any interrupts. Maybe, just maybe (the opto may be broken after a few faulty tries... I remember I put directly 5V to pin 1, wich somehow triggered a short and the whole power cuts off. (maybe I broke it, because there is a led there, and leds are not supporting 5v directly...) So this is why i put a resistor there. But after a few measures, the emitter and collector does not tie up.

So, I will take a new opto, to test again... but I want to know for sure If it is wired correctly (I dont want to broke another one).

Thanks!

optocup-schematics.png

Just connect pin3 (emitter) of the opto to Arduino ground, and pin4 (collector) to D2.
NO resistor on the transistor side of the opto.

Make sure you have pull up enabled on that pin in setup().
pinMode(2, INPUT_PULLUP);

As hinted before, set interrupts to CHANGE, for double the counts.
So you get EVERY flip of the bucket.
Leo..

adiculiniute:
I use Blynk app, and the loop has about 1.5 sec

Definitely worth the question: why does it take that long? Doesn't sound right.