Correct usage of optoisolator for noise immunity on unshielded connections

eetech00

Joined Jun 8, 2013
3,951
Hi everyone,
I have a small CNC machine and the limit switches (normally closed) are getting false triggers from the stepper motor wires that run inside the same cable trunking. None of the wires are shielded of course.

What's the best way to filter this noise? Current controller is an Arduino GRBL shield. Another controller is on its way, but I would like to solve this induced noise problem.

My first thought was an optoisolator, but as far as I can tell, I would need to add a completely separated power supply otherwise there would be a shared ground connection - that would negate the point of an optoisolator, right?

Otherwise, perhaps I could add a capacitor (value? series/parallel?) to filter the input? Since it's just a 5v DC on/off signal coming from the limit switches, maybe this could work, too?

Any help would be greatly appreciated!

All the best,
Dax Liniere.
The device you posted is not an NANO. It is a UNO.

Did you write the programming of the UNO? If so, did you include switch debounce code?
The false triggering may be related to bounce noise from the limit switches.
 

drjohsmith

Joined Dec 13, 2021
852
I am thinking that adding a low resistance pull-up resistor will not eliminate the noise problem.

I have built my own CNC machine from scratch and made a point of using shielded cables on the limit switches.
Also, the controller input uses opto-couplers which sense current and not voltage.

In your case, the limit switches are normally closed to GND. The unshielded cables are picking up EMI which is seen as a voltage going above the logic threshold voltage at the input pin of the ATmega328. We can assume that the signal has to rise about Vcc/2, that is above 2.5V to register as a fault condition. Adding a pull-up resistor will only make this worse. What we need instead is low impedance termination to GND.

So, what can we do to remedy your situation? Perhaps a capacitor to ground might help but you will still need a pull-up resistor in order to present a low RC time-constant otherwise the fault condition will not be recognized in a timely fashion.

Would an extra board with opto-couplers on the inputs be an acceptable solution for you?
@MrChips

can you draw a diagram please
My reading is were saying a low resistance to ground,
but the switches are to ground,

To all
in general I find it easier to understand a diagram,
even a hand drawn one ,
 

MrChips

Joined Oct 2, 2009
30,810
TS has something like this.

Arduino - Limit switch.jpg
There are a number of issues.

1) The cable is very long, unshielded and running along side digital switching cables.
2) The input at the Arduino is high impedance, 20k-50kΩ.

Yes, the signal wire is grounded at the switch. However, the program code is receiving false positives.
 

djsfantasi

Joined Apr 11, 2010
9,163
My question is how the other wires to the CNC machine are routed?

Are both of wires to the limit switches twisted along their run? This would help eliminate any noise since these wires are not shielded.

Secondly, are the control wires to the stepper motors also not shielded and are they physically separated from the limit switch wiring? Or (I hope not), are they run in a bundle with the stepper motor wires? Somewhat related, what voltage/current do the control wires carry?
 

MrChips

Joined Oct 2, 2009
30,810
No, it's GRBL and NC switches don't need debouncing because they're breaking, not making.
This is not correct. NO and NC switches both need debouncing when required.

In your case there is no need for deboucing because they are limit switches. It does not matter if the switches bounce. The MCU should be using the limit switches to detect the first change in switch condition. It doesn't care if it bounces for the next 100ms.
 

Thread Starter

daxliniere

Joined Aug 7, 2021
52
The wire I used is single lengths of silicone sheathed wire with lots of fine conductors. This makes for a very flexible cable which I thought was a good idea considering that when I was given the CNC, the cables running to the steppers (through the constantly-moving cable trunking) all had some repairs done to them where a new wire was cable-tied to the trunking and soldered to each end to replace dud cores in the 4-core.
I can pull them all out again and add a shielding braid, but that's a ball-ache I was hoping to avoid, plus I'd have to wait for the braid to arrive. I figured a few passive components should be able to solve it quickly... haha

Incidentally, GRBL does have debounce for all switches in the code already. You can even specify the debounce time by sending the relevant g-code at the terminal command line.
 

Thread Starter

daxliniere

Joined Aug 7, 2021
52
Are both of wires to the limit switches twisted along their run? This would help eliminate any noise since these wires are not shielded.
See above, not twisted.

Secondly, are the control wires to the stepper motors also not shielded and are they physically separated from the limit switch wiring? Or (I hope not), are they run in a bundle with the stepper motor wires? Somewhat related, what voltage/current do the control wires carry?
Yes, they're not shielded either and they run inside the same articulated cable trunking.
Voltage is 24v, current is about 2A with the steppers I have now, but will be closer to 3.5A when the new steppers arrive.
(The wire is 22AWG, so plenty enough for 3.5A)
 

djsfantasi

Joined Apr 11, 2010
9,163
See above, not twisted.


Yes, they're not shielded either and they run inside the same articulated cable trunking.
Voltage is 24v, current is about 2A with the steppers I have now, but will be closer to 3.5A when the new steppers arrive.
(The wire is 22AWG, so plenty enough for 3.5A)
Twist the wires to the limit switches. This means you need an individual ground wire per switch.

Add separate “cable trunking”. That is, Group the wires together and run them with a physical separation from the motor wires.

Or…

Wire the limit switches with a 3-4 twisted pair shielded cable, again physically separated from the stepper motor wires.

Motor noise is being transmitted to the limit switch wires.

I had the same problem with limit switches and RC servos.
 

drjohsmith

Joined Dec 13, 2021
852
TS has something like this.

View attachment 262150
There are a number of issues.

1) The cable is very long, unshielded and running along side digital switching cables.
2) The input at the Arduino is high impedance, 20k-50kΩ.

Yes, the signal wire is grounded at the switch. However, the program code is receiving false positives.
Thanks @MrChips
I was asking abput the idea you commented about a low value pull down resistor,
as to how that would work,
 

drjohsmith

Joined Dec 13, 2021
852
The original machine didn't have limit switches, but I wanted to add them since I've made a lot of the other upgrades.
Thanks for the pictures
what a great machine

Your picking up false signals,
this is likely due to a few problems
a) pickup due to the high impedance inputs and the high noise environment
b) switch bounce


The opto idea of #44 by @MrChips
fixes the (a)
place the opto by the uno,
then all the long wires are low impedance, so low noise pick up
twisted pairs will make this even safer.
and the 0.6v threshold of the Arduino is satisfied

for (b)
the arduino library debounce is very effective,
https://www.arduino.cc/reference/en/libraries/bounce2/
 

MrChips

Joined Oct 2, 2009
30,810
I was asking abput the idea you commented about a low value pull down resistor,
as to how that would work,
The signal wire is grounded at the limit switch (the far end of the cable).

At the controller, the input impedance is 20k-50kΩ. Hence there is almost no termination of the long cable to absorb any EMI picked up along the wire.

If we assume an input threshold voltage of 2.5V, then a 50μA current pulse would trigger a false positive.
Input impedance of 100-500Ω to GND is effective at reducing any low current spikes.
20mA current loop is commonly used in applications such as this one.

Switch bounce is not an issue in this application.
 

drjohsmith

Joined Dec 13, 2021
852
The signal wire is grounded at the limit switch (the far end of the cable).

At the controller, the input impedance is 20k-50kΩ. Hence there is almost no termination of the long cable to absorb any EMI picked up along the wire.

If we assume an input threshold voltage of 2.5V, then a 50μA current pulse would trigger a false positive.
Input impedance of 100-500Ω to GND is effective at reducing any low current spikes.
20mA current loop is commonly used in applications such as this one.

Switch bounce is not an issue in this application.
@daxliniere , this is just a background chat,

@MrChips
Depending upon the Uno, if its a real one, and old type one or what
our experience is that the input voltage thresholds are "ttl" i,e, around below 0.6 v and above 2.5 v
and the pull up resistance is of the order of 50K

If we take your picture of #43, can you make a drawing of where the 100 - 500 ohm to ground resistor should go ?
If its across the switch, will that not make the Uno input always "zero", or worryingly, bias the input into the "cross over region" of the UNO input ?

@daxliniere
IMHO, I'd be looking at the opto isolator solution,
Opto paced by the Uno
with Switches connected by by twisted pairs,
( no need for screened, but would be nice )

Be careful with the 12V going to the switches,
Do not run that in the same cable as the switch wires,
a separate PSU, on the rig for the opto inputs is a good idea.

Re the pull ups on the Uno
these can be turned on or off,
and are of fairly high value
We would typically use external pull ups on the Uno inputs,
1 to 10K ohms , to the Uno's VCC would be typical,

And we automatically use debounce input code on all switches,
it adds very little to the Arduino code,
its an easy to use library
and it gives you nice clean switch inputs,

One other thing,
its easy to miss
do not use the wait() or such instructions in your code.
 

MrChips

Joined Oct 2, 2009
30,810
As drj says, this is just for discussion and thinking out loud.

I cannot see a reason why the Arduino got fried.
100Ω pull-up to Vcc would not kill a GPIO if it is always set to input mode.
Pullup to +12V would destroy the chip.
Enabling the GPIO in output mode would also kill the chip.

I can see that debouncing the input in software could alleviate the problem if the code only responds to sustained constant level. Debouncing code commonly waits for 50ms for the switch to settle. We would have to determine the impact of this long delay knowing the linear speed of the translation motor. The purpose of limit switches is to stop the motor dead in its tracks as soon as the limit is reached. This is a fault condition.

As for input threshold voltages, I am going by the Atmel ATmega328 data sheet.
At Vcc = 5V, high level threshold is 2.6V, low level threshold is 2.1V.

If we take your picture of #43, can you make a drawing of where the 100 - 500 ohm to ground resistor should go ?
If its across the switch, will that not make the Uno input always "zero", or worryingly, bias the input into the "cross over region" of the UNO input ?
In the picture, there is no proper place for resistor termination.
At the switch, the signal line is grounded.
At the Arduino, the input pin sees a very long antenna with 50kΩ input termination. It would be impractical to put resistor termination to GND at the input. The proper solution is to use an optocoupler.
 
Top