Czy wolisz polską wersję strony elektroda?
Nie, dziękuję Przekieruj mnie tamHow to change PWM frequency on Arduino
To change PWM frequency on Arduino, you usually change the hardware timer settings that generate PWM on the selected pin.
For a classic Arduino Uno / Nano / Pro Mini (ATmega328P):
The simplest method is to change the timer prescaler by writing to the TCCRnB register.
void setup() {
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
// Timer1 prescaler = 1
TCCR1B = (TCCR1B & 0b11111000) | 0x01;
analogWrite(9, 128); // 50% duty cycle
}
void loop() {
}
That is the short answer.
The important part is choosing the correct timer and understanding the side effects.
PWM frequency depends on:
In simplified form:
\[ f{PWM} = \frac{f{CPU}}{N \times \text{counts}} \]
where:
counts depends on PWM mode and timer resolutionOn the Uno, the default Arduino core uses:
That is why the default frequencies are approximately:
| Timer | Pins | Default frequency |
|---|---|---|
| Timer0 | 5, 6 | ~976 Hz |
| Timer1 | 9, 10 | ~490 Hz |
| Timer2 | 3, 11 | ~490 Hz |
This is the most common approach if you only need “higher” or “lower” PWM and not an exact arbitrary frequency.
void setup() {
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
// Change Timer1 prescaler
TCCR1B = (TCCR1B & 0b11111000) | 0x01; // prescaler = 1
analogWrite(9, 128);
}
For Timer1 on Uno, practical frequencies are approximately:
| Prescaler bits | Prescaler | Frequency on pins 9/10 |
|---|---|---|
0x01 |
1 | ~31.37 kHz |
0x02 |
8 | ~3.92 kHz |
0x03 |
64 | ~490 Hz |
0x04 |
256 | ~122 Hz |
0x05 |
1024 | ~30.6 Hz |
void setup() {
pinMode(3, OUTPUT);
pinMode(11, OUTPUT);
TCCR2B = (TCCR2B & 0b11111000) | 0x01; // prescaler = 1
analogWrite(3, 128);
}
Approximate Timer2 frequencies:
| Prescaler bits | Prescaler | Frequency on pins 3/11 |
|---|---|---|
0x01 |
1 | ~31.37 kHz |
0x02 |
8 | ~3.92 kHz |
0x03 |
32 | ~980 Hz |
0x04 |
64 | ~490 Hz |
0x05 |
128 | ~245 Hz |
0x06 |
256 | ~122 Hz |
0x07 |
1024 | ~30.6 Hz |
void setup() {
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
TCCR0B = (TCCR0B & 0b11111000) | 0x01; // prescaler = 1
}
Approximate Timer0 frequencies:
| Prescaler bits | Prescaler | Frequency on pins 5/6 |
|---|---|---|
0x01 |
1 | 62.5 kHz |
0x02 |
8 | 7.81 kHz |
0x03 |
64 | ~976 Hz |
0x04 |
256 | ~244 Hz |
0x05 |
1024 | ~61 Hz |
A frequent mistake is using the formula for 8-bit fast PWM for all timers, then claiming Timer1 or Timer2 default is several kilohertz. On the Uno, the default Arduino setup for Timer1 and Timer2 is phase-correct PWM, so the default is about 490 Hz, not 3.9 kHz.
That distinction matters when calculating expected frequency.
If you need a specific frequency such as:
then changing only the prescaler is not enough.
You should set Timer1 into a mode where TOP = ICR1.
void setup() {
pinMode(9, OUTPUT);
// Fast PWM, mode 14: TOP = ICR1
TCCR1A = _BV(COM1A1) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // prescaler = 1
ICR1 = 639; // 25 kHz: 16e6 / (1 * (1 + 639)) = 25 kHz
OCR1A = 320; // ~50% duty cycle
}
void loop() {
}
Formula:
\[ TOP = \frac{F{CPU}}{N \cdot f{PWM}} - 1 \]
Duty cycle is set by OCR1A or OCR1B:
\[ D = \frac{OCR1x}{TOP+1} \]
This method gives:
But:
analogWrite() on that timer’s pins is no longer the normal Arduino behaviorFor Arduino-class embedded work, the practical direction is:
If you are using something other than an ATmega328P-based board, the register names and method will be different.
analogWrite()| Application | Typical PWM frequency |
|---|---|
| LED dimming | 200 Hz to 2 kHz |
| DC motor control | 4 kHz to 25 kHz |
| Silent motor drive | >20 kHz |
| PC 4-wire fan control | 25 kHz |
| Servo-style control | usually not standard PWM duty control; often 50 Hz pulse timing |
Note that servo control is not the same as generic PWM dimming. Servos expect pulse timing, not merely duty-cycle modulation.
millis() / delay()millis(), micros(), delay()Servo librarytone()If you want to go deeper, the next topics to study are:
TCCRnA, TCCRnB, OCRnx, ICR1To change PWM frequency on Arduino:
For a standard Uno:
TCCR1BTCCR2BTCCR0B, but this affects timing functionsIf you want, I can give you a ready-to-use snippet for your exact board, pin, and target frequency.