Here we will show how you can control a DC motor using the Arduino PWM build in capability. We will be using a general purpose transistor to amplify the output signal from the Arduino PWM pin. Also we will be using diode and decoupling capacitor for extra protection and reducing noise created by the DC motor. After explanation the interfacing of the motors with Arduino, we will show and explain the code for driving and controlling DC motor using PWM. We will show how to use PWM to start the motor from zero to mid-value speed and then maximum speed and then gradually reduce its speed. PWM technique for speed control is not only used for DC motors but also for Stepper Motors.
PWM for Motor Speed Control
PWM stands for Pulse Width Modulation and is a technique of generating signal with different width of high and low pulses. The act of changing the pulse width for low and high is called modulation. When such PWM signal(series of different width pulses) is supplied to a DC motor, we can increase or decrease the amount of power supplied to the motor. This increase or decrease in power supplied to the motor is what increases or decreases the speed of the DC motor. In fact, PWM technique is so widely used to control DC motor that microcontrollers(not only Arduino or ATmega328p) have in-built PWM circuitry embedded in the chip.
Using PWM has the advantage that, although you could write in software to send PWM pulses using digitalWrite() function and changing delay, this technique would tie up the processor time. But if you use PWM feature built into the microcontroller you can use the microcontroller processor to do other task.
In Arduino most digital pin can also be used for PWM but not all, so you must first find out which pin do have PWM feature. But almost on all Arduinos, the PWM pins are 3, 5, 6, 9, 10, and 11. Arduino Due and Arduino Mega have more PWMs pin which are on pins 2 to 13. When the digital pins are used as PWM, they appear to be transmitting signalling voltage between 1 and 0 because in case of PWM the switching happens very fast. For Arduino which is 8 bit microcontroller you can select PWM level(equivalently power) from 0 to 255. The frequency of the PWM generated on the pin is 490Hz for pins 3, 9, 10 and 11 and 980Hz on pin 5 and 6 for Arduino UNO.
Hardware & Components required
For this tutorial you will the followings:
1. Arduino(USB cable too)
2. DC motor
3. General purpose transistor 2N5555
4. Resistors(1KOhm, 10KOhm)
5. Standard diode 1N4001(or 1N4007, 1N4148)
6. Capacitor(0.1uF)
7. 5V DC power supply
8. Some Wires
Wiring diagram for Arduino PWM DC motor control
In the schematic diagram as shown, we have used a general purpose transistor 2N2222 to drive the DC motor. The Arduino UNO can supply current in the range from 20mA to 40mA which might not be enough for driving DC motors. It depends upon the DC motor you are using. If your DC motor requires high current input, specially if the stall current is high, then you should probably use darlington transistor like TIP120(recommended) or motor driver IC like L293/L293D or L298. You can learn more about using L293D IC in our earlier tutorial DC Motor Control using ATmega32 and L293D. Here we are using medium sized DC motor with voltage rating of 3V to 5V. The point is that, using transistor we can increase the current into the motor.
We have connected the Arduino PWM pin 10 to the base of the 2N2222 NPN transistor via 1kOhm resistor. You could use any PWM pin on the Arduino but it must be PWM digital pin. A 10KOhm resistor is connected between the base of the transistor and ground to reduce unwanted current spikes into the base because the base is sensitive. For example, if you touch the base with your finger it could cause current into the base and the motor will rotate. This is not mandatory but it is good to include to reduce chances of accidental starting of the DC motor. The DC motor is connected as load at the collector.
The protection diode and decoupling capacitor are connected across the motor. Be careful about the diode polarity connection direction. The diode prevents back emf from motor that might destroy the transistor. The capacitor is used to reduce EMI(Electromagnetic Interference) noise created by the motor. Here a separate 5V power supply is used for the motor to reduce chances destroying the microcontroller and other control circuit. This becomes more important if you are using higher rated motors. You should not forget to connect the ground of the 5V supply with ground of the Arduino.
Transistor as DC motor driver
You might ask why transistor like 2N2222 is used here. Bipolar transistor like 2N2222 is current amplifying device which amplifies the base current by its current gain to get amplified collector current. For 2N2222 the current gain(hfe) on average is 100(max rated is 200). Thus for example, if the base current output from the Arduino is 20mA then the collector current is 100x20mA or 2000mA, theoretically, which is enough to drive DC motor.
Also the transistor acts as a switch. When the output from the Arduino pin 10 is LOW then there is no base current, the transistor is driven into cutoff region of operation and therefore there is no collector current. In this case there is no current flowing through the DC motor. When there is HIGH output signal from the Arduino pin 10, then current flows into the base driving the transistor in saturation region and the transistor is turned on. In this case, current flows from the 5V supply into the motor and through the transistor to ground.
Video demonstration of Speed control of DC motor with PWM using Arduino
Arduino Code for controlling DC motor using PWM
The DC motor control code using PWM is as shown below. In the code, we have declared motorPin as our name for the PWM pin 10 for code readability. In the setup() function, we don't need to declare pin 10 as output because later on in the loop() function we will call the analogWrite() function which will call the pinMode() function and declare the pin 10 as output. Next in the loop() function we call analogWrite() function with two arguments - the pin or pin name(motorPin) which we will be using to output PWM signal and the value of the PWM which ranges from 0 to 255 because Arduino is 8-bit microcontroller. A PWM value of 0 means no PWM and highest PWM pulse signal with highest power is 255. We start by sending lowest PWM value which is 0, wait for 1 second, then the half power PWM for which we send 127 and wait for 1 second. And finally we send PWM signal with highest power which is given by value 255 and again wait for 1 second. This process is then repeated.
/* Processor: Arduino Uno
* Compiler: Arduino AVR
* http://ee-diary.com
*/
// Name pin 10 as motorPin
int motorPin = 10;
void setup () {
// For PWM the PWM pins don't require the pinMode() function
}
void loop() {
// Turn motor on from zero
analogWrite(motorPin, 0);
// Wait 500 ms
delay(500);
// Turn motor to 1/2 the power
analogWrite(motorPin, 127);
// Wait 500 ms
delay(500);
// Turn motor to maximum speed
analogWrite(motorPin, 255);
// Wait 500 ms
delay(500);
// Turn motor to 1/2 the power
analogWrite(motorPin, 127);
// Wait 500 ms
delay(1000);
}
Further Recommended Tutorials:
Looks like a fun project! Tried it twice but did not get it working. Kind regards, Matthias