Inquire: Call 0086-755-23203480, or reach out via the form below/your sales contact to discuss our design, manufacturing, and assembly capabilities.
Quote: Email your PCB files to Sales@pcbsync.com (Preferred for large files) or submit online. We will contact you promptly. Please ensure your email is correct.
Notes: For PCB fabrication, we require PCB design file in Gerber RS-274X format (most preferred), *.PCB/DDB (Protel, inform your program version) format or *.BRD (Eagle) format. For PCB assembly, we require PCB design file in above mentioned format, drilling file and BOM. Click to download BOM template To avoid file missing, please include all files into one folder and compress it into .zip or .rar format.
When I first started working with microcontrollers in PCB design projects, one concept kept coming up: PWM. After years of implementing PWM in everything from LED dimming circuits to motor control systems, I’ve learned that understanding Pulse Width Modulation is fundamental to getting the most out of your Arduino projects.
This Arduino PWM tutorial will walk you through everything you need to know about generating analog-like outputs using digital pins, complete with practical examples and real-world applications.
What is PWM and Why Does It Matter?
PWM stands for Pulse Width Modulation. It’s a technique where we rapidly switch a digital signal on and off to simulate an analog voltage output. Think of it like rapidly flicking a light switch – if you do it fast enough, the light appears dimmed rather than blinking.
In practical terms, instead of outputting a constant 2.5V (which Arduino can’t do directly), PWM outputs a 5V signal that’s on 50% of the time and off 50% of the time. The average voltage delivered to the component is 2.5V, achieving our analog effect through digital means.
The key advantage? Microcontrollers like Arduino can only output HIGH (5V) or LOW (0V) digitally. PWM lets us effectively create any voltage between 0V and 5V without additional hardware like DACs.
Understanding PWM Fundamentals
The Duty Cycle Concept
The duty cycle determines what percentage of time the signal stays HIGH during each cycle. In this Arduino PWM tutorial, you’ll see duty cycle expressed as a value from 0 to 255 in Arduino code.
Here’s the relationship:
Duty Cycle (%)
Arduino Value
Effective Voltage
Common Use
0%
0
0V
Completely OFF
25%
64
1.25V
Very dim LED
50%
127
2.5V
Half brightness
75%
191
3.75V
Bright LED
100%
255
5V
Full brightness
PWM Frequency Matters
Arduino boards typically generate PWM at approximately 490 Hz (on most pins) and 980 Hz (on pins 5 and 6 on Uno). From a PCB engineering standpoint, this frequency affects several things:
490 Hz is fast enough for:
LED brightness control (human eye can’t detect flicker above ~50 Hz)
Basic motor speed control
Heating element control
490 Hz might be too slow for:
Audio applications (creates audible whine)
High-performance motor control
Switch-mode power supplies
Arduino PWM Pin Configuration
Not all Arduino pins support PWM. This is a hardware limitation based on the timers built into the ATmega microcontroller.
Arduino Uno PWM Pins
On the Arduino Uno, you’ll find PWM capability on pins 3, 5, 6, 9, 10, and 11. These pins are marked with a tilde (~) symbol on the board.
Pin Number
Timer Used
Default Frequency
Notes
3
Timer 2
490 Hz
Shares timer with pin 11
5
Timer 0
980 Hz
Also used for millis()
6
Timer 0
980 Hz
Also used for millis()
9
Timer 1
490 Hz
16-bit timer
10
Timer 1
490 Hz
16-bit timer
11
Timer 2
490 Hz
Shares timer with pin 3
Other Popular Arduino Boards
Arduino Mega 2560: Pins 2-13 and 44-46 support PWM (15 total pins) Arduino Nano: Same as Uno – pins 3, 5, 6, 9, 10, 11 Arduino Due: All digital pins support PWM with 12-bit resolution
Basic Arduino PWM Tutorial: Your First Program
Let’s start with the classic LED fading example. This demonstrates the fundamental analogWrite() function:
In my workshop, I always connect a 220Ω resistor in series with the LED to protect both the LED and the Arduino pin (max 40mA per pin).
Practical PWM Applications
DC Motor Speed Control
One of the most common uses of PWM in my projects is controlling DC motor speed. Here’s a practical implementation:
int motorPin = 10;
int potPin = A0;
void setup() {
pinMode(motorPin, OUTPUT);
}
void loop() {
int potValue = analogRead(potPin); // Read 0-1023
int motorSpeed = map(potValue, 0, 1023, 0, 255); // Convert to 0-255
analogWrite(motorPin, motorSpeed);
delay(10);
}
Important note from my experience: Always use a motor driver IC (like L298N or L293D) between Arduino and motors. Direct connection can damage your Arduino due to back-EMF.
RGB LED Color Mixing
PWM shines (literally) when controlling RGB LEDs:
int redPin = 9;
int greenPin = 10;
int bluePin = 11;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
}
void setColor(int red, int green, int blue) {
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
void loop() {
setColor(255, 0, 0); // Red
delay(1000);
setColor(0, 255, 0); // Green
delay(1000);
setColor(0, 0, 255); // Blue
delay(1000);
setColor(255, 255, 0); // Yellow
delay(1000);
}
Servo Motor Control
While servo control technically uses PWM, Arduino provides a dedicated Servo library. However, understanding PWM helps you grasp why servos need specific pulse widths:
Pulse Width
Servo Position
Duty Cycle (20ms period)
1.0 ms
0°
~5%
1.5 ms
90°
~7.5%
2.0 ms
180°
~10%
Advanced PWM Techniques
Modifying PWM Frequency
Sometimes the default 490 Hz isn’t suitable. I’ve had projects where LED drivers created audible noise, or motors needed higher frequencies. You can modify timer prescalers to change PWM frequency:
void setup() {
// Set PWM frequency for pins 9 and 10 to 31250 Hz
TCCR1B = TCCR1B & 0b11111000 | 0x01;
}
Warning: Changing timer registers affects other functions. Timer 0 modifications will break millis() and delay().
Timer
Affected Pins
Default Frequency
Prescaler Options
Timer 0
5, 6
980 Hz
Don’t modify (breaks timing)
Timer 1
9, 10
490 Hz
31250 Hz to 122 Hz
Timer 2
3, 11
490 Hz
31250 Hz to 122 Hz
Software PWM for Non-PWM Pins
In some designs, I’ve needed PWM on pins without hardware support. Software PWM is possible but CPU-intensive:
unsigned long previousMicros = 0;
int period = 2000; // 2000 microseconds = 500 Hz
int dutyCycle = 128; // 0-255
void loop() {
unsigned long currentMicros = micros();
unsigned long elapsed = currentMicros – previousMicros;
if(elapsed < (period * dutyCycle / 255)) {
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(LED_PIN, LOW);
}
if(elapsed >= period) {
previousMicros = currentMicros;
}
}
Common Pitfalls and Solutions
Problem 1: LED Not Dimming Smoothly
Issue: LED appears to flicker or doesn’t dim linearly. Solution: Human eye perception is logarithmic. Use gamma correction:
Issue: Using analogWrite() for servo control causes erratic movement. Solution: Always use the Servo library for servos – analogWrite() PWM frequency is wrong for servo control.
Measuring and Debugging PWM Signals
As a PCB engineer, I rely on these tools for PWM debugging:
Oscilloscope: Essential for viewing actual waveforms, measuring frequency and duty cycle Multimeter (in frequency mode): Quick frequency checks Logic Analyzer: Excellent for multi-channel PWM timing analysis LED + Resistor: Simple visual confirmation that PWM is working
Hardware Considerations for PWM Projects
Current Limitations
Each Arduino pin can source/sink approximately 40mA maximum. For most PWM applications:
LEDs: Use current-limiting resistors (220Ω for 5V, standard LEDs)
Motors: Always use driver ICs (L298N, L293D, TB6612FNG)
High-current loads: Use MOSFETs or relays triggered by PWM
PCB Layout Tips
When designing PCBs with PWM outputs:
Keep PWM traces short to minimize EMI
Use ground planes for noise reduction
Add decoupling capacitors (0.1µF) near driver ICs
Separate analog ground from digital ground when using precision analog sensors
Consider RC filters on PWM outputs if you need true analog voltage
Useful Resources and Tools
Official Documentation:
Arduino Language Reference: https://www.arduino.cc/reference/en/
ATmega328P Datasheet: Available from Microchip’s website
Software Tools:
Arduino IDE: Free download from arduino.cc
Fritzing: Circuit diagram and PCB design tool
PlatformIO: Advanced IDE for embedded development
Libraries:
Servo Library: Built into Arduino IDE
PWM Frequency Library: Search “PWM Frequency library” on GitHub
FastLED: Advanced LED control with gamma correction
Hardware Tools:
Digital Multimeter with frequency measurement
USB Logic Analyzer (Saleae or compatible)
Oscilloscope (even entry-level models work)
Learning Resources:
Nick Gammon’s Timer Tutorials: Comprehensive timer/PWM guides
Electronics Stack Exchange: Community troubleshooting
AVR Freaks Forum: Deep technical discussions
Real-World Project Examples
Home Automation Dimmer
I recently designed a room lighting controller using PWM:
Q: Can I use PWM to generate audio tones on Arduino?
A: Yes, but with limitations. The tone() function is better suited for audio as it can generate precise frequencies. PWM at 490 Hz creates audible humming in most applications. For music projects, use tone() or dedicated audio libraries with better frequency control and waveform shaping.
Q: Why does my motor make noise when using PWM control?
A: Motors produce audible noise when PWM frequency is below roughly 20 kHz. Arduino’s default 490 Hz is well within human hearing range (20 Hz – 20 kHz). You can reduce noise by increasing PWM frequency by modifying timer prescalers, though this requires direct register manipulation. Alternatively, use motor driver ICs with built-in high-frequency PWM.
Q: Can I damage my Arduino with PWM?
A: PWM itself won’t damage Arduino, but connecting high-current loads directly to PWM pins will. Each pin handles maximum 40mA. Always use appropriate drivers (MOSFETs, motor drivers, relay modules) for loads exceeding this limit. I’ve seen countless burned-out pins from direct motor connections – don’t learn this lesson the hard way.
Q: How many PWM devices can I control simultaneously?
A: Arduino Uno has 6 hardware PWM pins, so you can control 6 devices with hardware PWM. For more devices, use software PWM (less accurate, CPU-intensive), PWM expansion boards (like PCA9685 with I2C – controls up to 16 channels), or multiplexing techniques. I’ve successfully controlled 12 RGB LEDs (36 channels) using PCA9685 modules.
Q: What’s the difference between PWM and true analog output?
A: PWM rapidly switches between HIGH and LOW to simulate analog voltage through averaging. True analog (from a DAC) provides continuous voltage levels. PWM works perfectly for motors, LEDs, and heating elements where inertia smooths the signal. For precision analog requirements (like audio or sensitive analog circuits), use dedicated DAC modules. Arduino Due has built-in DACs on pins DAC0 and DAC1.
Conclusion
Understanding PWM is crucial for any Arduino project involving analog-like control. Throughout my years designing embedded systems and PCBs, I’ve found that mastering this Arduino PWM tutorial opens doors to countless applications – from simple LED dimmers to complex motor control systems.
The key takeaways: PWM simulates analog output digitally, duty cycle determines effective voltage, only specific pins support hardware PWM, and most applications need supporting hardware (drivers, filters, or protection circuits).
Start with simple LED fading projects to build intuition, then progress to motors and more complex applications. Pay attention to current limitations, use proper driver circuits, and don’t be afraid to experiment with different frequencies for your specific needs.
Whether you’re dimming LEDs, controlling motor speeds, or mixing RGB colors, PWM gives you precise analog-like control with minimal hardware complexity. Now go build something amazing!
Inquire: Call 0086-755-23203480, or reach out via the form below/your sales contact to discuss our design, manufacturing, and assembly capabilities.
Quote: Email your PCB files to Sales@pcbsync.com (Preferred for large files) or submit online. We will contact you promptly. Please ensure your email is correct.
Notes: For PCB fabrication, we require PCB design file in Gerber RS-274X format (most preferred), *.PCB/DDB (Protel, inform your program version) format or *.BRD (Eagle) format. For PCB assembly, we require PCB design file in above mentioned format, drilling file and BOM. Click to download BOM template To avoid file missing, please include all files into one folder and compress it into .zip or .rar format.