I have a small project that involves an Arduino Uno controlling a 12V motor. I am getting spurious readings in the Arduino, and believe I have traced them to the motor running.
A test routine that does nothing but run the motor for a few seconds in one direction, and then a few seconds in the other while watching for stray readings will quickly detect them. But if I remove the fuse to the motor so that no current goes through the motor, the stray readings never appear.
I have snubber diodes in parallel to the relay coil, and to the motor (see diagram). I used a pair of Zeners on the motor because polarity reverses to change its rotation. On the relay snubber, though, I believe I have the 1N4007 diode in the wrong way, and that both diodes should have been put in the opposite way.
Am I correct about this? As shown, will the diodes suppress flyback voltage? Is it possible I am getting flyback voltage from both sources?
Zeners don't really work like the book says. A real zener can't carry a lot of current before the voltage across the zener goes up. Remove the 6V zener.
Zeners across the motor aren't going to help much. At the instant that the relay opens, the motor inductance wants to keep the current the same, so whatever amps were going through the relay are now trying to go through your zener. A TVS diode is like a more advanced version of a zener. They can carry lots of amps. But the main use for a TVS is suppressing electrostatic sparks, not just regular motor flyback current.
Change to using an H-bridge motor controller and don't use relays at all.
Yes, this motor draws ~200 mA under the load it deals with. Is there internal flyback control on the board? The one concern I have is that the motor has to stop rapidly -- it moves a door that trips a contact switch, and once that happens the power must be immediately shut off to the motor. (The problem I have been encountering is phantom HIGH readings from the contact switches.) Do I need to use the PWM feature to avoid generating flyback voltage?
The problem I have been encountering is phantom HIGH readings from the contact switches.
Are those switches properly pulled up or down when open. A 0.1uf cap across each switch will absorb a lot of noise, especially useful where the switch has long wires.
If the motor moves the fllyback voltage is generated when it is stopped. PWM may lessen the (average) amplitude but the flyback diodes are still necessary.
@groundFungus ... this brings me back to my current configuration. I don't have any capacitors on the contacts. When you say across each switch -- they have COM, NO and NC. How should the caps be connected? Also, if I have to use flyback control with the H-bridge card, would there be any advantage to it? The issue I'm struggling with now is is wondering if the flyback configuration is doing its job. It sounds like I have to get that answered either way?
Any decent motor driver module will take care of the flyback diodes.
How are the switches wired? Can you post a schematic? The caps would go from the Arduino input to ground. I would wire the switches the same, NO to an input and COM to ground and, in setup() enable the internal pull up resistor to hold the switch HIGH when open. The switch will read LOW when closed.
Even better, an H-bridge can apply passive or dynamic braking.
Here is a fun experiment: take any DC motor (brushed or brushless) which is not connected to anything and try to turn the motor shaft. Pretty easy, right? Now touch all of the motor wires to each other, as a short circuit. Try to turn it again. Massively more difficult.
That braking effect is easy to do with an H bridge.
@groundFungus, I am attaching a drawing of the switch wiring. Each input pin is defined with:
pinMode(pinID, INPUT_PULLUP);
Again, there are no phantom signals on the contact switches if the motor is not activated. I use a Grove 2-coil latching relay (https://www.seeedstudio.com/Grove-2-Coil-Latching-Relay-p-1446.html) to set the direction. The on/off relay is positioned in one of the two wires going to the motor.
If an H-bridge board such as the one sold by Adafruit can run the motor without having to add snubber diodes, I would want to go that route. However, for my own education, I'm still wondering about the diodes. Can the diodes in parallel to the relay coil really be placed either way if only one is a Zener, or does polarity matter? The motor is a different case since polarity changes with direction. Do a pair of Zeners back-to-back really not work on the motor?
How long are the wires from the Arduino to the switches? The longer the wires, the more noise that they will pick up. A solution is to use external pulups and reduce the values of the pullup resistors to provide a stronger pullup. The internal pullups are 30K to 50K, so pretty weak. Start at 10K and go down, not lower than 1K.
I don't know about the diodes. I just use drivers for my motors and for relays, 1N400x diodes.
MorganS:
Zeners across the motor aren't going to help much.
Certainly will help, it clamps the voltage spike to 16V in this instance which is going to be better than
unclamped.
Sizing a zener for this purpose is more tricky, you need to figure out the inductive energy and ensure the
device can soak that up in the timescale involved.
Interference from motors is not limited to inductive kick-back, you get RF EMI direct from the motor
brushes (ceramic capacitor across the motor terminals can help), and the high currents directly
radiate from the wiring (which is why twisted pair is a really good idea for all such wiring).
@MarkT, thanks for the feedback. I have done all those things -- twisted the wires, have 0.1 uF caps on the terminals and the zeners. I am hoping the problem is with the reversed diodes on the relay. I'm going to replace them and see what happens. If that doesn't work, the H-bridge boards will arrive in a day or two ...