3. RESULTADOS Y DISCUSIÓN
3.6. Actividades
3.6.2. Sprints de desarrollo
A motor that can only be on or off is not that useful. We need to control the speed of a motor using code. Sometimes, we want the motor at half speed; sometimes we want it faster and sometimes slower. However, the motor is connected to a digital pin, whose value can either
be maximum or nothing. How can we make this clear 1 and 0 into something in-between?
With Pulse Width Modulation or PWM.
Getting ready
Following are the ingredients needed for this recipe: f A DC motor
f A resistor between 220 ohm and 4,700 ohm
f A standard NPN transistor (BC547, 2N3904, N2222A, TIP120) or a logic-level compatible MOSFET (IRF510, IRF520)
f A standard diode (1N4148, 1N4001, 1N4007)
How to do it…
The following are the steps to control the speed of a motor using PWM: 1. Connect the Arduino GND to the long strip on the breadboard.
2. Connect one of the motor terminals to VIN or 5V on the Arduino. We use 5V if we power the board from the USB port or, if we want higher voltages, we could use an external power source, such as a battery, and connect it to the power jack on the Arduino.
3. Connect the other terminal of the motor to the collector pin on the NPN transistor or to the drain pin on the MOSFET. Check the datasheet to identify which terminal on the transistor is the collector or which terminal on the MOSFET is the drain. 4. Connect the emitter pin of the NPN transistor or the source pin of the MOSFET
5. Mount a resistor between the base or gate pin of the transistor and one PWM pin on the Arduino. These pins are generally marked with ~ next to the pin number on the board. The Arduino Uno has pins 3, 5, 6, 9, 10, and 11 as PWM pins.
6. Mount a protection diode in parallel with the motor terminals, pointing to either VIN or 5V, depending on whether an external power supply has been used or not. Schematic
This is one possible implementation. Other digital pins with PWM functionality can be used; in this example, the ninth digital pin has been used:
Code
The following code will start the motor at maximum speed and then gradually reduce its speed until it stops it:
// Declare the pin for the motor
int motorPin = 9; void setup() {
// PWM pins don't require the pinMode() function
}
void loop(){
// Turn motor on to maximum analogWrite(motorPin, 255);
// Wait 1000 ms delay(1000);
// Turn motor to 1/2 power analogWrite(motorPin, 127);
// Wait 1000 ms delay(1000);
// Turn motor off
analogWrite(motorPin, 0);
// Wait 1000 ms delay(1000); }
If the motor is connected to a different pin, simply change the motorPin
value to the value of the pin that has been used. However, it has to be a PWM-enabled pin.
How it works…
PWM is a clever trick that allows a digital pin, which can only output 1 or 0, to simulate values in-between. It works by switching the digital pin on and off very fast. For example, if we switch a digital pin on for 1 millisecond and off for another millisecond, we will be doing this on-off cycle 500 times a second. If we have a motor connected to the pin, the motor will spin at half
speed. Why? Because, first of all, we are actually giving it power half of the time, since the pin
In practice, this means we are turning it on and off, but due to the high frequency at which
we are doing it, the result will be a motor with half power. This, of course, doesn't work at low
frequencies. If we turn the motor on for a second and off for another one, the result will be a motor that is truly starting and stopping; so, the higher the frequency, the better.
This doesn't mean that we can only have half-speed. By varying the time that it is on and the
time it is off, we can obtain many speed variations. And the best part is that the Arduino has an inbuilt library to handle this. The following diagram shows how all of this works in a more graphic way:
We can see in the first part of the graphic that we are mostly keeping the pin LOW, to 0 V,
and thus the average voltage output is quite low. In the middle of the graphic, we are roughly keeping the pin HIGH and LOW for an equal amount of time, and the resulting voltage is half. In the last part, we see that the time the pin is HIGH is called Pulse Width. The total time between the beginning of each pulse is called the period of the PWM signal.
A few pins on the Arduino are PWM-enabled and can be used to generate this PWM signal. On almost all Arduinos, the PWM pins are 3, 5, 6, 9, 10, and 11. The exceptions are the Arduino Due and Mega, which have more PWMs on pins 2 to 13.
Almost all Arduinos can output 8-bit PWM signals at a frequency of 490 Hz Exceptions are the newer boards such as the Uno that, for pins 5 and 6, output 980 Hz. An 8-bit PWM means that we can output a level between 0, which is the equivalent of LOW, up to 255, which is the equivalent of HIGH. The middle is roughly at 127.
Code breakdown
The code uses the analogWrite() function, which outputs a PWM signal on a PWM-enabled
pin, at the specified level:
This function will output the PWM signal at the value of 127, which is roughly half of the 0–255 range. Other values can be provided, such as 85 for one-third and 170 for two-thirds. A very good thing to remember is that the analogWrite() function used on PWM-
compatible pins will not use the processor continuously. Once we call analogWrite()
at a specific level, the code execution will continue and the PWM signal will be generated continuously, until stopped. This is a very good thing because we can leave all PWM at the levels we want and then execute the rest of the code with no interruption.
There's more…
The PWM pins are very useful. Any load can be controlled with them; for example, LED intensity, motors, or speakers. In order to use multiple PWM pins, in the analogWrite() pin value, we just need to modify the pin argument to the pin we want to change.