Perché frequenza e risoluzione sono legate
Una periferica PWM conta gli impulsi di un clock: il contatore fissa il periodo, il valore di confronto quanto tempo l’uscita resta accesa. Con n bit di risoluzione il contatore ha bisogno di 2^n impulsi di clock per periodo, quindi la frequenza massima è il clock diviso 2^n. A 80 MHz, con 8 bit si arriva a 312,5 kHz, con 13 bit a 9,77 kHz e con 1 bit a 40 MHz, ma con il duty bloccato al 50 %.
f(max) = f(clock) / 2^bit f = f(clock) / (divisore × 2^bit)
Anche il divisore ha un limite superiore, quindi le frequenze basse richiedono più bit, non meno: su un ESP32-S3 con il clock a 80 MHz, a 50 Hz servono almeno 11 bit.
ESP32: la periferica LEDC
Tutti gli ESP32 generano il PWM con la periferica LEDC: un divisore con 8 bit di parte frazionaria, da 1 a circa 1024, e un contatore fino a 20 bit su ESP32, C5, C6, H2 e P4, 14 bit su S2, S3 e C3. Il clock può essere l’APB a 80 MHz (un’uscita del PLL sui chip più recenti, 96 MHz sull’H2), il quarzo (40 MHz; 32 MHz sull’H2, 40 o 48 MHz sul C5), un oscillatore RC interno oppure, su ESP32 e S2, il REF_TICK a 1 MHz.
Arduino-ESP32 3.x prende il clock del PWM dal quarzo su tutti i chip tranne l’ESP32 originale. Così a ogni risoluzione la frequenza massima scende, della metà dove un quarzo a 40 MHz prende il posto di un clock a 80 MHz: su un ESP32-S3, a 5 kHz si ottengono 12 bit invece di 13. Se chiami ledcSetClockSource(LEDC_AUTO_CLK) prima di ledcAttach(), il driver sceglie il clock più veloce; la funzione c’è da Arduino-ESP32 3.0.5. ESPHome usa il clock APB dove c’è e sceglie la risoluzione da solo.
Raspberry Pi Pico: RP2040 e RP2350
Ogni slice PWM ha un contatore a 16 bit che riparte da zero dopo TOP e un divisore da 1 a 255 + 15/16 a passi di 1/16. La frequenza è il clock di sistema diviso per (TOP + 1) e per il divisore, e ancora per 2 in modalità phase-correct. Dato che TOP può avere qualsiasi valore, il Pico centra esattamente quasi tutte le frequenze: a 125 MHz, 25 kHz si ottengono con TOP 4999 e divisore 1, circa 12,3 bit.
Arduino Uno e Nano: i timer dell’ATmega328P
Il Timer0 e il Timer2 sono a 8 bit, il Timer1 a 16 bit, ognuno con una serie fissa di prescaler N. La frequenza dipende da N e da TOP: clock / (N × (TOP + 1)) in fast PWM, clock / (2 × N × TOP) in phase-correct. analogWrite() li lascia con prescaler 64: 976,6 Hz sui pin 5 e 6, 490,2 Hz sui pin 3, 9, 10 e 11. Per altre frequenze il Timer1 con TOP in ICR1 mantiene entrambi i pin e fino a 16 bit: un segnale da 25 kHz per una ventola sul pin 9 si ottiene con ICR1 = 639 senza prescaler.
ESP8266
L’ESP8266 non ha un PWM hardware: il core Arduino ed ESPHome lo generano via software, da 100 Hz a 40 kHz nel core Arduino, con un range di serie di 255. Secondo la documentazione del core, le frequenze alte tengono impegnata la CPU.
Quale frequenza per cosa
| Uso | Frequenza | Perché |
|---|---|---|
| Luminosità dei LED | 1,25 kHz o più | L’IEEE 1789 considera a basso rischio di sfarfallio un PWM tutto acceso / tutto spento da 1250 Hz |
| Servo da modellismo | 50 Hz, impulsi da 1 a 2 ms | Un impulso ogni 20 ms; la durata dell’impulso fissa l’angolo |
| Ventola PC a 4 fili | 25 kHz (21–28 kHz) | Specifica Intel per le ventole PWM a 4 fili |
| Motore DC | circa 20 kHz o più | Oltre le frequenze udibili; controlla il limite del driver |
| Buzzer passivo | La frequenza della nota, 50 % | La frequenza è l’altezza del suono |
Valori di serie delle varie piattaforme
| Piattaforma | analogWrite() di serie | Risoluzione massima | Clock del PWM |
|---|---|---|---|
| ESP32 (Arduino-ESP32 3.x) | 1 kHz, 8 bit | 20 bit | APB 80 MHz o REF_TICK 1 MHz (AUTO) |
| ESP32-S2, S3, C3 (Arduino-ESP32 3.x) | 1 kHz, 8 bit | 14 bit | XTAL 40 MHz di serie |
| ESP32-C5, C6, P4 (Arduino-ESP32 3.x) | 1 kHz, 8 bit | 20 bit | XTAL 40 MHz di serie (C5: 40 o 48 MHz) |
| ESP32-H2 (Arduino-ESP32 3.x) | 1 kHz, 8 bit | 20 bit | XTAL 32 MHz di serie |
| RP2040, RP2350 (Arduino-Pico) | 1 kHz, range 255 | 16 bit | Clock di sistema: 200 MHz (Pico), 150 MHz (Pico 2) |
| ATmega328P (Uno, Nano) | 490 Hz (pin 3, 9, 10, 11), 976,6 Hz (pin 5, 6), 8 bit | 16 bit (Timer1) | 16 MHz con prescaler 64 |
| ESP8266 (core Arduino 3.x) | 1 kHz, range 255 | Range fino a 65535 | PWM software |
Fonti: driver LEDC e file delle capacità dei SoC di ESP-IDF (release 5.5), esp32-hal-ledc.c e documentazione dell’API LEDC di Arduino-ESP32 3.x, componenti ledc, rp2040_pwm ed esp8266_pwm di ESPHome, datasheet dell’RP2040 e hardware_pwm del pico-sdk, wiring_analog.cpp di Arduino-Pico, datasheet Microchip dell’ATmega328P e core Arduino AVR, guida di riferimento del core Arduino per ESP8266, specifica Intel delle ventole PWM a 4 fili, IEEE 1789-2015 nella sintesi del Dipartimento dell’Energia statunitense, libreria Servo di Arduino.
Domande frequenti
Qual è la frequenza PWM massima sull’ESP32?
40 MHz, con 1 bit di risoluzione e duty fisso al 50 %: il clock a 80 MHz diviso 2. Per una regolazione utilizzabile, con 8 bit si arriva a 312,5 kHz e con 10 bit a 78,1 kHz. Con Arduino-ESP32 3.x sui chip diversi dall’ESP32 originale, il clock di serie dal quarzo abbassa questi valori (della metà sui chip con quarzo a 40 MHz e clock APB o PLL a 80 MHz), a meno di chiamare ledcSetClockSource(LEDC_AUTO_CLK), disponibile dalla versione 3.0.5.
Perché ledcAttach() fallisce con “requested frequency and duty resolution can not be achieved”?
Perché il divisore deve restare tra 1 e circa 1024. Se la frequenza è troppo alta per i bit che hai chiesto, abbassa la risoluzione. Se è troppo bassa, alza la risoluzione: con meno bit serve un divisore più grande. Il calcolatore mostra l’intervallo valido per entrambi.
Che frequenza PWM serve per una ventola PC a 4 pin?
25 kHz: la specifica Intel accetta da 21 a 28 kHz. Un ESP32 a 25 kHz arriva a 11 bit con il clock a 80 MHz; un Arduino Uno ottiene 25 kHz sul pin 9 con il Timer1 e ICR1 = 639. Comanda la linea PWM della ventola con un’uscita open-drain o un transistor, perché la ventola ha già un pull-up su quella linea.
Come comando un servo in PWM con l’ESP32?
A 50 Hz con 14 bit un passo vale circa 1,2 µs, abbastanza fine per un servo: 1,5 ms corrispondono a 1229, 1 ms a 819 e 2 ms a 1638. In ESPHome collega un output ledc a 50 Hz al componente servo; con Arduino puoi usare anche una libreria come ESP32Servo.
Perché sui pin 5 e 6 dell’Arduino Uno la frequenza PWM è diversa?
I pin 5 e 6 usano il Timer0 in fast PWM (976,6 Hz), gli altri il Timer1 e il Timer2 in phase-correct (490,2 Hz). Il Timer0 conta anche millis(), quindi cambiane il prescaler solo se puoi convivere con millis() e delay() sballati.
Che risoluzione PWM serve per i LED?
Con 8 bit (256 passi) la regolazione si vede a scatti a bassa luminosità, dove l’occhio nota di più le piccole variazioni; con 12 bit o più e una curva gamma le dissolvenze sono fluide. Tieni la frequenza a 1,25 kHz o più per uno sfarfallio basso.
Le due uscite di una slice PWM del Pico possono avere frequenze diverse?
No: A e B condividono il contatore, quindi hanno la stessa frequenza e lo stesso TOP, e può cambiare solo il duty. Se ti servono frequenze diverse usa pin su slice diverse.