Calculate prescaler, OCR/ICR register values, and generate Arduino C++ code for any PWM frequency
Pulse-Width Modulation (PWM) is one of the most powerful features built into the AVR microcontroller at the heart of Arduino boards. By rapidly switching an output pin between HIGH and LOW states, PWM allows an Arduino to simulate analog output — dimming LEDs, controlling motor speed, generating audio tones, and driving servo motors — all without a digital-to-analog converter. The key to unlocking custom PWM frequencies lies in understanding the timer hardware, its prescaler, and the compare registers that determine both the output frequency and duty cycle. At 16 MHz, the Arduino Uno and Nano (ATmega328P) run three hardware timers: Timer0 (8-bit), Timer1 (16-bit), and Timer2 (8-bit). Timer0 is special because the Arduino core uses it for millis(), delay(), and micros() — modifying it will break those built-in functions. Timer1 is the most flexible: as a 16-bit timer with variable-TOP modes, it can produce frequencies from 0.24 Hz all the way up to 8 MHz, making it ideal for servo libraries, audio generation, and precision motor control. Timer2 also supports extra prescaler values (32 and 128) that give it slightly different frequency options compared to Timer0 and Timer1. The Arduino Mega (ATmega2560) adds Timer3, Timer4, and Timer5 — three additional 16-bit timers, each with three output compare channels (A, B, and C). This gives the Mega twelve independent PWM channels capable of high-resolution frequency control, which is why it is the preferred board for robotics, multi-servo projects, and CNC applications. Choosing the right PWM frequency matters enormously for your application. For motor control, frequencies below 20 kHz produce audible whine; frequencies above 20 kHz are inaudible but may reduce efficiency due to switching losses. LED dimming at frequencies below 100 Hz causes visible flicker. Audio applications need precise frequency control to hit musical pitches. RC servo motors expect 50 Hz signals with a specific pulse width. Understanding how to configure the timer registers lets you tune the Arduino's PWM output for any of these requirements. The two core PWM modes on AVR timers are Fast PWM and Phase Correct PWM. Fast PWM counts from BOTTOM to TOP in a single direction, producing a higher effective frequency — ideal for power conversion and rapid switching. Phase Correct PWM counts up to TOP and then back down (dual slope), which produces exactly half the frequency of Fast PWM but centers the pulse symmetrically — this symmetry is critical for motor control because it reduces ripple current and electromagnetic interference. CTC (Clear Timer on Compare) mode is primarily used for interrupt-driven timing rather than direct PWM output. The prescaler divides the 16 MHz system clock before it reaches the timer, slowing down the count rate. Timer0 and Timer1 offer prescalers of 1, 8, 64, 256, and 1024. Timer2 adds 32 and 128 as intermediate options. Selecting a smaller prescaler gives faster counting and higher maximum frequencies but limits the achievable minimum frequency. Larger prescalers unlock very low frequencies at the cost of resolution — the number of discrete steps available for duty cycle control shrinks as the TOP register value decreases. The TOP register value is the other half of the equation. For 8-bit timers in fixed modes, TOP is always 255, and only the prescaler can change the output frequency. For 16-bit timers in variable-TOP modes (ICR1 or OCR1A), both the prescaler and the TOP value work together — this dual control allows extremely precise frequency targeting with minimal error. The duty cycle is then set by writing a compare value (OCR1A or OCR1B) as a fraction of TOP. This Arduino PWM Frequency Calculator handles all the complexity automatically. Select your board (Uno/Nano or Mega), choose the timer, pick Fast PWM, Phase Correct PWM, or CTC mode, enter your desired frequency and duty cycle percentages, and the calculator instantly computes the optimal prescaler, TOP value, OCR register values, TCCR register hex codes, CS bit patterns, WGM bit encoding, and a complete copy-paste Arduino C++ sketch. The prescaler comparison table shows all valid prescaler options with their achieved frequencies and percentage errors so you can make an informed choice. The SVG waveform diagram gives you an immediate visual confirmation of your duty cycle setting.
Understanding Arduino PWM Timer Configuration
What Is PWM on Arduino?
Pulse-Width Modulation (PWM) is a technique where a digital output is switched on and off at a fixed frequency, but the proportion of time it spends HIGH (the duty cycle) is varied. Because the switching happens faster than the load can respond, the load sees an effective average voltage proportional to the duty cycle. Arduino boards generate PWM using hardware timers — dedicated counters inside the AVR microcontroller that run independently of the CPU. When the counter value matches a compare register (OCRnA or OCRnB), the corresponding output pin toggles state automatically. This hardware approach allows precise, jitter-free PWM without consuming CPU cycles in a polling loop.
How Are PWM Frequencies Calculated?
The output frequency depends on three factors: the system clock (16 MHz for most Arduinos), the prescaler that divides the clock, and the TOP value that determines how high the counter counts before resetting. For Fast PWM on an 8-bit timer: f = f_clk / (N × 256), where N is the prescaler. For Phase Correct PWM on an 8-bit timer: f = f_clk / (N × 510) — the factor 510 accounts for counting up 255 steps and back down 255 steps. For 16-bit Timer1 in Fast PWM with variable TOP: f = f_clk / (N × (1 + TOP)), so TOP = (f_clk / (N × f_desired)) − 1. The duty cycle register value is: OCR = TOP × (duty% / 100). The calculator iterates all valid prescaler values, computes the closest achievable TOP for each, and selects the combination that minimizes the frequency error percentage.
Why Does PWM Frequency Matter?
The default analogWrite() frequency on Arduino Uno is 490 Hz for most pins and 980 Hz for pins 5 and 6. These defaults work for simple LED dimming but are audible when driving motors or speakers. For motor control using an H-bridge or MOSFET, a PWM frequency above 20 kHz eliminates coil whine. For audio output, the frequency must be high enough that the carrier does not interfere with the audible signal (typically 32 kHz or higher). For RC servos, exactly 50 Hz is required. For switching power supplies, the optimal frequency is a tradeoff between switching losses and filter size. Setting the wrong frequency can damage components, cause heating, or produce interference.
한계 및 고려사항
Modifying Timer0 on Arduino Uno/Nano breaks millis(), delay(), and micros() because those functions rely on Timer0 overflow interrupts. Use Timer1 or Timer2 for custom PWM whenever possible. 8-bit timers (Timer0, Timer2) cannot achieve frequencies as low as 16-bit Timer1 because their fixed TOP of 255 leaves fewer prescaler steps between the minimum and maximum. Very high frequencies (above 1 MHz) may exceed what your circuit can respond to — signal integrity, PCB trace inductance, and driver capability all matter. The calculated register values assume a perfect 16 MHz crystal; actual Arduino crystals have a tolerance of typically ±50 ppm, resulting in a small but real frequency error. The Phase & Frequency Correct PWM mode (WGM modes 8 and 9) is not included here — it is identical to Phase Correct at steady state but preserves phase symmetry during dynamic TOP changes.
공식
For Fast PWM mode (single-slope counting). f_clk is the system clock (16 MHz), N is the prescaler value, and TOP is the timer's maximum count value (255 for 8-bit fixed, or ICR1/OCR1A for 16-bit variable). Rearranged: TOP = (f_clk ÷ (N × f_desired)) − 1.
For Phase Correct PWM mode (dual-slope counting up and down). Exactly half the frequency of Fast PWM for the same prescaler and TOP, because the counter traverses TOP steps twice per cycle. Preferred for motor control due to symmetric pulse centering.
Sets the duty cycle by specifying when the output pin toggles within the counting cycle. OCR = 0 gives ~0% duty, OCR = TOP gives ~100% duty. Resolution in bits = log₂(TOP + 1).
The number of discrete duty cycle steps available. Higher TOP values give finer duty cycle control. For 8-bit timers with fixed TOP=255, resolution is always 8 bits (256 steps). For 16-bit Timer1, resolution depends on the chosen TOP value.
Reference Tables
Arduino Uno/Nano Timer Overview (ATmega328P, 16 MHz)
| Timer | Bits | Prescalers | PWM Pins | 메모 |
|---|---|---|---|---|
| Timer0 | 8-bit | 1, 8, 64, 256, 1024 | D5 (OC0B), D6 (OC0A) | Used by millis/delay — avoid modifying |
| Timer1 | 16-bit | 1, 8, 64, 256, 1024 | D9 (OC1A), D10 (OC1B) | Most flexible — variable TOP via ICR1 |
| Timer2 | 8-bit | 1, 8, 32, 64, 128, 256, 1024 | D3 (OC2B), D11 (OC2A) | Extra prescaler values (32, 128) |
Common PWM Frequencies and Applications
| Application | Typical Frequency | Timer / Mode | 메모 |
|---|---|---|---|
| RC Servo Control | 50 Hz | Timer1, Fast PWM | 1–2 ms pulse width within 20 ms period |
| LED Dimming | 500–1000 Hz | Any timer, Fast PWM | Above 100 Hz to avoid visible flicker |
| DC Motor (silent) | 20–25 kHz | Timer1, Phase Correct | Above human hearing range |
| Audio Carrier | 31.25–62.5 kHz | Timer1/2, Fast PWM | 8-bit resolution at these frequencies |
| Switching PSU | 50–200 kHz | Timer1, Fast PWM | Higher freq = smaller filter components |
| Default analogWrite() | 490 / 980 Hz | Timer0/1/2, Phase Correct | Arduino's built-in defaults |
Worked Examples
50 Hz Servo Signal on Timer1
f_desired = 50 Hz, f_clk = 16,000,000 Hz
Try prescaler N = 8: TOP = (16,000,000 ÷ (8 × 50)) − 1 = 40,000 − 1 = 39,999
39,999 fits in 16-bit register (max 65,535) — valid
Actual frequency = 16,000,000 ÷ (8 × 40,000) = 50.000 Hz — exact match
Duty cycle OCR = round(39,999 × 7.5 ÷ 100) = round(3,000) = 3,000
1.5 ms pulse = 3,000 × (8 ÷ 16,000,000) = 1.5 ms — confirmed
25 kHz Silent Motor PWM
Phase Correct: f = f_clk ÷ (2 × N × TOP), so TOP = f_clk ÷ (2 × N × f)
Try prescaler N = 1: TOP = 16,000,000 ÷ (2 × 1 × 25,000) = 320
320 fits in 16-bit register — valid
Actual frequency = 16,000,000 ÷ (2 × 1 × 320) = 25,000 Hz — exact
Duty cycle OCR = round(320 × 60 ÷ 100) = 192
Resolution = log₂(321) ≈ 8.33 bits (321 discrete duty cycle steps)
1 kHz LED Dimming on 8-bit Timer2
Fast PWM 8-bit: f = f_clk ÷ (N × 256)
Solve for N: N = f_clk ÷ (256 × f) = 16,000,000 ÷ (256 × 1,000) = 62.5
62.5 is not a valid prescaler. Available: 1, 8, 32, 64, 128, 256, 1024
N = 64: f = 16,000,000 ÷ (64 × 256) = 976.56 Hz (error: −2.3%)
N = 32: f = 16,000,000 ÷ (32 × 256) = 1,953.13 Hz (error: +95.3%)
Best match is N = 64 at 976.56 Hz
OCR2A = round(255 × 25 ÷ 100) = 64
How to Use the Arduino PWM Frequency Calculator
Select Your Board and Timer
Choose Arduino Uno/Nano for ATmega328P or Arduino Mega for ATmega2560. Then select the timer you want to configure: Timer0 (8-bit, avoid — used by millis/delay), Timer1 (16-bit, most flexible), Timer2 (8-bit, extra prescaler options), or Timer3/4/5 (Mega 16-bit). The calculator automatically adjusts available prescalers and output pins based on your selection.
Choose PWM Mode and Enter Frequency
Select Fast PWM for highest frequency and simpler counting (counts up only), Phase Correct PWM for symmetric pulses ideal for motor control (counts up and down), or CTC for interrupt-based timing. Enter your desired PWM frequency in Hz — for example, 490 (default), 1000 (1 kHz), 20000 (20 kHz for silent motor control), or 50 (RC servo). The auto prescaler mode finds the combination with the lowest frequency error.
Set Duty Cycles for Both Channels
Enter the duty cycle percentage for Channel A and Channel B independently (0–100%). Channel A corresponds to the OC1A/OC2A pin and Channel B to OC1B/OC2B. The calculator computes the exact OCR register value for each channel and displays a bar showing the duty cycle proportion. The waveform diagram at the top of the results card shows a visual preview of Channel A's pulse shape.
Copy the Generated Code
The Generated Arduino Code section at the bottom shows a complete setup() function with all TCCR register assignments, the ICR/OCR TOP value, both OCR duty cycle values, and pinMode calls for the output pins. Click 'Copy Code' to copy it to your clipboard, then paste directly into your Arduino sketch. Use 'Print' to print all register values and code for your project notes.
자주 묻는 질문
Why is Timer0 dangerous to modify on Arduino?
Arduino's core library uses Timer0 for three critical functions: millis(), micros(), and delay(). These functions rely on Timer0's overflow interrupt to count time since the sketch started. If you change Timer0's prescaler or mode registers, the timing reference shifts — millis() will return incorrect values, delay() will wait for the wrong duration, and any library that depends on them (such as SoftwareSerial, the Servo library on Timer0-assigned pins, and PWM on pins 5 and 6) will malfunction. For custom PWM, use Timer1 or Timer2 on Uno, or Timer3/4/5 on Mega, which do not interfere with the Arduino core timing.
What is the difference between Fast PWM and Phase Correct PWM?
Fast PWM uses single-slope counting: the timer counts from 0 up to TOP, resets to 0, and the output pin is set and cleared based on the OCR compare value within that one-way count. This produces the highest frequency for a given prescaler and TOP. Phase Correct PWM uses dual-slope counting: the timer counts from 0 up to TOP, then counts back down to 0, with the output toggling on the way up and again on the way down. This produces exactly half the frequency of Fast PWM but creates symmetrically centered pulses, which reduces harmonic distortion. For motor control and servo driving, Phase Correct PWM is preferred because the symmetric pulses minimize ripple current and electromagnetic interference. For audio DAC or high-frequency switching, Fast PWM is typically chosen.
What is the highest PWM frequency achievable on an Arduino Uno?
The theoretical maximum PWM frequency on an Arduino Uno (16 MHz) depends on the timer. With Timer1 in Fast PWM mode and prescaler 1, the formula gives f = 16,000,000 / (1 × (1 + TOP)). Setting TOP = 1 gives 8 MHz, but the duty cycle resolution drops to only 1 bit (2 steps: 0% or 50%). A more practical maximum is around 4 MHz with TOP = 3 (4 steps of resolution). For Timer0 and Timer2 in Fast PWM with prescaler 1, the fixed TOP of 255 gives f = 16,000,000 / (1 × 256) = 62,500 Hz with full 8-bit resolution. The highest frequency with reasonable resolution is generally considered around 1 MHz for Timer1 (TOP ~15, prescaler 1).
What is the lowest PWM frequency achievable on Arduino?
The lowest frequency is achieved with the largest prescaler and the highest TOP value. For Timer1 (16-bit) in Phase Correct PWM mode with prescaler 1024: f = 16,000,000 / (2 × 1024 × 65535) ≈ 0.119 Hz — about one cycle every 8.4 seconds. For Fast PWM: f = 16,000,000 / (1024 × 65536) ≈ 0.238 Hz. For 8-bit timers with prescaler 1024 and fixed TOP of 255, Phase Correct gives f = 16,000,000 / (1024 × 510) ≈ 30.6 Hz. Timer1's 16-bit range makes it far more capable than Timer0 or Timer2 for very low frequency applications such as slow LED breathing effects or long-period control signals.
Why does my achieved frequency not exactly match my target?
The TOP register only accepts integer values (0–65535 for 16-bit, 0–255 for 8-bit), which means the achievable frequencies are quantized — you can only hit exact multiples of the base tick frequency (clock / prescaler). For example, with a 16 MHz clock and prescaler 8, the timer ticks at 2 MHz, so Fast PWM frequencies are available only at 2,000,000 / (TOP + 1) for integer TOP values. If your target frequency does not land exactly on one of these quantized values, there will be a small error. The calculator shows this frequency error as a percentage and picks the prescaler/TOP combination that minimizes it. Switching to a different prescaler or using Timer1's variable-TOP mode usually yields a smaller error than 8-bit timers.
How do I set different duty cycles on Channel A and Channel B?
Each output compare channel (A and B) on a timer has its own OCR register: OCR1A for Channel A, OCR1B for Channel B (and OCR1C on Mega timers). Both channels share the same TOP value and therefore the same output frequency, but you set OCR1A and OCR1B independently to control their individual duty cycles. The duty cycle percentage maps to a register value via: OCR = round(TOP × duty% / 100). Both channels' output pins must be configured with pinMode(pin, OUTPUT) in setup(). In the generated code, the calculator includes both OCR assignments and both pinMode calls so that both channels work immediately after uploading.