Note: my entire answer below assumes you need to drive a 2-wire brushed DC motor (or similar load, such as an audio speaker) directly, with real power and real current. That is what my entire answer is based on. However, after I wrote my answer, the OP posted this in a comment under his question (emphasis added):
I didn't have the serial number of the fan until today, now I have that I have checked the spec, and a low powered option is suitable as it only requires a PWM signal to control the speed the rest is done with its on-board controller - no more than a 0.5mA signal is required.
So, although my answers below will still work to provide an output PWM at, lets say, 12V, from an input PWM at 5V, they are intended to drive a 2-wire brushed DC motor directly with real power and real current. The fact that they can also provide an output PWM signal at 12V is incidental, but just as applicable.
Also, it is important to note that all my answers below are expected to be usable up to a few dozen kHz max PWM frequency, unless otherwise stated on the product datasheets--Ex: many high-end Pololu brand motor drivers (H-bridges) I recommend below can be driven with up to 100kHz PWM frequency since they use such high-quality and fast MOSFET Gate driver circuits with both high-power active Gate drive HIGH and active, high-power Gate drive LOW in their H-bridges.
TLDR;
Jump straight down to the section titled "Here's some H-bridges you can buy", in the "Option 2" section below. Buy one of those and be done.
Reminder: on any H-bridge, when you drive a PWM to the input at 5V with a certain duty cycle and frequency, an equivalent or almost-equivalent PWM output at voltage level Vsupply
will occur on the H-bridge output. This is the exact purpose of the half-H-bridge. And, this, in addition to allowing bi-directionality of power, current, and voltage, is the exact purpose of the full H-bridge. PWM output freq from the H-bridge will be exactly identical to the input PWM, and PWM duty cycle will be almost identical, with output PWM waveform distortion increasing as PWM frequency is increased.
Option 1 of 3: [custom circuitry] The Electrical Engineer / "very curious hobbyist with lots of time" answer:
I've upvoted @Sahasrar's answer. If you haven't taken a look at it, you should. It fits squarely into this "Option 1" category.
However, in his first image, when controlling pin D7
, the MOSFET gate is actively driven both HIGH and LOW with a max (initial) current of I = V/R = 5V / 100 Ohms = 0.05A = 50mA, which is good, but kind of weak (a good MOSFET gate driver is more like 500~1000mA drive current). This is also exceeding the 40mA max current rating of the Arduino pin, so I recommend you choose a slightly bigger resistor. The resistor here is to limit current to not damage your Arduino pin when charging and discharging the Gate capacitance of the MOSFET, which capacitance is significant enough for MOSFETS (but NOT BJT transistors), that it is even listed as a parameter in a MOSFET transistor datasheet (but not in a BJT transistor datasheet). WithOUT this Gate resistor, each time you drive the Gate HIGH or LOW, you'd otherwise have the equivalent of a momentary instantaneous short through the Arduino pin, which could damage the pin.
Also, you have to be sure to use a Logic-Level N-Channel MOSFET which can be driven with a gate voltage as low as 3.3V~5V instead of requiring more like 10V~12V.
So, with @Sahasrar's first circuit, the max PWM frequency you can use is probably a few dozen kHz.
If you need to drive higher PWM frequencies, the solution is to use the push-pull logic circuit which @Sahasrar shows next instead. But, you have to fill in the blanks: choosing parts, doing calculations, having advanced knowledge.
In both cases, you must also be sure to use a flyback diode to snub inductance-induced voltage spikes!
Option 2 of 3: [just buy an H-bridge DC motor driver] The normal hobbyist / time-constrained-individual answer:
So, the quick solution is to just buy a motor driver instead and be done!
You can use any H-bridge for a 1-channel (1 device) bi-directional drive, or for a 2-channel (2 separate devices) uni-directional drive.
Or, you can use a half H-bridge for a 1-channel uni-directional drive.
H-bridges are frequently called "brushed motor drivers". They handle all the fancy Electrical Engineering circuitry for you.
H-bridges are excellent for driving things like:
- brushed, NOT brushless, DC motors
- high-power LEDs, assuming you have a means of current-control too, such as a large passive power resistor, or current feedback control loop and control code
- speakers (for tone's, beeps, or digital PWM-based [NOT analog-amplifier-based] music, voice, or rich audio). Ex:
- tone library
- music/rich audio PWM-based library
Here's some H-bridges you can buy:
When searching for these things, recommended search terms include "DC motor driver" or "h bridge". Even if you plan to drive an LED or speaker with it, these are still the correct search terms and parts. Just make sure what you buy accepts PWM input as the control signal is all, and that this PWM input means true PWM, NOT a servo "PWM" signal, which is very different.
Just buy one of these and be done:
- Cheap $1 L9110S H-bridge:
- Ebay search for "arduino h bridge"
- L9110 datasheet
- 2.5V to 12V supply
- 800mA max continuous current per channel
- Cheap $3 L298N H-bridge (much more powerful):
- Ebay search for "arduino h bridge L298"
- Example specs sheet: http://www.handsontec.com/dataspecs/L298N%20Motor%20Driver.pdf
- 3.2 to 40V supply
- 2A peak current
- 20W max power
- High-end, reliable, very-well-engineered DC motor drivers/H-bridges by Pololu robotics company:
- See the full list of motor drivers here! https://www.pololu.com/category/11/brushed-dc-motor-drivers
- Ex: $40 Pololu G2 High-Power Motor Driver 18v25
- 6.5V to 30V supply
- 1.8V, 3.3V, or 5V logic signals
- 25A max continuous current
- up to 100kHz PWM operation, because they have excellent MOSFET gate drivers to minimize MOSFET time in the ohmic region, and therefore MOSFET heating!
- If you're in a hurry and want high-quality, Pololu is an excellent choice!
- Tiny! 1.3" x 0.8", and no heat sink required, again, because of their excellent MOSFETS and MOSFET gate driver circuits.
Option 3 of 3: [Radio Control brushed ESC (Electronic Speed Controller)] (easiest of them all!)--preferred by people with RC vehicle experience and/or who need really high power
Important: since this option does NOT give you the low-level control over the PWM output directly, these controllers can NOT drive speakers for audio, whereas Option 1 and Option 2 drivers above can!
I'd be remissed if I didn't include this answer as well, since this is one of my specialties. This is the easiest by far! Its only downside is it gives you less fine-tuned control than controlling the low-level PWM output to the motors directly, as you can do with the motor drivers above, versus the motor controllers below. Another advantage of the hobbyist RC brushed ESCs below over the Pololu-type robotics motor drivers above is power and current: the above motor drivers from Pololu peak out at 25A continuous, for instance, whereas some RC brushed motor controllers, some less-powerful examples of which are shown below, can drive as much as 100~200A continuous, which is HUGE.
Just buy a Radio Control (RC) brushed ESC and feed it a servo PWM signal via the Arduino servo
library, NOT a true PWM signal with analogWrite()
!
You give it a servo signal, and it generates the low-level PWM to the motor automatically using its internal microcontroller and MOSFET driver circuitry, usually on the order of 8kHz~16kHz PWM output frequency. Many of these types of ESCs use the ATmega168 mcu internally.
For a single-direction ESC, such as for RC airplanes, a microsecond servo value between 700~1300us is 0% throttle, and a microsecond servo value between 1700~2100us is 100% throttle.
For a dual-direction ESC, such as for RC cars, with both forward and reverse, a microsecond value of ~1500us is 0% throttle, with ~2000us or so being 100% forward throttle and ~1000us or so being 100% reverse throttle.
Sample code:
#include <Servo.h>
Servo brushed_motor;
void setup()
{
brushed_motor.attach(9); // pin 9
// ~0% throttle (0% output PWM duty cycle), depending on ESC
// calibration, and assuming a forward-only ESC for RC airplanes
brushed_motor.writeMicroseconds(1000);
delay(2000);
// ~100% throttle (100% output PWM duty cycle), depending on ESC
// calibration, and assuming a forward-only ESC for RC airplanes
brushed_motor.writeMicroseconds(2000);
}
void loop()
{
// whatever you need here
}
To calibrate one of these ESCs to whatever throttle values you want, just set it to 2000us (full throttle) BEFORE you turn it on (careful--just in case it decides to go full throttle instead), then power it up, and it will register that as "full throttle". Next, withOUT powering it off, set it to 1000us (0% throttle), and it will register that as 0% throttle. Now, it is calibrated to have 1000us be 0% throttle and 2000us to be 100% throttle. If using an RC car brushed ESC instead of an RC airplane brushed ESC, you may have to play with it, do some research, and read its manual to get what you want, since 1500us might be considered 0% throttle, with 2000us being 100% forward throttle and 1000us being 100% reverse throttle. So, do the research.
In either case, here's some brushed RC ESCs which can drive motors and blowers or whatever just fine too.
These are just a couple examples. RC ESCs like these are designed to be really high power for high-end RC vehicles which can go up to 25~100mph sometimes, and be quite large. Do some research. Brushed RC ESCs are sold in many places. HobbyKing has the best prices in the industry for these types of things, with generally good to very-good quality parts.
Related:
- [my answer] Switching a Solenoid Using Arduino's 5V Output?
- Here's my answer to another question which answers your question. In the diagram below, from this other answer, the relay + R2 is the load. Replace this load (relay + R2) with your motor as the load instead, and this is also a perfectly legitimate circuit to solve your problem. The 5V here in this circuit to the transistor base would be replaced by your 5V logic level PWM signal coming from your Arduino. I also go over calculations and how to size all components. Try a high-current TIP120 NPN BJT 5 Amp continuous transistor in place of the 2N3904 in my circuit, and be sure to redo the calculations to size your base resistor, R1.
- Note that this circuit allows your Arduino pin to actively drive the output both HIGH and LOW, but since its through this (relatively small) base resistor, it's probably only good for PWM frequencies up to a few dozen kHz or so. An oscilloscope used to look at the output would make this clear. Increase input PWM frequency until output PWM waveform distortion becomes significant.
