Interference on my digital input - suggested fixes?

I have a "garage door is open" detector set up in my garage, the circuit being like this:

There is a reed switch adjacent to the door, with a magnet affixed to the door. If the door opens the switch closes. There is about 15m of cable running to a power supply which powers a relay. The relay closes in sympathy with the switch. Then a short run of wire goes to the Arduino digital input. This is set to INPUT_PULLUP, to detect when the switch is closed.

The purpose of the relay was to isolate the Arduino from stray voltages in the long cable run.

Now all this appeared to be working fine for a couple of years. Plugged into the Arduino is an Ethernet board, and that was used to send notifications if the door was open (actually it responded to a query, so the notifications didn't happen in real time).

Now a couple of days ago I added an audible alert output, which sounds immediately the door is opened. This uncovered a problem (at 2 am) when the alert sounded unexpectedly.

Further testing showed that merely turning on the lights in the garage (a couple of fluorescent tubes) also caused the alert to sound.

It seems that despite the use of the relay, stray voltages were reaching the Arduino input, causing a false LOW reading. These appeared to come from turning on lights, or turning on a nearby hot water heater.

A temporary fix was achieved by wiring in a 0.1µF capacitor across the Arduino input (between pin 7 and Gnd).

However is there a better solution? Eg. a diode between pin 7 and +5v? Or another diode between pin 7 and Gnd? Or something else?

How about debouncing the pin with a fairly long interval - half a second? Presumably the real signal causes a LOW for quite a long time whereas the glitches are intermittent.

Pete

is the cable between the relay and arduino shielded ? if not, maybe it would help to use a shielded twisted pair

el_supremo: How about debouncing the pin with a fairly long interval - half a second? Presumably the real signal causes a LOW for quite a long time whereas the glitches are intermittent.

Pete

I've added in a 3-second delay, which certainly should eliminate short bursts. But I still wonder where these erroneous signals are coming from.

For example, would it be possible that the relay coils act as a sort-of transmitter, so when interference travels down the long wire, it crosses over into the Arduino side?

alnath: is the cable between the relay and arduino shielded ? if not, maybe it would help to use a shielded twisted pair

No it is isn't shielded.

I have a little trouble to explain in English (French will be easier :grin: )
I think you have parasitics gnd paths.
You can use a ferrite (like picture) and make several round with both useful mass and wires signal in the same direction .
For the useful signal (gnd+ Signal) there will be no inductance effect : as the gnd useful current is the same that the useful current signal wire magnetic field of each wire is canceled by the other wire.
The spurious network : parasistic gnd + signal) will see inductor so the parasistic effect is dramaticaly devrease.

ferrite.jpg

an analog solution may be the best the cap. can be ok (even 1uf) but i suggest you to put a resistor on the GND line just before the cap. and a pullup resistor to strenghten the arduino internal one of course use a pullup resistor like 7 times bigger than the gnd one (1k and 10k)

if i turn my PC's UPS on then i turn on\off my room's fluorescent tube the PC will boot :) :) there's no need to press the "on" button

The usual culprit is running wires in parallel #. How are the 50mm wires routed? Along the outside of a wall? Is it possible there are high voltage wires on the inside?

# In High School a fellow from Champion Spark Plugs provided a great demonstration. He began the demonstration with a very long ignition cable connected to a lawnmower engine. He started up the engine, folded the cable once so he had two sections running in parallel and then cut the cable at the fold. Only about 10cm in parallel was necessary to keep the engine running.

# I spent time troubleshooting an ethernet network in a factory. I came to discover the electrician had run 220, 440, and CAT5 through the same large conduit. I can say beyond any doubt that, despite the amazing common mode rejection of ethernet, long parallel runs with high voltage power cables stops all communications.

The run from the relay to the Arduino is just along a bench. 50 mm is not long. Admittedly the whole setup is near a power board.

sorry i didn't see the "50mm" on your scheme

50mm? Is that correct. The connection from the relay switch to the arduino is just 5cm long?

I think I'd be inclined to add an external pull up resistor. It doesn't sound like the internal one is doing it's job properly.

Huh. So much for my theory.

If it is convenient, disconnect the Arduino from the relay, at the relay, and switch the lights. Does the alarm still sound?

A temporary fix was achieved by wiring in a 0.1µF capacitor across the Arduino input (between pin 7 and Gnd).

However is there a better solution? Eg. a diode between pin 7 and +5v? Or another diode between pin 7 and Gnd? Or something else?

● No diode, capacitor or external pullup resistor required. Just 5cm of wire and optional 100Ω series resistor. ● Continue using INPUT_PULLUP for pin 7. ● Connect the wire from pin 7 to relay COM. ● Add the new wire from 5V to relay NC (could include a series resistor for short circuit protection). ● Connect the GND wire to relay NO.

Now pin 7 is normally at a solid 5V. When the door opens and the relay energizes, as the COM contacts transfer to NO, the INPUT_PULLUP will keep the signal high until it hits the NO contact which is at GND.

The contacts should have long life as they are not switching a capacitive load. Effects of noise should be completely eliminated.

Thanks for the suggestions. Based on an app note from DigiKey I made up the following protection circuit:

D1 and D2 are Schottky diodes designed to clamp the signal to no more than 5v and no less than 0v.
R1 protects the diodes from excess current.
R2 and C1 form a low-pass filter to smooth ringing effects.
R3 is a stronger pull-up resistor for the input pin.

Because of the value of C1, this circuit will have a slow reaction time# but that doesn’t particularly matter in the case of the door opening.

2.2RC which should be 2.2 * 1000 R * 0.0000001 F = 220 µS (I probably got that bit wrong).


@dlloyd - I’m not sure your suggestion will eliminate the interference, but I see where you are coming from.

Ground the relay chassis.

I don't have that option. The relay is a sort-of moulded plastic thing.

...in case you change your mind:

If for some reason, your relay is just showing it's age, I think an opto-isolator would be a good alternative.

dlloyd: If for some reason, your relay is just showing it's age, I think an opto-isolator would be a good alternative.

Good point. I must admit this is a bit of a "legacy system", first installed a few years ago before there was even an Arduino, and all the relay did was turn on a strobe light.

It had probably been picking up transient "door open" messages for ages, but since they probably only lasted a few milliseconds, no-one would have noticed the light flashing briefly.

It was only when the "improved" version activated a doorbell chime, that went off at 2 a.m. and we woke up saying "what the %^$&# was that!" that the flaw in the design was realized.

Good thing it was a false alarm!

Hmm, how is the reed switch / magnet alignment ... might be off a bit and just on the verge of closing the circuit and tripping the relay ... could also be a faulty reed switch.