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
[edit | edit source]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
[edit | edit source]Hook up the LED to pin 9 of the Arduino, as shown in the diagram below.
Step 2
[edit | edit source]Connect the Arduino to your computer.
Step 3
[edit | edit source]Paste the following code into Arduino and run it:
/*
Fading
This example shows how to fade an LED using the analogWrite() function.
The circuit:
* LED attached from digital pin 9 to ground.
Created 1 Nov 2008
By David A. Mellis
Modified 17 June 2009
By Tom Igoe
http://arduino.cc/en/Tutorial/Fading
*/
int ledPin = 9; // LED connected to digital pin 13
void setup() {
// nothing happens in setup
}
void loop() {
// fade in from min to max in increments of 5 points:
for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
// fade out from max to min in increments of 5 points:
for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
}
Code explanation
[edit | edit source]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
[edit | edit source]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
[edit | edit source]Try changing the delay value, and see what effect this has.
Step 6
[edit | edit source]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:
/*
Fading
This example shows how to fade an LED using the analogWrite() function.
The circuit:
* LED attached from digital pin 9 to ground.
Created 1 Nov 2008
By David A. Mellis
Modified 17 June 2009
By Tom Igoe
http://arduino.cc/en/Tutorial/Fading
*/
int ledPin = 9; // LED connected to digital pin 13
void setup() {
// nothing happens in setup
}
void loop() {
// fade in from min to max in increments of 5 points:
for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
// fade out from max to min in increments of 5 points:
for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
//Now fade back in, so we get a pulsing effect
for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
// sets the value (range from 0 to 255):
analogWrite(ledPin, fadeValue);
// wait for 30 milliseconds to see the dimming effect
delay(30);
}
}
Step 7
[edit | edit source]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
[edit | edit source]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
[edit | edit source]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
[edit | edit source]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.