PWM 12-24v Fan speed controller. What is the best approach to vary speed?

It occurred to me today that smaller 40mm fans used in my project run off 24v d/c power. The Arduino itself can only supply 5v PWM of variable output and if I run too much current through the board itself, it can fry it.

My first thought was to make a voltage divider circuit. Run the fans on an external suppy and control a resistance value via PWM. This would mean the resistor would have to be a variable resistance. From googling around, it seems that digital potentiameters could do the job. They are a little pricey (I say that with hesitance lol) at around $1-2 a piece. 5 fans that could be as much as $10 (+-) for the missing component needed to complete this approach to the circuit. Between the fans themselves, the arduino nano's, the thermistors, thermal grease, the copper cabling and other components, the expenses have been adding up quickly and I want to get it finished as cheaply as possible. This might mean I'd just have to order parts from China, but as I'm sure everyone is aware, they take quite some time to get here these days due to the global health pandemic situation.

My second thought would be to use a boost converter to go from 5v, to 12 or 24v DC straight through the Arduino, but as mentioned earlier, too much power draw could burn the board pretty quickly. Additionally, most boost converters are static and not dynamically set. I believe these cost even more than digital potentiameters as well.

What is the best and least expensive way to vary a fan's speed (DC) power, using PWM from an Arduino? Thanks!

Use analogWrite(), a PWM output pin, and a transistor or MOSFET as a switch to turn the power on and off very quickly. The transistor or MOSFET can be controlled with 5V and can turn on and off a higher voltage and current.

Thanks for the quick response. I found a S8580 Transistor from a leftover starter kit but I am having some troubles with it.

I'm trying to gate a 12v source to a tester fan. The Fan is rated 24v at 0.10 watts, but I do not have a convenient 24v power source lying around. If my Math serves me right, that means it should be pulling about 120ma at 12v.

I have attached a diagram of my circuit right now. I have a 1K resistor attached from pin 9 on the arduino to the base of the S8550 transistor to help eliminate noise. Does the resistor serve any other purpose than this?

GreatScott did a good little video on transistors and mentioned that the transistor or mosfet might turn on from even the smallest voltages/current otherwise without the transistor, and showed this by switching on an LED by touching the base signal of the transistor with his finger.

As far as the Arduino and Code setup, I have pin 9 initialized and set to OUTPUT. I am also just leaving a digitalWrite() signal to HIGH just to test the circuit's gating for now. It should be cutting signal to the fan but it does not. Not only that, but that transistor gets extremely hot! I am worried I might have blown one already.. I have spares so not a big deal, but I would like to not waste components when possible.

[The datasheet for the Transistor can be found here.](http://"https://components101.com/sites/default/files/component_datasheet/S8550 Transistor Datasheet.pdf")

I don't understand all the perimeters on the datasheet, but it looks like a minimum 1.2V logic signal is required to turn the gate on. I did not think that amplification would be an issue, since from what I understand, the fan should only pull the required 120ma from the 12V signal.

Do I need a secondary resistor somewhere or to increase the resistance on the signal pin? Are my voltages too high for this transistor? What am I missing?

I am still a novice with circuits and this is a learning experience for me, so I apologize and thank you in advance for any help.

The S8580 appears to be a PNP transistor. It can act as a high-side switch (between +V and the fan) but to switch it off you need to raise the Base voltage to match the +V voltage and the Arduino pin can't do that. Generally, you would use an NPN transistor (or N-Channel MOSFET) as a low-side switch, between the fan and Ground. Then the Arduino pin can set the pin LOW to turn off the transistor (no current from Base to Emitter/Ground) or HIGH to turn on the transistor (current from Base to Emitter/Ground).

Your schematic shows the transistor in parallel with the fan. That is not correct. The transistor should be in series with the fan to act as a switch. You also show the negative side of the fan connected to the positive side of the power source.

I have good news and bad news. I got the circuit working with an NPN type transistor (it's complimentary to the PNP type). With a Pot and a little bit of code, I was successfully able to modulate the speed of the fan.

The bad news is, despite trying numerous current resistors, there seems to be some current leaking into the fan during it's off state. According to my googling, the resistor should be attached to the base bias pin (ie, the arduino PWM pin). Anything over 100 ohms will not power the fan in this circumstance it seems.

There seems to be a lot of tutorials on how transistors work and they typically specify a specific rated resistor for a given piece of hardware being tested (motor, amp, etc). The resistor helps dial in the correct current saturation based on the amplification of the transistor. Here's what I understand on calculating the needed resistor value:

The collector current is value of the base current * DC Current Gain.

If we look at the datasheet for this transistor, we can see 3 different values of DC Current Gain. This confuses me as to which value I should be using.

To determine the base current, we need to do:
I(b) = (Collector Current/DC Current Gain).

To determine the resistor value:
R = VCC - V(b) / I(b)

Lets say I use the "500ma" value of the D/C current gain and the Fan is rated at 0.1 Amp:
I(b) = 100ma / 40
I(b) = 2.5ma

Then we find the resistance for the base current:
R = (12 - 5) / 0.025
R = 220 ohms

However when applying a 220 ohm resistor, the fan fails to spin altogether. Could you help explain the DC Current Gain value (also known as "bella" I guess), a little better and how to determine which one to use for a given piece of hardware?

You are using the transistor as a switch.
NPN (Arduino High output into Base), or PNP (Arduino Low output into Base), the most base current you can get to flow without damaging the Arduino pin is about 35mA long term.

The Arduino will have about a 0.7V drop across the base.
So (5V - 0.7)/.035A = 122 ohm is about as much as you can turn the transistor on (Ic) with Vbe of 35mA.
So forget the current gain, you are not using the transistor as an amplifier, but as an on/off switch.

aspen1135:
However when applying a 220 ohm resistor, the fan fails to spin altogether. Could you help explain the DC Current Gain value (also known as "bella" I guess), a little better and how to determine which one to use for a given piece of hardware?

Use a mosfet.

CrossRoads:
The Arduino will have about a 0.7V drop across the base.

How do you determine the voltage drop across the base? Yes, I can use a multi-meter, but is there a way to determine this without it?

bluejets:
Use a mosfet.

Mosfets use the same concept, except are gated by Voltage values instead of current. Correct?

Also for this project, are there any mosfets you would recommend in particular? Fast-Switching, up to 24v, etc...

Vbe is in the datasheet. Typically it is about the same as 1 diode drop.

Logic level MOSFET with low Rds would be great.
If you can handle a large package SMD part, then this one
https://www.digikey.com/en/products/detail/alpha-omega-semiconductor-inc/AOD4184A/2353886
Very low Rds, 0.01 ohm with Vgs at 4.5V, and it can do high currents.
0.01 ohm, that's practically just a piece of wire!

This is an N-channel part, so you will use it as a switch between motor (-) and Gnd.
I have a customer using very similar AOD514 to PWM LED strips (single color) with SX1509 driving the gate thru a 74ACT541 buffer to bring 3.3V output to 5ish volts for the gates. Lot of LEDs, says the part barely rises 10 degrees F on this board with 12V power supply:

Those look nice. Thanks for the recommendation. It seems they are hard to come-by in the U.S. I'd have to order some from overseas which would take awhile. I might do so just so I have some laying around and on-hand.

For now, I went with these from Amazon. Whenever I buy a new component I like to have spares lying around and these come in a pack of 100 for $6 bucks! The Drain Source Resistance Specification was only 5 ohms max, so it didn't seem too bad. The Gate Source Voltage spec says a minimum of 0.8v and a max of 3v, so an Arduino should be able to switch it just fine.

If it says the gate voltage is 'max' of 3v, does that mean if I use a 5v PWM signal from the arduino it would damage the gate on the mosfet? Should I create a voltage divider and drop the arduino signal voltage to hit 3v or is that just the minimum voltage required to switch it when driving a given amount of current load?

aspen1135:
For now, I went with these from Amazon. Whenever I buy a new component I like to have spares lying around and these come in a pack of 100 for $6 bucks! The Drain Source Resistance Specification was only 5 ohms max, so it didn't seem too bad. The Gate Source Voltage spec says a minimum of 0.8v and a max of 3v, so an Arduino should be able to switch it just fine.

That 3V is the THRESHOLD voltage. The maximum at which they START to conduct. The Rds-on of 5 Ohms is at a Vgs of 10V. That's normal for a MOSFET but not for a logic-level MOSFET. At 5V the MOSFET won't be fully ON and the resistance will be higher. They can switch 500 mA at a Vgs of 10V but they won't handle as much current at a Vgs of 5V. For switching with an Arduino pin you want a "logic level" MOSFET where the Rds-on is measured at 4.5V or 5V.

I got the mosfets in the mail today (yay!). I know you mentioned these may not work for switching an Arduino, but for educational purposes I wanted to play around with them today to get a better understanding of how they work.

I hooked up my circuit and incidentally blew one right away lol. I had my fan's positive lead hooked to the gate and the negative lead to the drain by accident... whoops. This was me just being too eager and clumsy. :confused:

The second time around, I connected the fan's positive lead to source V and the negative to the gate. This actually worked and I was able to modulate the fan's speed with the Arduino surprisingly. However, I was still encountering an issue where I could not get the full range of speed out of the fan. Specifically, I could not turn it off all the way..

From the learnings while playing around with the S8050 transistor, I tried attaching a 300 ohm resistor to the gate of the mosfet, hoping that it would reduce any possible amplification. And that, well-- managed to blow my second mosfet (if you keep reading though, it might not actually have been due to the resistor).

I realized and remembered right then, that a mosfet and a transistor behave differently in their gating mechanisms. One is moreso influenced by current and the other, by voltage.

I removed the resistor, but kept blowing Mosfets.

"Hmmm. This is perplexing. This exact configuration worked a second before..."

After tinkering around a bit more, googling, and doing some investigation with my multi-meter, I discovered why I was not able to get the full range of speed of the fan to work prior with the transistor or the mosfet. There was a problem in my Arduino code where I was not returning the remaped variable during it's function call. A silly mistake... but a critical one.

This was also why it took me awhile to figure out why I kept blowing out mosfets. The PWM signal from the Arduino was outputting a full 0-5 volts range instead of a more constrained range. Based on what you told me with the mosfets having limited current output with lower voltage levels, I pulled up the datasheet to investigate. According to this graph, this little 2n7000 mosfet should be able to supply 100mah at a minimum of around 3ish volts. And this was probably why when I had started my circuit before, I was blowing mosfets right and left. My potentiometer was probably set at a lower state below 3V, it would instantly blow the mosfet trying to drive the fan.

Once the mapping was fixed and I had initialized the circuit with the Pot all the way on, it was stable enough to drive the fan no problem. It didn't even get hot at all! I slowly lowered the potentiometer down to 3.5 volts and it very slowly started to smoke and burn up. Interesting...it should still be stable at these values. ???

Then I remembered I swapped the old 24v 0.1 amp fan I had previously been testing with, for a 12v fan with an unknown current rating. I did this because the power source I am limited to is a 12v lithium cell battery. I figured it would be more sensible to use a fan that matches the batteries voltage output, than to limit the max RPM's automatically due to the lower voltage drop across the battery. As a result, the fan could actually be pulling more power than 0.1amp and need a higher voltage across the mosfet's gate to drive it safely.

So in conclusion from this little mosfet shit show, I have basically learned that when using this 2N7000 mosfet, I can probably get away with driving a low-powered device (such as a small PC fan), so long as I do not incidentally lower the voltage across the gate. I can vary the HIGH/LOW switching speed of the PWM output, but I do not want to change the logic gating voltage.

As a side question, I wanted to learn more about the power dissipation of the mosfet. An article I came across while troubleshooting the circuit had some good information on how the drain resistance effects the temperature and power dissipation of the component. If we know the drain current, then we can calculate the power dissipation by using the formula:

P(d) = I^2(d) * R(ds)

So in my scenario, lets say I am powering a 0.1 Amp fan while using this 2n7000 Mosfet with a Resistance of 5ohms. 0.1^2 * 5 = 0.05 watts. Did I do this right?

How and when is this power dissipation formula useful? Could you provide an example?

Thank you everyone so far for your replies thus far. Learning a lot here :smiley:

screenshot.png

screenshot.png

aspen1135:
The second time around, I connected the fan's positive lead to source V and the negative to the gate.

I hope you connected the negative side of the fan to the DRAIN, not the GATE.

aspen1135:
As a side question, I wanted to learn more about the power dissipation of the mosfet.

Pushing current through a resistance causes heat. Too much heat causes your semiconductor to melt.

aspen1135:
So in my scenario, lets say I am powering a 0.1 Amp fan while using this 2n7000 Mosfet with a Resistance of 5ohms. 0.1^2 * 5 = 0.05 watts. Did I do this right?

Remember that the Rds-on is 5 Ohms when the Vgs is 10V. You are using a Vgs of 5V so your Rds is likely to be higher than 5 Ohms. The higher resistance causes higher power dissipation (Watts) which causes higher temperatures.

Aha. John you are a lifesaver!

I'm not sure why, but I was looking at so many references trying to figure out the correct way to wire the circuit last night to no avail. Yes, I had the negative lead of the fan connected to the gate incidentally. Additionally, I was testing with a mosfet that must have been shorted because it would not work even after the proper circuit was setup... it was all a tad frustrating. As soon as I replaced the mosfet, the mosfet worked like a charm!

I apologize for having so many questions, but this now regards the original post topic a bit more... Would it be better to just control the current flow through the mosfet to adjust the fan speed, or can you sustain a lower range speed by pulsing the PWM signal with a timer on the arduino?

I have not written any Arduino code using the timer before, but in my testing with a simple sketch and pulsing a PWM with a delay in microseconds it seems like the pulsing technique may work better...? I noticed the pulsing frequency is slightly audible through the circuit, which is not a huge deal to me.

What are your thoughts and experience on this?

aspen1135:
can you sustain a lower range speed by pulsing the PWM signal with a timer on the arduino?

Are you saying that analogWrite(pin, 1) does not run the fan slow enough?