How to control the speed of a 12V DC motor with an Arduino?

I'm trying to figure out how to control the speed of a 12V DC motor with an arduino and a 12V battery.

I want to split the «power» and «control» parts of the circuit so the Arduino and sensors receive only 5V.

So far, this is what I've tried :

I am able to control the speed of the motor by changing the PWM of pin 3 on the Arduino. This opens the NPN transistor (BUF654).

The problem is that the speed of the motor doesn't change enough.

From 0% to 50% PWM on pin 3, the motor is stalled.

Above 50%, the motor is nearly reaching its maximum speed.

I wonder if I would be able to have a linear variation :

0% - 10% : very slow
10% - 20% : slow
20% - 50% : normal speed
50% - 80% : fast
80% - 100% : RELEASE THE KRAKEN!


Here are the voltage and current the motor draws when using only a battery, or the previous circuit :

+----------------------------+---------+--------+
| Directly on 12V battery    | 12.7 V  | 61 mA  |
+----------------------------+---------+--------+
| Arduino circuit (100% PWM) | 12.47 V | 60 mA  |
+----------------------------+---------+--------+
| Directly on 9V battery     | 9 V     | 54 mA  |
+----------------------------+---------+--------+
| Arduino circuit (60% PWM)  | 9 V     | 52 mA  |
+----------------------------+---------+--------+


What have I done wrong? Could the problem come from my motor?

• Is that diode connected across the transistor? Commented Mar 6, 2014 at 15:20
• Yes it is. It prevents damaging the components when the motor stops (current reverses). Commented Mar 6, 2014 at 15:27
• Is there a specific advantage to use this transistor instead of the classic L293D?
– maxy
Commented Mar 6, 2014 at 19:53
• I'm quite new to transistors, and I don't know the «classic» ones. Any reason to use the L293D? Commented Mar 6, 2014 at 23:45
• Built-in clamping diods, ability to reverse the direction. I don't know if BUF654 is a good or bad choice for this. But the L293D datasheet specifically shows driving motors coils as the main application, while the BUF654 datasheet doesn't.
– maxy
Commented Mar 8, 2014 at 11:40

3 Answers

Your diode is in the wrong position- it should be across the motor (blocking!) not across the transistor.

The purpose of the diode is to allow current that is flowing in the motor coil to continue to flow in the same direction when the transistor turns off. When the transistor turns off, the voltage at the transistor collector will rise as it was flowing out of the motor. From $V_{CE(SAT)}$ it will rise above the power supply voltage and stop only when the transistor breaks down (or when it starts to ring with parasitic capacitance). By putting a diode from the transistor collector to the +12V rail, you prevent the voltage across the transistor from exceeding 12V and and allow the motor current to continue to flow.

The way you have the diode in your pictorial, it would only conduct were the voltage to go below ground. That could only happen if someone mechanically spun the motor very fast in the reverse direction (and your diode would cause the voltage on the 12V rail to increase as a result).

• I don't see why it should be across the motor, as it is supposed to rotate in both directions (using a DPDT switch AFTER the transistor). Lots of tutorials I've read used the diode acress the transistor to prevent damages to the components. If I missed something, can you explain it please? Commented Mar 6, 2014 at 15:33
• Okay, it should be across where the motor is NOW. We have no way of knowing what you might have in mind. If you add a DPDT switch it would be across the switch common terminals (or, more simply, from the transistor collector to the +12 rail). Commented Mar 6, 2014 at 15:34
• I understand your point, but I don't understand why it would change something. The only difference in this case is it prevents current from flowing through the transistor when reversed. If I put the diode across the motor (or the DPDT switch in my case), could that break the transistor if too much current flow back? Commented Mar 6, 2014 at 15:39
• Thanks for your edit, it is much clearer now :) I'll give it a try. I think I misunderstood the purpose of this tiny thing. Commented Mar 6, 2014 at 15:41
• No it will protect the transistor. Current that should be flowing through your motor (creating torque) is being mostly wasted heating the transistor. That's why you're not getting much torque. Commented Mar 6, 2014 at 15:42

Albeit the diode is in an unusual position, the circuit works well. Usually the diode is placed across the inductive load - i.e. across the motor pins - very close to the motor (if you use long wires, this is important). This helps to suppress electric spikes generated by the motor when you stop it but it keeps rotating and acts as a generator for a very short fraction of time.

These spikes can kill your transistor. The other solution - what you have done - is to protect the transistor itself.

You shall note that it is impossible to make a DC motor turn very slowly. This comes from the mechanical structure of the motor. If you're using a motor without gear reduction, you'll see that 30%-100% pwm makes some difference, while 0..30% does nothing. With geared motor (the gears are extra load), you may need go to to 50% just to make it start.

You can do a few things:

• use the map function to map your 0..100% power needs to 50..80% of PWM output. Note that the speed is not always linear to the pwm input, so you may need a linerization table to fix that.
• if your goal is to have a motor which can rotate extremelly slow, consider using a stepper motor. If you need extremelly slow and mid range, this is good.
• If you need from extremelly slow to extremelly fast, you'll better go with two motors, and a differential gearbox, if you're good at mechanics
• Another solution is to use a three phase AC motor and drive that with the microcontroller. This solution is not a beginners' topic, but this is the de-facto solution for todays electric vehicles. The trick is that the motor windings are always energized, therefore you have a constant torque. While changing the frequency of the driving waveform, you have a very precise control over speed.

Could it be static friction? What happens if your arduino sketch first starts the motor (maximum PWM) and then slowly decreases over several seconds?

My experience is that it's very hard to run a DC motor slowly (unless you have position feedback of course, or gears).

• Sorry, my first question wasn't clear enough. I'm using gears and the very slow motion I want is out of the gearbox. Commented Mar 6, 2014 at 23:46