Many Arduino boards, such as the Uno and Nano, don't have the capability to output different voltages―as we discussed in our Arduino digital to analog converter (DAC) article . They can, however, rapidly cycle outputs in the form of pulse-width modulation (PWM) to simulate a varying output.
We can use two characteristics to describe an Arduino PWM (or any PWM) signal:
1. Frequency: how often pulses occur in a given period of time.
2. Duty cycle: what percentage of time the signal is on.
A 50% duty cycle signal, for instance, would have the same repeating on time and off time. Frequency tends to stay constant in a control signal. Check out our article, All About PWM, for more information on this technique.
For now, we'll address PWM as it relates directly to Arduino boards, especially in the context of the Arduino Uno with its ATmega328P microcontroller. Fortunately, we can apply these concepts to any dev board.
Image: Jeremy S. Cook
Arduino PWM LED Control
To get started with Arduino PWM LED, you can use "Fade," the PWM example that comes built into the Arduino IDE. To access this example, which you can see in the screencap above, follow these steps:
1. Navigate to the IDE and look for the name under "basics."
2. Load the example onto your board.
3. Hook up an LED, plus the appropriate resistor in series, to pin 9. You'll see your LED brighten and darken over time.
4. If you prefer, you can change the output pin number around (to 3, 5, 6, 10, and 11).
You'll also be able to modify the brightness and fade amount, and you can use this code as a template for more advanced designs.
Arduino PWM Motor Control
You can also use PWM with a DC motor. This method uses the same pulsing voltage concept, but you'll need a motor driver/transistor setup to handle a motor's higher current needs.
If you want to control a servo via PWM, stick to the Arduino environment and use one or more servo objects, such as:
- Sweep example, as seen on Arduino's website.
- Controlling a servo using an ATtiny85 under the Arduino framework.
Arduino PWM Frequency and Duty Cycle
In basic PWM discussions, frequency tends to take a back seat to the duty cycle. And in many cases, once you're above a certain point, it doesn't make much of a difference. At other times, however, frequency matters. For example, the six hardware PWM pins on an Uno run at two different default frequencies via three individual timers. These are divided up into:
- D3/D11, with a speed of 490.20 Hz.
- D5/D6, with a speed of 976.56 Hz.
- D9/D10, with a speed of 490.20 Hz.
Conveniently, you can change these frequency values as sets in code. Here's an example: TCCR2B = TCCR2B & B11111000 | B00000001 gives D3/D11 a frequency of 31,372.55Hz. You can set D5/D6 even higher with TCCR0B = TCCR0B & B11111000 | B00000001, yielding a speed of 62500.00 Hz. Values into the sub-100 Hz levels are available for all PWM pins as needed.
Whether you use it to control motors, lights, or another application, Arduino PWM is a great tool to have at your disposal. With this technique, you can do much more than power a device on and off; you can simulate a more nuanced output with a minimum of hardware.