Noise Immunity, need help

For all who bothered to click into this thread, thank you for your time....

I have a dilemna in a present project, which I have chosen an Arduino as the control and data acquisition controller for. The environment of the circuit is very noisy, and I have a few of the digital I/O's running parrallel with a 4-conductor cable which drives a stepper motor. I do have the cables shielded, and the digital I/O's have their own shielded cable, and the stepper motor has its own. The shield wires for both cables are connected to earth ground. It is important that these lines run together, and they pass through an AMP connector at the outside of the enclosure. The earth ground passes through the AMP connector as well.

The symptom is that I am somehow coupling in noise when the stepper motor runs, which is triggering low conditions on digital inputs. I have used pull-up resistors on the digital input lines, to help the micro maintain a high until a switch pulls it low, despite the micro having internal pull-ups. When I meter the input while debugging, it is a solid 5.00V, but when debugging the I/O in code, I am somehow triggering a low condition. If a specific valve solenoid, outside the circuit's earth grounded metal enclosure, is cycled, the Ardiuno inadvertently resets.

I have tried using a 120VAC powered 5VDC supply to power the Arduino, directly to the 5V pin of the Arduino board, as well as a 120VAC powered 12VDC supply to the VIN pin of the board. I've tried using the same 5VDC supply on the AREF pin as well as using the Arduino's internal AREF. I'm using two of the Arduino's serial ports, one to communicate to a serial LCD display(powered by same 5VDC supply), and the other serial port to communicate to a serial dot matrix printer. I am using a MAXIM TTL to RS232 driver IC, and a B&B Electronics RS232 opto-isolator repeater between the Arduino and the display and printer, and both work great. I'm using an SPI 12-bit DAC for fine DC output control, no problems there either. I'm controlling five 24VDC air valves with 5 different digital outputs, using opto-coupled solid state relays and as far as I can tell they never mis-fire. I'm taking analog inputs on 2 mass flow sensors and an air pressure transducer, and all 3 sensors are isolated with DC-DC isolators, and I get stable readings. And I'm controlling a stepper motor with a PWM output, using a simple purchased stepper motor driver and it works fine, with the exception of the noise it must be coupling into a couple digital inputs.

I'm a little new to noise immunity strategies with these boards. I've never seen such fragile operation of the Arduino like this before. I'm not sure what is the best way to snub out these inductive spikes that a coupling into the digital inputs and/or the reset pin. Can someone please refer me to a circuit diagram of a proper power supply configuration for the Arduino, which maximizes on noise immunity, as well as the best component configuration(inductor, diode, capacitor, etc.) which could be added to my digital inputs? Is there a way to make it impossible to reset the controller except through code? Are there conflicts that can occur by utilizing so much of the board's I/O capabilities? Can these conflicts be fixed in code(ie turning off serial port after each communication)? Are there digital inputs that are more or less immune to noise or resource conflicts? Can I possibly have a grounding issue going on? I do have the grounds to the 5VDC power supply and the 24VDC supply connected. Could that be the issue? Again, the symptom only occurs when high inductive motors or solenoids are activated.

You people are great. Again, thanks for your time. :slight_smile:

How long are the cable runs? Are you connecting the digital ground to the motor ground at more than one point?

MarkT,

Thanks for the quick reply.

From the outside of the enclosure, the stepper motor cable and the digital input cable are about 3 feet long. They both pass through the enclosure wall, through an amp connector, and the motor cabling is about 8 inches to the stepper controller, but the digital input lines are channeled up through some wire-way and approximately another 2 feet in length to the Arduino. The motor cabling inside the box are shielded and have the recommended magnets around cabling as well. I've done all I can do as far as the motor cabling, I'm afraid.

The digital input lines inside the box are not shielded. Shielding them INSIDE the box may help. Hmmmm....

That will probably be my next move. Thanks. We'll see if that works tomorrow.

The way to tame such cross talk is to shield everything from a single common point of ground. If you ground at both ends of cable runs then the heavy currents in the motor wiring induces voltage spikes on its ground shield and this current flows down the signal ground as well (completing a ground loop) - this then couples to the signals.... In audio systems you get hum from ground loops (but only at low amplitudes since only wiring resistance is involved)

In high speed logic circuits the inductance of the ground wiring dominates and the effect is much worse. People usually deal with it by using differential line drivers for long digital signal runs (USB, ethernet, etc all do this), but a common single ground might help (although often equipment is grounded in each 'box' for safety.

Another approach is to deliberately slow down the logic signals by adding an RC low pass filter followed by schmidt trigger - this reduces the amplitude of induced spikes at the expense of data rate.

You may also have a lot of noise from the motor itself - decoupling the motor itself may help (only a small capacitor across the terminals - just to reduce radio frequency noise from the commutator)

I'd also just run the logic separately from the motor wiring...

OK, I spent nearly all day trying to resolve this issue and getting consistent results from this project.

I finally had to come to terms and realize that I have done all that I can do to shield the cabling and help the Arduino hold up these digital lines. The resolution had to be a digital filter on the lines getting affected.

As soon as the erroneous low trigger occurs....

void high_to_low_triggered_Subroutine();
{
delay(10);
if (digitalRead(noisyLine) == HIGH)
{
return;
}
else
{
carry on, because it was no false trigger.......
}
}

This was the scheme I used, and it was very effective with relatively no ill effect on the operation.

Again, thanks for your feedback.