Simple Arduino Motor Control

May 29 2013 Published by under Physical Computing

Send to Kindle

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:

void setup() {
    pinMode(7, OUTPUT);
}

void loop() {
    digitalWrite(7, HIGH);
    delay(1000);
    digitalWrite(7, LOW);
    delay(1000);
}

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

Send to Kindle

4 responses so far

  • 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

  • Pup says:

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

  • 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)

Leave a Reply