Simple Arduino Motor Control

WP_20130529_001

One thing you might want to do with an Arduino or even a Raspberry Pi is control a motor. Of course, the GPIO pins on this board are really just designed to send and receive informational signals, not drive the load of something that’s going to draw any significant current like a motor. An LED is fine, but much beyond that and you really need to look at a different solution.

I simply wanted to control a motor from my Arduino. I have a little hobby motor. I measured that at 3 volts it draws 150 mA (milliAmps). The Arduino’s GPIO pins are rated at around 40 mA. So that wasn’t going to cut it. I know there are various motor controller shields that you can hook up to your Arduino for this purpose, but I didn’t think I needed to go that route. Those boards offer a lot of functionality and are great if you have a specific project in mind and need all that control without going through the hassle of figuring out how to do it. But they are also the very definition of a “black box”. You put some input into them and get some input out of them. There’s all kinds of components and chips and traces on the boards, so you don’t really have any idea what’s going on between the input and output.

150 mA - too high for Arduino's GPIO

150 mA – too high for Arduino’s GPIO

For me, it was far more important to know exactly what was going on at this stage. So I grabbed a breadboard, some components and wire, and got busy.

All you really need is a transistor, a resistor and a separate power supply for the motor. I’m not going to go into a deep explanation of transistors, because there are about 73 million deep discussions about them on the net. Basically, it’s an electronic switch with three leads called the emitter, base, and collector. You put the emitter/collector combo between the external power and your load, in this case a motor. By default, it acts as an open switch, so the motor does not run. But when you supply a small current between the base and emitter, this “closes the switch”, allowing the current to flow from collector to emitter, and your motor runs!

The important thing is that it only takes a very small control signal at the base to allow a much larger current to flow through the emitter/collector. So you can use the GPIO output signals to control the transistor, and use a separate power supply to control the motor itself without taxing your delicate little Arduino.

WP_20130529_002

The transistor I used is a PN2222 series. These are very common, general use transistors. You can get 10 of them for under $2. I checked the data sheet for this transistor and found it can handle a maximum of around 50-60 volts on the emitter/collector. (There are a few different varieties of these, so I’m just reporting averages.) So my 3 volt motor should be fine. It can also handle a peak load of 1 amp – again fine for my 150 mA motor. Motors do draw a lot more current when the first start, but this would allow me more than 6x the running current as a peak. The base/emitter voltage is around 5-6 volts max. The Arduino outputs are 5 volts, which is cutting it close, so I threw in a 1000 ohm resistor. This results in just a few milliamps being drawn from the GPIO pin, through the base of the transistor and back out the emitter.

motorcontrol

motorcontrol_bb

Then I hooked up the motor to a separate 3 volt power supply, passing it through the emitter/collector. With this setup, when the GPIO pin I choose is HIGH, the motor will run. When it’s LOW, the motor will stop. Despite the motor drawing at least 150 mA, the Arduino’s GPIO pins will only be serving up 2-3 mA about 4 mA by actual measurement – way below the 40 mA limit.

For software, I set up a simple sketch as follows:

[php lang=”c”]void setup() {
pinMode(7, OUTPUT);
}

void loop() {
digitalWrite(7, HIGH);
delay(1000);
digitalWrite(7, LOW);
delay(1000);
}[/php]

Obviously, I’m using GPIO pin 7 as an output. This will set it HIGH for one second, then low for one second, switching the motor on and off for that amount of time. And it works! And as far as I can tell, everything is within safe ranges.

So there you go. Of course, this isn’t going to give you all the features of a dedicated motor control shield, such as variable speed with pulse with modulation, multiple motors, forward/reverse, etc. But now you know exactly what’s going on and can build on it if you want. Or at least have some concept on what’s going on inside that fancy shield.

Of course, it goes without saying to be VERY careful when wiring up a circuit like this. You are hooking up an external power source to the same board that your Arduino is hooked up to. A wrong move and you could send electrons flooding into where they have no business being. That’s another advantage to using shields, which buffer the Arduino’s connections and add a layer of protection. But don’t worry too much. A little smoke won’t kill you. 🙂

WP_20130529_004

This entry was posted in Physical Computing. Bookmark the permalink.

7 Responses to Simple Arduino Motor Control

  1. Jensa says:

    Hi Keith,
    Why don’t you try to connect it to (for instance) pin 9 instead? Then you can do PWM and control the speed of the motor more easily with analogWrite(pin, speed).

    J

  2. Pup says:

    Shouldn’t there be a flyback diode somewhere on that schematic?

  3. Commi says:

    Have you ever had what they call feedback from the motor causing problems? I hear that sometimes, especially if a motor is close to the end of it’s life, it can cause feedback which could destroy your other circuits (and especially delicate things like the Arduino board)

  4. John says:

    Hello

    I appreciate that this post is about a year old but just in case some stumbles across it…

    I would recommend moving the 1k Ohm resistor into the base path for the transistor i.e. between the Output pin of the Arduino and the base of the transistor.

    In the configuration you currently have, once the transistor starts to conduct, the voltage at the emitter will appear to rise with respect to the arduino’s ground.

    If more current starts flowing in this branch (through the 1K ohm resistor) because you use a motor which requires more current or a transistor which has a lower gain, then the voltage at the emitter would rise to the point where the 5V coming out the arduino (referenced to the arduino’s ground) would be insufficient to turn on the transistor fully and you would find that your motor would not run as you expect.

    By moving the resistor to the base branch and connecting the Motor Power supply ground to the arduino ground you do two things;

    First you ensure that the voltages have a common reference, so you will be able to turn the transistor onfully

    Secondly, you limit the current into the transistor base so that the transistor and the arduino are happy.

    If you are wondering why we need to do this then let me explain;

    When the transistor is conducting it looks like a diode between the base and the emitter so there will be approximately 0.7v dropped between the two pins.

    If you connect the base straight into the arduino, then the “diode” in the transistor will try and clamp the pin voltage at 0.7V while the arduino attempts to drive the pin to 5Vs – Ultimately, the arduino will hit its 40mA output limit, and that extra power going into the transistor will kill it.

    A resistor between the arduino and the base limits the output current of the arduino so that the transistor can happily clamp the voltage at 0.7 volts and any extra drive voltage will be dropped harmlessly across the resistor.

  5. fishy says:

    What happens if you try to connect the voltage and ground supply from the arduino board instead of using the external supply?
    The GPIO pins cannot handle more than 40ma but the source pins are capable of higher ratings right?
    So if that’s true could you have used the power from your board instead of getting batteries unless the limitations of the source pins were also exceeded.

Comments are closed.