Bird
Raised Fist0
Arduinoprogramming~15 mins

analogWrite() and PWM output in Arduino - Deep Dive

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Overview - analogWrite() and PWM output
What is it?
analogWrite() is a function used in Arduino programming to simulate an analog output using digital pins. It does this by rapidly switching the pin on and off, creating a signal called Pulse Width Modulation (PWM). This allows control over devices like LEDs or motors by adjusting the brightness or speed. Although it looks like an analog voltage, the output is actually a digital pulse that changes in width.
Why it matters
Without analogWrite() and PWM, controlling devices smoothly with Arduino would be difficult because most pins only output digital on/off signals. PWM lets you create effects like dimming lights or controlling motor speed without needing expensive analog hardware. This makes projects more flexible and affordable, enabling creative and precise control in electronics.
Where it fits
Before learning analogWrite(), you should understand basic Arduino digital input/output and how to write simple programs. After mastering analogWrite() and PWM, you can explore advanced motor control, LED fading effects, and even audio signal generation with Arduino.
Mental Model
Core Idea
analogWrite() controls device power by turning a pin on and off very fast, changing the ratio of on-time to off-time to simulate different voltage levels.
Think of it like...
It's like turning a faucet on and off quickly to control how much water flows out, instead of just having it fully open or fully closed.
PWM Signal:
┌─────┐     ┌─────┐     ┌─────┐
│     │     │     │     │     │
│     │     │     │     │     │
│     │     │     │     │     │
└     └─────┘     └─────┘     └─────
Time →
Duty Cycle = On Time / Total Time
Build-Up - 7 Steps
1
FoundationDigital Pins and On/Off Signals
🤔
Concept: Arduino pins can be set to HIGH or LOW, meaning fully on or fully off.
Arduino digital pins output either 5V (HIGH) or 0V (LOW). This is like a light switch that is either on or off. You can turn an LED fully on or off using digitalWrite(pin, HIGH) or digitalWrite(pin, LOW).
Result
The LED connected to the pin will be either fully lit or completely off.
Understanding that Arduino pins are digital and only have two states is the base for learning how PWM simulates analog levels.
2
FoundationWhat is PWM and Why Use It
🤔
Concept: PWM changes how long a pin stays on versus off to simulate different power levels.
Pulse Width Modulation (PWM) rapidly switches a pin between HIGH and LOW. The ratio of ON time to total cycle time is called the duty cycle. For example, 50% duty cycle means the pin is on half the time and off half the time.
Result
Devices like LEDs appear dimmer or motors run slower because they receive less average power.
PWM lets us create the effect of varying power using only digital signals, which is essential since Arduino pins can't output true analog voltages.
3
IntermediateUsing analogWrite() to Set PWM Duty Cycle
🤔Before reading on: do you think analogWrite() sets a voltage level or a timing pattern? Commit to your answer.
Concept: analogWrite() sets the duty cycle of the PWM signal on a pin using a value from 0 to 255.
The analogWrite(pin, value) function takes a value between 0 (always off) and 255 (always on). For example, analogWrite(pin, 128) sets about 50% duty cycle. This controls how bright an LED glows or how fast a motor spins.
Result
The device connected to the pin responds to the average power set by the PWM duty cycle.
Knowing that analogWrite() controls the timing pattern, not a true voltage, helps avoid confusion when measuring output with a multimeter.
4
IntermediatePWM Frequency and Its Effects
🤔Do you think changing PWM frequency affects brightness or speed directly? Commit to your answer.
Concept: PWM frequency is how fast the pin switches on and off, usually fixed but important for device behavior.
Arduino PWM frequency is typically about 490 Hz on most pins, meaning the pin switches on and off 490 times per second. Some pins have different frequencies. Changing frequency can affect how smooth the output feels or how a motor sounds.
Result
At normal frequencies, devices appear to respond smoothly; too low frequency causes flicker or noise.
Understanding frequency explains why PWM output looks steady to our eyes but is actually a fast on/off signal.
5
IntermediateLimitations of analogWrite() and PWM Output
🤔
Concept: analogWrite() only works on specific pins and does not produce true analog voltage.
Not all Arduino pins support PWM. Only pins marked with ~ can use analogWrite(). Also, the output is a digital pulse, so measuring voltage with a multimeter shows an average, not a steady voltage. Some devices need true analog signals, requiring extra hardware.
Result
You must choose the right pins and understand PWM's digital nature for correct use.
Knowing these limits prevents confusion and helps select the right approach for your project.
6
AdvancedAdvanced PWM Control and Custom Frequencies
🤔Can you change PWM frequency easily with analogWrite()? Commit to your answer.
Concept: Advanced users can change PWM frequency by manipulating Arduino timers directly for special effects or motor control.
By accessing Arduino's hardware timers, you can adjust PWM frequency beyond the default. This requires understanding of registers and timer interrupts. Changing frequency can reduce noise or improve motor performance but is more complex.
Result
You gain fine control over PWM signals but must handle more complex code and hardware details.
Knowing how to customize PWM frequency unlocks professional-level control but requires deeper hardware knowledge.
7
ExpertWhy PWM Works Despite Digital Pins Only
🤔Is analogWrite() output a real voltage or a time-based signal? Commit to your answer.
Concept: PWM tricks devices into perceiving different power levels by averaging fast on/off signals over time.
Although Arduino pins output only HIGH or LOW, devices like LEDs or motors respond to the average power they receive. The human eye or motor inertia smooths out the rapid switching, making the output appear analog. This is why PWM is effective without true analog hardware.
Result
PWM provides a cost-effective way to simulate analog control using digital pins.
Understanding this principle explains why PWM is widely used in embedded systems and why it works so well despite hardware limits.
Under the Hood
Arduino uses hardware timers to generate PWM signals. When analogWrite() is called, it configures a timer to toggle the pin on and off at a fixed frequency. The duty cycle is set by changing the timer's compare register, which controls how long the pin stays HIGH in each cycle. This happens automatically in the background, freeing the CPU to do other tasks.
Why designed this way?
PWM was chosen because Arduino's microcontrollers have limited analog output hardware. Using timers to create PWM allows precise control without extra components. This design balances cost, complexity, and functionality, making Arduino accessible and versatile.
┌───────────────┐
│ analogWrite() │
└──────┬────────┘
       │ sets duty cycle
       ▼
┌───────────────┐
│ Hardware Timer│
│ (PWM Signal)  │
└──────┬────────┘
       │ toggles pin
       ▼
┌───────────────┐
│ Digital Pin   │
│ Output PWM   │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does analogWrite() output a steady voltage like a real analog pin? Commit yes or no.
Common Belief:analogWrite() outputs a steady analog voltage between 0 and 5V.
Tap to reveal reality
Reality:analogWrite() outputs a PWM signal, a digital pulse that switches between 0V and 5V rapidly, not a steady voltage.
Why it matters:Measuring PWM output with a multimeter shows an average voltage, which can confuse beginners into thinking it's a true analog voltage, leading to wrong assumptions about circuit behavior.
Quick: Can you use analogWrite() on any Arduino pin? Commit yes or no.
Common Belief:You can use analogWrite() on all Arduino digital pins.
Tap to reveal reality
Reality:Only specific pins marked with ~ support PWM and analogWrite(). Using it on other pins has no effect or causes errors.
Why it matters:Trying analogWrite() on unsupported pins wastes time and causes bugs, especially in complex projects.
Quick: Does changing PWM frequency with analogWrite() require special code? Commit yes or no.
Common Belief:You can change PWM frequency easily by passing a parameter to analogWrite().
Tap to reveal reality
Reality:analogWrite() does not allow frequency changes; you must manipulate hardware timers directly to change frequency.
Why it matters:Assuming frequency can be changed easily leads to frustration and incorrect code when trying to optimize device behavior.
Quick: Does PWM cause visible flicker on LEDs at normal Arduino frequencies? Commit yes or no.
Common Belief:PWM always causes flickering visible to the human eye.
Tap to reveal reality
Reality:At typical Arduino PWM frequencies (~490 Hz), flicker is usually not visible because it's too fast for the eye to detect.
Why it matters:Believing PWM flickers unnecessarily can cause beginners to overcomplicate designs or avoid PWM when it's actually suitable.
Expert Zone
1
Some Arduino boards have different PWM frequencies on different pins, affecting how devices respond and requiring careful pin selection.
2
Changing PWM frequency affects timer functions used by other Arduino features like millis() or delay(), so advanced users must balance PWM control with system timing.
3
PWM resolution is limited to 8 bits (0-255), so very fine control requires additional hardware or software techniques like dithering.
When NOT to use
Avoid using analogWrite() and PWM when true analog voltage is required, such as in sensitive audio circuits or precise sensor inputs. Instead, use a digital-to-analog converter (DAC) or external analog hardware.
Production Patterns
In real projects, PWM is used for LED dimming, motor speed control, servo positioning, and audio tone generation. Professionals often combine PWM with feedback sensors and PID control loops for precise automation.
Connections
Digital Signal Processing (DSP)
PWM is a form of signal modulation used in DSP to encode analog information digitally.
Understanding PWM in Arduino helps grasp how digital systems represent analog signals, a key idea in communications and audio processing.
Human Visual Perception
PWM exploits the eye's inability to detect rapid flickering to create smooth brightness changes.
Knowing how human perception works explains why PWM can simulate analog brightness effectively without true analog signals.
Water Flow Control Systems
PWM is like controlling water flow by rapidly opening and closing a valve to adjust average flow.
This connection shows how time-based control methods apply across engineering fields, from electronics to fluid mechanics.
Common Pitfalls
#1Trying to measure PWM output voltage with a multimeter and expecting a steady voltage.
Wrong approach:analogWrite(9, 128); // Measure pin 9 voltage with multimeter expecting ~2.5V steady
Correct approach:analogWrite(9, 128); // Use an oscilloscope or LED brightness to observe PWM effect
Root cause:Misunderstanding that PWM is a digital pulse, not a steady analog voltage.
#2Using analogWrite() on a pin that does not support PWM.
Wrong approach:analogWrite(2, 200); // Pin 2 does not support PWM on many Arduino boards
Correct approach:analogWrite(3, 200); // Pin 3 supports PWM
Root cause:Not checking which pins support PWM before using analogWrite().
#3Trying to change PWM frequency by passing extra parameters to analogWrite().
Wrong approach:analogWrite(9, 128, 1000); // Attempt to set frequency to 1000 Hz (invalid)
Correct approach:// Use timer registers to change frequency, e.g., TCCR1B settings
Root cause:Believing analogWrite() has frequency control parameters when it does not.
Key Takeaways
analogWrite() uses PWM to simulate analog output by rapidly switching a digital pin on and off.
PWM controls the average power delivered to devices by changing the duty cycle, not the voltage level.
Only specific Arduino pins support PWM and analogWrite(), so pin selection is important.
PWM frequency is fixed by hardware timers and affects how devices perceive the signal.
Advanced control of PWM frequency requires direct manipulation of hardware timers beyond analogWrite().

Practice

(1/5)
1. What does the analogWrite() function do on an Arduino board?
easy
A. It sets a digital pin to HIGH or LOW.
B. It reads the voltage from an analog sensor.
C. It outputs a PWM signal to simulate an analog voltage on a digital pin.
D. It measures the frequency of a signal on a pin.

Solution

  1. Step 1: Understand the purpose of analogWrite()

    The analogWrite() function does not output a true analog voltage but uses PWM (Pulse Width Modulation) to simulate varying voltage levels on digital pins.
  2. Step 2: Compare options with function behavior

    It outputs a PWM signal to simulate an analog voltage on a digital pin. correctly describes this behavior. Options A, B, and D describe other functions or actions unrelated to analogWrite().
  3. Final Answer:

    It outputs a PWM signal to simulate an analog voltage on a digital pin. -> Option C
  4. Quick Check:

    analogWrite() = PWM output [OK]
Hint: Remember: analogWrite() controls brightness/speed via PWM [OK]
Common Mistakes:
  • Confusing analogWrite() with analogRead()
  • Thinking analogWrite() outputs true analog voltage
  • Assuming analogWrite() sets pin HIGH or LOW directly
2. Which of the following is the correct syntax to set pin 9 to half brightness using analogWrite()?
easy
A. analogWrite(9, 512);
B. analogWrite(9, 0);
C. analogWrite(9, 255);
D. analogWrite(9, 127);

Solution

  1. Step 1: Understand the value range for analogWrite()

    The analogWrite() function accepts values from 0 to 255, where 0 is off and 255 is full brightness.
  2. Step 2: Calculate half brightness value

    Half brightness is about half of 255, which is approximately 127. A uses 512 (out of range), B uses 0 (off), C uses 255 (full brightness), so D is correct.
  3. Final Answer:

    analogWrite(9, 127); -> Option D
  4. Quick Check:

    Half brightness ≈ 127 [OK]
Hint: Use values between 0-255; half is about 127 [OK]
Common Mistakes:
  • Using values above 255 (like 512)
  • Confusing digitalWrite() with analogWrite()
  • Using full brightness value instead of half
3. What will be the effect of the following code snippet on an LED connected to pin 6?
void setup() {
  pinMode(6, OUTPUT);
}

void loop() {
  analogWrite(6, 0);
  delay(1000);
  analogWrite(6, 255);
  delay(1000);
}
medium
A. The LED will blink on and off every second.
B. The LED will stay dimly lit.
C. The LED will stay fully on.
D. The LED will flicker rapidly.

Solution

  1. Step 1: Analyze analogWrite values and delays

    The code sets pin 6 to 0 (off) for 1 second, then to 255 (full brightness) for 1 second, repeatedly.
  2. Step 2: Understand LED behavior

    When the pin is 0, the LED is off; when 255, it is fully on. The delays cause the LED to stay in each state for 1 second, making it blink on and off every second.
  3. Final Answer:

    The LED will blink on and off every second. -> Option A
  4. Quick Check:

    0 and 255 with delays = blink [OK]
Hint: 0 means off, 255 means full on; delays cause blinking [OK]
Common Mistakes:
  • Thinking analogWrite(0) dims LED instead of off
  • Ignoring delay effects on LED timing
  • Assuming LED flickers rapidly without delay
4. Identify the error in this code snippet intended to fade an LED on pin 10:
void setup() {
  pinMode(10, OUTPUT);
}

void loop() {
  for (int i = 0; i <= 255; i++) {
    analogWrite(10, i);
    delay(10);
  }
  for (int i = 255; i >= 0; i--) {
    analogWrite(10, i);
    delay(10);
  }
}
medium
A. The code will work correctly and fade the LED in and out.
B. The for loop variable i should be declared outside the loop.
C. The pin 10 is not set as OUTPUT.
D. analogWrite() cannot be used with pin 10.

Solution

  1. Step 1: Check pinMode setup

    Pin 10 is correctly set as OUTPUT in setup().
  2. Step 2: Analyze the for loops and analogWrite usage

    The loops increase and then decrease the PWM value from 0 to 255 and back, with delays to create a smooth fade effect. This is a common and correct pattern.
  3. Final Answer:

    The code will work correctly and fade the LED in and out. -> Option A
  4. Quick Check:

    For loops with analogWrite create fade [OK]
Hint: For fading, increase then decrease PWM values smoothly [OK]
Common Mistakes:
  • Forgetting to set pinMode to OUTPUT
  • Thinking analogWrite can't be used on pin 10
  • Misunderstanding loop variable scope
5. You want to control the speed of a DC motor using PWM on pin 3. Which code snippet correctly sets the motor speed to 60% power?
hard
A. analogWrite(3, 60); // 60 is the percentage value
B. analogWrite(3, 153); // 60% of 255 is about 153
C. analogWrite(3, 0.6); // decimal value for 60%
D. analogWrite(3, 255); // full power always

Solution

  1. Step 1: Convert percentage to PWM value

    60% of the maximum PWM value 255 is 0.6 x 255 = 153.
  2. Step 2: Check the analogWrite parameter

    analogWrite() requires an integer between 0 and 255. analogWrite(3, 153); // 60% of 255 is about 153 uses 153, which is correct. analogWrite(3, 60); // 60 is the percentage value uses 60 which is too low, C uses a decimal which is invalid, and D sets full power.
  3. Final Answer:

    analogWrite(3, 153); // 60% of 255 is about 153 -> Option B
  4. Quick Check:

    60% x 255 = 153 [OK]
Hint: Multiply percentage by 255 for PWM value [OK]
Common Mistakes:
  • Passing percentage directly instead of scaled value
  • Using decimal numbers instead of integers
  • Always setting full power without scaling