5
\$\begingroup\$

I need to control a solenoid that requires 120 VAC to actuate. I’m powering an Arduino with a 5V power supply (directly into the 5V pin), and I want to use the Arduino to control a relay that will drive the solenoid. I found a relay G6DN-1A-SL DC5 that requires 22 mA for the coil current. Would an Arduino be able to drive this reliably? I know that I can easily wire up a BJT that could send the same 5V powering the Arduino to the relay, I’m just curious to hear recommendations.

\$\endgroup\$
3
  • 4
    \$\begingroup\$ Theres tens if not hundreds of different things that are called Arduinos, which one you are using? \$\endgroup\$
    – Justme
    Commented Oct 18, 2023 at 23:13
  • 1
    \$\begingroup\$ You could risk it if it's not so important (one-time hobby project). There is usually some safety margin anyway - they don't want the chip to burn out the moment you go to 20.01mA, because then natural variations mean a particularly unlucky chip could burn out at 15mA and they'd be in trouble. If they say 20mA, the absolute worst chips burn out above 20mA, which means the average chips can handle quite a lot more mA... in fact, sometimes people accidentally short-circuit their arduinos and they still work afterwards. But if you don't feel like pushing your luck, use the transistor design. \$\endgroup\$ Commented Oct 20, 2023 at 9:33
  • \$\begingroup\$ What is the total maximum current allowance for the bank of I/O ports you're using, and is there anything else drawing current from that bank? Also, a transistor may be less hassle to replace than an Arduino and reprogramming it if something goes wrong. \$\endgroup\$ Commented Oct 21, 2023 at 19:37

9 Answers 9

16
\$\begingroup\$

Directly driving a relay coil with an MCU is bad style, but if you combine it with another bad style element and use 3..4 port pins in parallel and take a Schottky diode as clamping element, you have a working solution for a private hobby project.

The Schottky diode conducts before the internal protection diodes and carries most of the pulse current.

The software must set and clear these port bits simultaneous in one write operation or this trial ends quickly.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I would not call the parallel solution bad style, especially if well implemented. This technique is used with FPGAs where synchronising IOs is trivial - on a micro this can also be done, with some caveats. \$\endgroup\$ Commented Oct 19, 2023 at 12:44
  • \$\begingroup\$ @VladimirCravero At least on an AVR. Not every microcontroller architecture has provisions for changing multiple GPIO pins at once. \$\endgroup\$
    – Hearth
    Commented Oct 19, 2023 at 15:29
  • 2
    \$\begingroup\$ Yep well the best approach would be to use GPIOs that can be controlled with one single write to one single register. If that is not possible, I would transition through highz, like off/off;off/hiz;on/hiz;on/on - you avoid shoot through but one of the ports is carrying all the current for a few clock cycles - this perhaps I would call bad style, or janky. \$\endgroup\$ Commented Oct 20, 2023 at 6:40
11
\$\begingroup\$

I recommend against doing that. A relay coil is a solenoid, which will have high voltage spikes when switching it off. To handle that, you need a flyback diode. The relay might already include one. Aside from that, it could still exceed the current rating briefly. In other words, 22mA is probably its holding current, and it might go higher during actuation.

Even if it never goes beyond its rating, it's 2mA higher than the maximum for the Arduino IO pin. You shouldn't exceed that rating unless you want to risk damage or a shortened lifespan to the microcontroller. It pretty much obliterates the keyword you used: reliably.

In an analogy, you could drive an 11000 kg truck on a bridge rated for 10000 kg, and it would probably hold, due to a bit of safety margin. But would you really want to do that repeatedly? Fortunately, an Arduino is cheap and unlikely to cause loss of life, so you have an opportunity to roll the dice. It might work just fine, or it might be a learning experience that costs as much as an Arduino and a bit of your time.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ If you drive a 10000kg truck on a 10000kg bridge and the bridge collapses, it's the bridge builder's fault. If you drive an 11000kg truck on a 10000kg bridge and the bridge collapses, it was a shitty bridge (it should have been designed to 20000kg) but it's still your fault. \$\endgroup\$ Commented Oct 20, 2023 at 9:35
  • \$\begingroup\$ @user253751 I don't see how this helps. I am not a civil engineer and I'm not sure what actual safety margins exist for structures. The point of the analogy was just that there should be some overhead and operating close to stated maximums can result in failure. \$\endgroup\$
    – JYelton
    Commented Oct 20, 2023 at 15:32
  • \$\begingroup\$ yes, that is the point of the analogy: if you exceed the POSTED limits and it works, fine, but if you exceed the posted limits and it breaks, it's your fault and you have to pay for whatever broke. \$\endgroup\$ Commented Oct 21, 2023 at 9:56
5
\$\begingroup\$

Maybe consider a solid-state relay instead? (If you do, make sure it uses 'random' switching - required for an inductive load.)

At any rate, I think you answered your own question: the current required (22 mA) is more than the Arduino can deliver (20 mA). On the face of it, not enough, it needs a buffer.

Besides, you also need to add a spike catcher diode across the relay coil to prevent damaging your driver, even for an external device.

\$\endgroup\$
5
\$\begingroup\$

Yes, if you control a BJT from the Arduino to power the relay, it can be done. That will protect the Arduino as long as you limit the base current to <20mA, with an appropriate resistor. Just make sure put a diode across the relay to catch the turnoff Spike and protect the transistor, Arduino, and the rest of the circuit.

Finally, two common jellybean parts, the 2N3904 (NPN) or 2N3906 (PNP), carry a max rating of 200mA, which handles the 22mA for the relay just fine. And if you kill the BJT, the replacement cost is pennies (and you're more likely to have a bunch on hand). For prototyping with relays, a mistake becomes less expensive, in parts, money, and time.

\$\endgroup\$
4
\$\begingroup\$

Yes, but.


Looks like I'll have to add the dissenting/nuanced voice here.

Mind, just on a basic level, if you have to be asking these questions, and making such points [as below], you're very likely asking the wrong question, and the more general answer is: if you're not familiar with all these considerations, and how they can go wrong, or what you might be missing -- just keep it simple, add a driver, done and done.

Design Review

If I saw this proposed in a prototype design, I would mark it as OK to proceed, but required change before production. It's okay to be a little cheeky in prototyping, if it saves time. Engineering time costs exponentially more than the parts do.

I would most likely mark it as required change for a proposed/pilot production design. The following analysis is probably too much bother, to support production and design maintenance, and thus is worth simplifying. In other words: if you're asking the wrong questions, everyone who inherits your design will be cursed with asking the same questions over again, and even if you provide design documentation justifying the use, they still have to spend time reading and understanding it. The whole thing can be more productive for everyone involved, over the total product lifetime, by keeping it simpler.

It might still be acceptable, in production, if the tolerable yield rate or product lifetime is relatively poor, and cost is such an extremely tight consideration that adding a few-cent pre-biased transistor is prohibitive. Such margins imply production on the order of 1M+ units/yr, a significant endeavor. But there are also likely many other ways to squeeze cost out, that doesn't involve abusing logic pins; a custom ASIC with mask ROM MCU and power-driver pins is even a realistic consideration.

Logic Pins

Assuming a basic ATMEGA328P or the like (typical 5V Arduino; since the board wasn't specified, I will consider this a free variable, free to assume whatever example I like), the output impedance is approximately resistive. We see from the datasheet, a 40mA abs. max. rating (p.258), and 0.9 (high) and 0.8 low) V max. drop at 20mA (p.259), or 45/40Ω maximum resistance. (Note that's max over temperature and manufacturing variation.) Typical at room temperature will be lower, probably about half, or 20Ω.

Typically, an asserted/driven pin has resistance to VDD or GND at all times, for either polarity of current. It's okay to drive current into an active IO pin, so long as the current rating is respected, supply voltage isn't made to rise (i.e. you're injecting more current than there is load on the supply, so the supply voltage rises up) -- the pin literally doesn't know the difference, the voltage drop is small (100s mV), and nothing else happens, like activation of ESD diodes (which requires upwards of 300 or 500mV).

(There is the case for "5V tolerant" IOs, which may not assert VDD under current injection; though I think the way they're usually designed, is as an analog switch, i.e. it does assert, it's just that there's two MOSFETs in series and both are switched off when unasserted, hence allowing the pin to be overdriven above VDD. I'm not sure that these are ever used on 5V devices, but I've also assumed ATMEGA328P above, which does not use this type of structure, so this doesn't apply here.)

The Load

A 5V 22mA relay coil can be modeled as a variable inductance in series with resistance. There is EMF associated with armature movement, but it's small, at least in all devices I've measured (which to be fair, isn't a great many, but you can always test a particular device to tell for sure).

The inductance starts small (open magnetic circuit), and rises as the armature closes; current indeed drops as the armature moves fastest, as the inductance increases rapidly as the magnetic path closes, meanwhile flux is accumulating at merely a constant rate (i.e., fixed coil voltage). A given flux distributing into a rising inductance means falling current (\$\Phi = L I\$ is the inductor equivalent to \$Q = V C\$ for capacitance); conservation of flux (or charge) doesn't necessitate conservation of energy, and indeed the discrepancy is the mechanical work done against the spring, closing the contacts (or solenoid, or advancing the motor to the next step; whatever the case, this applies to any reluctance machine).

In steady state, current is limited by coil resistance, and short of a jarring change of inductance (forcing the magnetic path open while under bias, I suppose?), current will never rise higher than this level.

Note also that the armature doesn't begin to move until coil current falls below holding current; at which point, any such mechanical disturbance must be as many times greater to try and exceed peak current.

This is all to say, we can quite safely assume peak current never exceeds nominal DC current, and we can treat the load as an RL equivalent circuit, ignoring the mechanical aspects.

And this is even more true if it's a poorly coupled type, like a reed relay; in that case, there is less or no closed magnetic path, so the inductance change is very small indeed, and we don't even need to average over the inductance, just assume a fixed value.

Switching

The GPIO shall be set as output (driven, DDR = 1) and toggled between a 0/1 OUT value.

The worst case condition to handle, is probably the flyback current (which, isn't so much a "flyback" thing because the voltage is 100% constrained at all times; it's just the current decaying), since we want to avoid activating ESD diodes; this suggests a common-ground load, so that the slightly lower resistance NMOS can handle that current. Thus it will be activated when the output is '1', and inactive when '0'.

Turn-on time is set by the L/R time constant, and (electrical) turn-off is equal. Since release current is generally much lower than operating current, the turn-off time (propagation delay, switching speed) however is delayed by this time constant. Now, this isn't much different from the diode-clamped case -- more or less the baseline; the voltage drop is only slightly lower (~0.1V versus ~0.7V), with coil resistance still dominant. However, we do not have the opportunity to add a zener clamp for example, if we wanted faster turn-off.

If faster turn-off is required, we do still have one option: drive the coil between an H-bridge of two pins. You'll need to calibrate for the L/R time constant, but by applying counter flux briefly (some ~ms), current can be ramped towards zero much quicker than letting it decay by itself.

You don't want to let the pin go open-circuit (DDR = 0), or drive it open-drain style, because that will activate ESD clamp diodes by the flyback. Current isn't excessive (again, it's never higher than steady-state 'on' current), but injected current is generally a poor idea: it can disrupt nearby analog functions, increase leakage current in neighboring pins, and induce CMOS latchup. (Usually latchup is in the 100mA range, significantly above 22mA, but all the same, a factor-of-5 ratio isn't really all that large in the grand scheme of things.) Granted, you could add a schottky diode for clamping, but you aren't gaining anything over the always-driven pin, so, why bother?

Oh also, once current decays to ~zero, the pin can be released (go Hi-Z), if that matters for some reason I guess.


Now, this is all to say some very general things, including things real at-work in-production engineers might be concerned with. But let's circle back to that keyword "Arduino". These are rarely used* in production equipment, and at the very least nothing very important*. Real Engineers(TM) do use them from time to time, and appropriately, often enough, I would say -- contrary to what some might impugn about them! To be clear, I'm not ragging on anything Arduino in particular, here. But if I may read into it a little bit -- their predominant use is still amateur, and the amateur might not care about occasional malfunction, or indeed destroying boards once in a while (which is bound to happen anyway, given the lack of ESD protection, shielding, etc. most projects have). In other words: it might be the prototype sort of circumstance I noted at the top. If all that matters is it works for a while, yeah, you absolutely can get away with it.

*At least... I hope??

tl;dr: Can? Yes. Should? No.

\$\endgroup\$
1
\$\begingroup\$

22mA is not actually needed.

For this relay the "must operate voltage" is quoted at just below 70% of nominal voltage, so if your Arduino can manage more than 4.2V at 15.4mA from an output pin you can make this work, you could measure this or check the datasheet of the microcontroller.

A shottky diode parallel to the coil to handle back emf is recommended

Using parts near their limits tends to cause them to age faster, so if you want this device to last a long time and be reliable this is probably not the best approach. use a transitor to swithc the relay coil current instead,

\$\endgroup\$
1
\$\begingroup\$

Don't use your MCU pin(s) to drive a relay. A 10 Cent 2N3904 or 2N2222 used as a driver will protect your MCU and you'll sleep better at night knowing you did it properly. Base Resistor for 2N3904 help

A 1k resistor is good for the pin to base connection.

\$\endgroup\$
1
\$\begingroup\$

The official answer is simply: no. 22mA is more than the specified 20.

In practice the atmega has pins that perform quite a lot better than the official specs. It will hold out doing 22mA for years.

Then there is the inductive kickback. This will force 22mA into the pin for a short while after switching the relay off. Again, this is more than the spec which would be 10mA if the datasheet were to mention it. The datasheet does not mention it so officially you are out of spec at .1mA. The diode you are loading this way is quite beefy; it is the ESD protection diode. As long as you allow the diode to cool off inbetween, you will be ok. One second is plenty, just dont trigger it 10+ times a second.

Ok, that 10 times a second was intuition saying that would be ok for sure. Having done the math, you will even be ok when you do it thousands of times in a second.

If you want a little extra security than trusting a random idiot on the internet, just test it yourself. Be prepared to lose the arduino, but I'm saying it will survive. Torture test it by switching at 1kHz. If the relay actually switches at that speed (which i do not expect) then the relay will be end of life after 5 minutes, but if it just buzzes a little even the relay can still be used.

In conclusion, this is frowned upon by hobbyist and professionals alike, but for a hobby one off project: keep it simple, just do it.

\$\endgroup\$
1
  • \$\begingroup\$ There is another answer saying the same. "Ok for prototyping, but required change for production." \$\endgroup\$
    – user242579
    Commented Oct 20, 2023 at 5:22
1
\$\begingroup\$

I don't think the 22mA 'limit' will be a problem under typical conditions because the output voltage of the Arduino (assuming an ATmega328) will be typically 4.45V (sourcing) so you'll see about 19mA.

When the output is switched low (off) the N-channel MOSFET on the output will conduct (most of) the current flow to discharge the energy stored in the inductance. Under nomal conditions. If the output went high-Z the protection diodes would more come into play and they'll probably be okay.

So I think this will work 'reliably' under typical conditions- typical samples of the parts near room temperature.

Personally I wouldn't do it, even for a room temperature test, but that doesn't mean it won't likely work. There may be some pathological situation where failures (soft or hard) occur. You might also see some interaction with ADC readings etc. when you have high currents switched by the pins. A transistor, base resistor and diode cost a couple pennies.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.