Arduino/Analog output

In this activity, we show how to dim an LED using a technique called PWM, which stands for Pulse Width Modulation.

Introduction
PWM is a technique for getting analog results with digital means. Digital control is used to create a square wave, which is a signal switched between on and off. This on-off pattern can simulate voltages in between full on (5 Volts) and off (0 Volts) by changing the portion of the time the signal spends on versus the time that the signal spends off. The duration of "on time" is called the pulse width. To get varying analog values, you change, or modulate, that pulse width. If you repeat this on-off pattern fast enough with an LED for example, the result is as if the signal is a steady voltage between 0 and 5v controlling the brightness of the LED.

In the graphic below, the space between each pair of green lines represents a regular time period of two milliseconds.



Step 1
Hook up the LED to pin 9 of the Arduino, as shown in the diagram below.



Step 2
Connect the Arduino to your computer.

Step 3
Paste the following code into Arduino and run it:

Code explanation
We have two new concepts here. The first is the “for” loop. This is a kind of control structure. This is used when we want to repeat a block of code over and over again until some condition is satisfied.

The statements inside the parentheses are what controls the conditions of the for loop. The first one sets up the loop. It is called every time the loop starts. In this example, we create an integer called “fadeValue” and set it to 255.

The next statement is checked every time the loop repeats. If it is true, the loop repeats again. If it is false, the loop stops. In this case, we check if the “fadeValue” is greater than or equal to zero.

The last statement is also run every time the loop repeats, but at the end instead of the start. In this case, we decrease the “fadeValue” by 5 every time.

The second new concept is the “analogWrite” function. This is the function that writes an analog value (PWM wave) to a pin. As such, it requires two arguments: first, the relevant pin and, second, a value between 0 and 255. Since a call to analogWrite is made on a scale of 0 - 255, analogWrite(pin, 255) requests a 100% duty cycle (always on) and analogWrite(pin, 127) a 50% duty cycle (on half the time) for example. It can be used to light an LED at varying brightnesses, like we do here, or drive a motor at various speeds, among other things.

After a call to analogWrite, the pin will generate a steady square wave of the specified duty cycle until the next call to analogWrite, or a call to digitalRead or digitalWrite on the same pin.

Generally, on current Arduinos, analogWrite only works on pins 3, 5, 6, 9, 10, and 11.

Step 4
Try changing the numbers in the for loop, and see what effect this has on the LED. You can change the initial value (currently 255), the final value (currently 0) and the step value (currently negative 5).

Step 5
Try changing the delay value, and see what effect this has.

Step 6
Using copy and paste, make a second copy of the for loop beneath the first one. In this second loop, change the initial value to 0, the final value to 255, and the step value from negative to positive 5. Also, change the greater than sign to a less than sign. The code should now look like the following:

Step 7
Try changing the values in the second loop, the way you did in steps 4 and 5, and see what effect this has.

Step 8
Make some more copies of the loop and use different values in each one. Can you think of other ways to produce different patterns, other than just making new loops one after the other?

Step 9
Once you get this running, grab your Arduino and shake it back and forth. What you are doing here is essentially mapping time across the space. To our eyes, the movement blurs each LED blink into a line. As the LED fades in and out, those little lines will grow and shrink in length. Now you are seeing the pulse width.

Attribution
Certain portions of this course are based on the Arduino documentation for PWM and used with permission under the CC-BY-SA 3.0 license.