Controlling a Solenoid Valve from an Arduino. Updated.

A very short post I made sometime ago has been more popular that it should have been. It wasn’t particularly detailed and it was in desperate need of an update. So here is the update, this time giving more details and adding mosfets.

 
Arduinos are limited in the current and voltage they can supply. A typical 5V Arduino can provide 5V and 3.3v at a maximum 40mA from a single pin. 40mA is the maximum and ideally the current draw should be kept to around 20mA. 20mA is fine for a LED but not so good for motors, solenoid valves or long strings of RGB LEDs. For these we need a separate power supply and a way of controlling it.

One of the problems many beginners have is knowing what can be connected to and Arduino and what should not be. This post does not really help with this except to show how to use a high voltage/high current device with the Arduino. The high voltage/current is not connected directly to the Arduino but it can controlled by the Arduino by using devices that act as digital switches.

Knowing what to connect and what not to comes from experience and a little understanding of volts and current. I do not cover this here beyond saying voltages should match and currents are more difficult to determine. I have killed/partially killed more things because of current than I have because of volts simply because most things clearly say what voltage they are, A 24v power supply says 24v on it and I know I shouldn’t connect it to an Arduino. A very small 6v motor that looks like it hardly required power melted an Arduino with seconds. Finding a devices current requirement may mean reading data sheets and extensive online searches. Unfortunately Arduinos do not give a warning when a device wants more current than they can supply, they simply tries to provide it. This leads to over heating and mini explosions (or at least a dead Arduino and the smell of burnt plastic).

 
In this post I am using DC voltage solenoid valves only. Valves that use AC have very different requirements and the below does not apply. Most DC solenoid valves tend to use a voltage any where from 6v up and 12V and 24V are very common. The one I am using below is 24v. The Arduino cannot handle these voltages and so cannot (or should not) be connected directly to the valve. Instead, we use another device as a middleman, one that can accept the 5v signal from the Arduino as a control signal and also handle the higher voltage and current required by the valve. There are various different devices that can fulfill this role. I am using transistors. The Arduino controls the transistor and the transistor controls the valve. A simple way of thinking about this is we are using the transistor as a switch. The Arduino is controlling the switch and the switch is controlling the valve.

There are many transistors you can use and you pick one depending on the voltage and current you need to control. To know the voltage and current required means knowing about the device you want use. Here I am using the good old TIP120 and the IRFZ44N mosfet. Why these 2 devices? Because they are what I have. They were purchased sometime ago purely because they are suitable for use with 5v Arduinos.

 

TIP120

The TIP120 is, by electronic standards, an old device and there is a lot of talk on the internet about how it is passed its prime and never the best option. Being old though, it well tested, proven to be very reliable, and cheap. They are very cheap. A while ago I bought 1000 of them for around 4 USD. I still have most of them in a box somewhere.

The TIP120 is a NPN Darlington pair transistor, which means it is two transistors, one piggy backed on top of the other, the first one driving the second one. The current amplified by the first transistor is amplified further by the second transistor. This allows a very small voltage to switch a very large voltage. The TIP120 can handle 60v up to 5 amps. These are the maximum ratings so the TIP120 should not really be used at this level. My valve is 24V and rated for 0.275 amps so well within the limits of the TIP120.

One downside to the TIP120 is the voltage drop across CE. This can be anything from 2v to 4v depending on the current and means the 24v supply is reduces to around 22v by the time it gets to the valve.

TIP120_CircuitDiagram

TIP120
In the example below the TIP120 can be thought of as a switch and applying a current to the Base pin allows current to flow between the Collector pin and the Emitter pin.

Fairchild TIP120 data sheet

 

IRFZ44N mosfet

The IRFZ44N mosfet is a logic level N-channel mosfet which means it can be controlled from a logic level voltage of 5V. There are also 3.3v logic level mosfets so when selecting a mosfet double check the data sheet. There are many similar mosfets that can be used in exactly the same way.

N-channel mosfets are voltage driven and require very little current. They also have very little voltage drop across drain-source. The actual voltage drop is dependent on the mosfets RDS(on) property. So the lower the RDS(on) the better. The IRFZ44N has a RDS(on) of 17.5mΩ, not bad, and can handle 55v at 49 amps (remember these are maximum ratings, don’t actually use it at this level).

I am using the mosfet as a switch exactly like the TIP120. But why bother with a mosfet? There a few advantages. Mosfets are voltage driven so we don’t need to worry as much about current, they are more efficient than TIP120s so we do not need to care as much about total power and heat, and they switch quicker. You can also get away without a resistor so there is one less component. However, if you use a mosfet for fast PWM then you may get issues with gate ringing and adding a small resistor (up to 100 ohms) will reduce it (in my own projects I typical use 200 ohms).

IRFZ44N_CircuitDiagram

IRFZ44N_Pins

IRFZ44N data sheet

 

Main Differences

Voltage drop
Darlington pair transistors have a considerable voltage drop across emitter and collector.
Mosfets don’t have a specified voltage drop but instead have a drain-source ON resistance (RDS-on) which is normally very small and results is a low voltage drop.

Base/Gate drive
Transistors are current driven and require a current limiting resistor on the Base pin.
Mosfets are voltage driven and require hardly any current on the Gate pin but does need enough voltage. This means a resistor on the Gate is not always required.

Please be aware there is far more to it than this. If you are using either a transistor or a mosfet for other things (like PWM) then there are other things to consider.

 

Solenoid Valve

For the following examples I am using a Shako PU220AR Solenoid valve with 24v coils. These draw around 0.275 Amps. The valve is a normally closed and uses an electromagnetic coil to open. Apply a current the coil charges creates a magnet that moves a plunger which opens the valve. Stop the current the plunger moves back and the valve closes (other valves can work in different ways).

Flyback Diode

When you remove power from an electromagnet, the magnetic field collapses creating current (the coil is an inductive load). This current can be very high and can be powerful enough to kill an Arduino. To stop this happening we add a flyback diode (AKA a snubber diode, freewheeling diode, and many other names). The diode allows current to move in one direction only and safely dissipates the current created by the collapsing magnetic field. This can slow the decay slightly but for use with solenoids this is not noticeable, the valve is much slower.

Arduino+_SolenoidValve_FlybackDiode

 
 

Circuit using TIP120

Here we have a very basic circuit. Note that all GNDs are connected. DO NOT CONNECT THE 24V WITH THE 5V!
Arduino_SolenoidValve_TIP120_CircuitDisgram_01

Arduino_SolenoidValve_TIP120_Circuit_01_1200
When we set Arduino pin D2 high, the transistor activates and allows current to flow to the valve.

Sketch

//  Arduino_Solenoid_Valve_01
 
byte LED = 13;
byte Valve = 2;
 
void setup() 
{
    pinMode(LED, OUTPUT);
    pinMode(Valve, OUTPUT);
}
 
void loop() {
  digitalWrite(LED, HIGH);   
  digitalWrite(Valve, HIGH); 
  delay(1000);       
 
  digitalWrite(LED, LOW);  
  digitalWrite(Valve, LOW);     
  delay(1000);                       
}

The sketch switches the valve on and off every second. It’s the blink example with an extra couple of lines of code. Hard to tell from the photo above but when running the valve clicks as it opens and closes in sync with the Arduinos on board LED.

Bonus

Here is a bonus circuit and sketch that uses a button switch to turn the valve on and off. First press opens the valve, second press closes it. If you want to know more about how the sketch works see Switching Things On And Off With An Arduino

Arduino_SolenoidValve_TIP120_02_Circuit
Note that all GNDs are connected. DO NOT CONNECT THE 24V WITH THE 5V!
Arduino_SolenoidValve_TIP120_CircuitPhoto_03_1200

//  Arduino_Solenoid_Valve_02
 
byte Valve = 2;
byte Switch = 3;
byte LED = 4;
 
// variable to hold the valve state
boolean valveState = LOW;
 
// variable to hold the switch state
boolean oldSwitchState = LOW;
 
// used for simple debouce
boolean newSwitchState1 = LOW;
boolean newSwitchState2 = LOW;
boolean newSwitchState3 = LOW;
 
 
 
void setup() 
{
    pinMode(LED, OUTPUT);
    pinMode(Valve, OUTPUT);
    pinMode(Switch, INPUT);   
}
 
 
void loop() 
{
    newSwitchState1 = digitalRead(Switch);     delay(1);
    newSwitchState2 = digitalRead(Switch);     delay(1);
    newSwitchState3 = digitalRead(Switch);  
    // if all 3 values are the same we can continue
    if (  (newSwitchState1==newSwitchState2) && (newSwitchState1==newSwitchState3) )
    {
 
        if ( newSwitchState1 != oldSwitchState ) 
        {
           oldSwitchState = newSwitchState1;
 
           // has the button switch been closed?
           if ( newSwitchState1 == HIGH )
           {
               if (valveState==LOW)
               {
                 valveState=HIGH;
                 digitalWrite(LED, HIGH);   
                 digitalWrite(Valve, HIGH); 
               }
               else
               {
                 valveState=LOW;
                 digitalWrite(LED, LOW);   
                 digitalWrite(Valve, LOW); 
               }
           }
        }  
    }
}

 

How to calculate the resistor value

The TIP120 is a current driven device and will, given the chance, try to use as much current as possible, sucking the life out of the Arduino. This is not good, so we add a current limiting resistor to stop it happening. So what resistor to use? I generally use 2K2. Why? because I am lazy and it is what the internet says.

I don’t go in to the full details on how to select a resistor, there are far better explanations than I can offer online, google “How to calculate TIP120 resistor value”, but the basics are as follows.

A few of things we need to know before starting to calculate:
– what current an Arduino is able to deliver. Safely this is 20mA. Max is 40mA.
– what current the valve uses when active. This is 275mA or 0.275A.
– the TIP120 data sheet.
– from the data sheet – DC gain
– from the data sheet – Vbe
– From the data sheet – Vce

The load (the current the solenoid needs) is 275mA or 0.275A. This is the collector current (Ic).
The DC gain at 275mA (according to the data sheet) is around 1200. Diagram 1.
Vbe is around 1.4v. Diagram 1.
Vce at 275mA is around 0.75v. Diagram 2.

DC_GAINTIP120_Vbe-Vce

In order to switch 275mA we calculate the Base current using Ib = Ic / DC gain.
Ib = Ic / DC gain or 0.275A/1200 = 0.000229uA. The general internet rule of thumb is to use Ib x 5 which gives us 1.15mA.

Now we can use ohm’s law to work out the resistor value.
Resistor value (Rb) = (5v-1.4) / 1.15mA. Rb = 3.6/1.15. Rb = 3.13 or 3K13 Ohms.

And for good measure we can work out the power consumption with P = Ic * Vce
Power = 0.275A * 0.75v = 0.2 watts. This tells us if we need a heat sink or not.

A 3K13 or 3K3 ohm resistor is the best case scenario and may cause the TIP120 to be borderline saturated (When using a TIP120 as a switch we need to make sure it is fully saturated or it doesn’t turn all the way on). To ensure the TIP120 is fully saturated we lower the resistor value, I normally go with 2K2 and for the valve I am using could probably go to 1K. I’ll stay with 2K2 because that is what I generally use and also have one on hand.

Edit 30.09.2019
The above is how I work out the resistor value when I need to, I must admit I generally just guess though, however, leovd contacted me to say I am using the wrong method.

As stated many times on the Arduino forum, don’t calculate/use Hfe for a saturated switch. Hfe does not apply when a transistor is reverse biased (collector voltage lower than the base). The datasheet clearly states a 1:250 B/E current for saturation of this darlington (inside one of the graphs). Just stick to that. Regards, Leo..

 

Circuit using IRFZ44N Mosfet

The circuit for the mosfet is very similar to that of the TIP120 and although the pins on the mosfet have different labels the connections are basically the same. You should notice that we no longer have the current limiting resistor but we do now have a 10K resistor that pulls the pin to ground. This stops it floating and causing issues.

When used as a basic switch, there is no need to add a resistor to the Gate of the mosfet. If you use a mosfet with a fast switching signal then there may be issues with gate ringing and a small resistor can help.

Arduino_SolenoidValve_MOSFET_Circuit_02_1200

Arduino_SolenoidValve_MOSFET_photo_01_1200

Sketch

Because we are using the same pins as above the sketch has not changed.

//  Arduino_Solenoid_Valve_02
 
byte Valve = 2;
byte Switch = 3;
byte LED = 4;
 
// variable to hold the valve state
boolean valveState = LOW;
 
// variable to hold the switch state
boolean oldSwitchState = LOW;
 
// used for simple debouce
boolean newSwitchState1 = LOW;
boolean newSwitchState2 = LOW;
boolean newSwitchState3 = LOW;
 
 
 
void setup() 
{
    pinMode(LED, OUTPUT);
    pinMode(Valve, OUTPUT);
    pinMode(Switch, INPUT);   
}
 
 
void loop() 
{
    newSwitchState1 = digitalRead(Switch);     delay(1);
    newSwitchState2 = digitalRead(Switch);     delay(1);
    newSwitchState3 = digitalRead(Switch);  
    // if all 3 values are the same we can continue
    if (  (newSwitchState1==newSwitchState2) && (newSwitchState1==newSwitchState3) )
    {
 
        if ( newSwitchState1 != oldSwitchState ) 
        {
           oldSwitchState = newSwitchState1;
 
           // has the button switch been closed?
           if ( newSwitchState1 == HIGH )
           {
               if (valveState==LOW)
               {
                 valveState=HIGH;
                 digitalWrite(LED, HIGH);   
                 digitalWrite(Valve, HIGH); 
               }
               else
               {
                 valveState=LOW;
                 digitalWrite(LED, LOW);   
                 digitalWrite(Valve, LOW); 
               }
           }
        }  
    }
}

 

Final Notes

In this particular example the solenoid valve does not require that much current and the TIP120 is probably over kill and a regular transistor could be used. A regular transistor is used in exactly the same way as the TIP120 but it will have lower capabilities (smaller voltage, smaller current).

Is a mostfet or a TIP120 better? In most cases a mosfet is better. They use a newer technology, are more efficient and do not have the large voltage drop the TIP120 has. Having said that, if you have a TIP120 there is no reason not to use it.

TIP120, TIP121, and TIP122 are mostly interchangeable. The difference is the TIP121 and TIP122 can handle larger voltages.

 
 
 
 

6 thoughts on “Controlling a Solenoid Valve from an Arduino. Updated.

  1. Hello Sir,

    In this concept Arduino Controller is to be used……but if we want to apart from this arduino controller then …. can be used???

    Please Advise

  2. Hi Martyn,

    Thanks for the great post! I am working on a project involving Water solenoid valve but unable to make it work. It is 24v DC valve. Does it require 24v power supply or 12v power supply would work?

    • A 24v valve requires 24V, however, depending on the valve there is probably a working voltage range. For example, I have some 12V solenoids that have a working voltage range of 10v-18v. Check the data sheet for the solenoid you have.

      It is also worth mentioning that the coil on most valves (the black plastic part) can be replaced. The Shako in the photo above has a 24v coil but I also have 12v coils I can swap with should I need to.

      If speed is important; higher voltage solenoids open (very slightly) faster than low voltage ones.

  3. Thank you for the post. In my project, I have to close the solenoid valve at a different rate of time (for each reading). Do you think by changing the delay time I will be able to do that?

    • delay() will work, simply use the Blink example as a starting point but a better solution would be to use millis(). millis() will give you far more flexibility. I don’t have an example but if you search online you will find many guides.

Leave a Reply to Marium Neshat Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>