Cos'è il PWM? Guida ad analogWrite, duty cycle e frequenza su Arduino
Cos'è il PWM (modulazione di larghezza di impulso) e come funziona? Duty cycle e frequenza, pin PWM di Arduino, luminosità dei LED e velocità dei motori con analogWrite, differenza con i servo, LEDC dell'ESP32 e PWM del Pico.
I pin digitali di Arduino conoscono solo due stati: 0 V o 5 V. Come fai allora a portare un LED a metà luminosità o a far girare piano un motore? La risposta è il PWM (Pulse Width Modulation, modulazione di larghezza di impulso). Il pin viene acceso e spento molto velocemente e, cambiando la percentuale di tempo in cui resta acceso, si regola la potenza media che arriva al carico. Dimmer per LED, controllo della velocità dei motori, servo, generazione di suoni e perfino i caricabatterie dei telefoni usano questa tecnica.

Come funziona il PWM?
Un segnale PWM è un'onda quadra: resta HIGH per un po', poi LOW, e il ciclo si ripete continuamente. La durata di un ciclo acceso-spento è il periodo, e la parte del periodo in cui il segnale è HIGH si chiama duty cycle (ciclo di lavoro). Con un duty cycle del 25% il segnale è acceso per un quarto del tempo, quindi un pin a 5 V si comporta in media come 1,25 V. Il LED lampeggia circa 490 volte al secondo; l'occhio non riesce a seguirlo e vede solo la luminosità media. Un motore, grazie alla sua inerzia, attenua gli impulsi e gira alla velocità media.
| Duty cycle | Valore di analogWrite | Tensione media (5 V) | LED |
|---|---|---|---|
| 0% | 0 | 0 V | Spento |
| 25% | 64 | 1,25 V | Debole |
| 50% | 127 | 2,5 V | Mezza luminosità |
| 75% | 191 | 3,75 V | Luminoso |
| 100% | 255 | 5 V | Massima luminosità |
I nostri occhi non rispondono alla luce in modo lineare: notano benissimo le variazioni a bassa luminosità e molto meno quelle ad alta luminosità. Per questo un LED al 50% di duty cycle sembra molto più luminoso della metà. Per una regolazione che sembri naturale si usa la correzione gamma che vedrai più sotto.
Frequenza: quanto è veloce il PWM?
La frequenza indica quante volte al secondo il segnale si accende e si spegne. Su Arduino Uno i pin 5 e 6 lavorano a circa 980 Hz, i pin 3, 9, 10 e 11 a circa 490 Hz. Per i LED sono frequenze più che sufficienti. Con i motori, però, 490 Hz rientrano nella gamma udibile e il motore può fischiare leggermente; su ESP32 e Pico puoi alzare la frequenza a 20 kHz per renderlo silenzioso. Alzarla molto più del necessario, invece, fa scaldare transistor e MOSFET.
| Scheda | Pin PWM | Frequenza predefinita | Risoluzione |
|---|---|---|---|
| Arduino Uno / Nano | 3, 5, 6, 9, 10, 11 | 490 Hz (5 e 6: 980 Hz) | 8 bit (0–255) |
| Arduino Mega | 2–13, 44–46 | 490 Hz (4 e 13: 980 Hz) | 8 bit (0–255) |
| ESP32 | Quasi tutti i pin di uscita | Regolabile (analogWrite: 1 kHz) | 1–16 bit |
| Raspberry Pi Pico | Tutti i GPIO | Regolabile | 16 bit (0–65535) |
Luminosità di un LED con analogWrite
Su Arduino il PWM si genera con analogWrite(pin, valore), con un valore tra 0 e 255. Nonostante il nome ingannevole, questo comando non produce una vera tensione analogica, ma PWM. Funziona solo sui pin contrassegnati con ~. Il codice qui sotto accende e spegne lentamente un LED con un effetto "respiro":
1const int LED_PIN = 9; // ~ işaretli PWM pini / PWM pin marked with ~
2
3void setup() {
4 pinMode(LED_PIN, OUTPUT);
5}
6
7void loop() {
8 for (int v = 0; v <= 255; v++) { // yavaşça yan / fade in
9 analogWrite(LED_PIN, v);
10 delay(8);
11 }
12 for (int v = 255; v >= 0; v--) { // yavaşça sön / fade out
13 analogWrite(LED_PIN, v);
14 delay(8);
15 }
16}Regolare la luminosità con un potenziometro
Se colleghi un potenziometro ad A0 puoi regolare a mano la luminosità del LED. analogRead() restituisce valori da 0 a 1023; dividendo per 4 ottieni l'intervallo 0–255 che analogWrite si aspetta. Il collegamento del potenziometro è spiegato in Cos'è un potenziometro?
1void loop() {
2 int pot = analogRead(A0); // 0–1023
3 analogWrite(9, pot / 4); // 0–255
4}Velocità di un motore DC con il PWM
Anche un piccolo motore DC assorbe centinaia di milliampere, mentre un pin di Arduino ne fornisce in sicurezza solo una ventina. Per questo il motore si pilota tramite un transistor, un MOSFET o un driver come l'L298N, e il segnale PWM va all'ingresso di velocità del driver. Sull'L298N questo ingresso è il pin ENA (ed ENB per il secondo motore); per usare il PWM devi togliere il ponticello. I pin IN1 e IN2 stabiliscono il senso di rotazione.

1const int ENA = 9; // hız (PWM) / speed (PWM)
2const int IN1 = 8; // yön / direction
3const int IN2 = 7;
4
5void setup() {
6 pinMode(ENA, OUTPUT);
7 pinMode(IN1, OUTPUT);
8 pinMode(IN2, OUTPUT);
9 digitalWrite(IN1, HIGH); // ileri / forward
10 digitalWrite(IN2, LOW);
11}
12
13void loop() {
14 analogWrite(ENA, 255); delay(2000); // tam hız / full speed
15 analogWrite(ENA, 150); delay(2000); // orta hız / medium speed
16 analogWrite(ENA, 0); delay(2000); // dur / stop
17}Servomotore e PWM sono la stessa cosa?
Anche i servo si comandano con impulsi, ma con una logica diversa: la posizione è data dalla larghezza dell'impulso, non dal duty cycle. Un servo si aspetta 50 impulsi al secondo (50 Hz); un impulso di 1 millisecondo corrisponde a circa 0°, 1,5 ms a 90° e 2 ms a 180°. analogWrite non può generare questa temporizzazione, per questo i servo usano la libreria Servo. I dettagli sono in Cos'è un servomotore?
Una vera tensione analogica dal PWM: il filtro RC
A volte serve davvero una tensione stabile, per esempio come riferimento per un amplificatore operazionale o per un'uscita audio. In questo caso fai passare il PWM in un filtro passa-basso formato da una resistenza e un condensatore. Con 10 kΩ e 10 µF la costante di tempo è 0,1 secondi: l'uscita è abbastanza liscia ma reagisce lentamente ai cambiamenti. Puoi provare altri valori con il calcolatore Costante di tempo RC. L'ESP32 classico ha inoltre due DAC sui GPIO 25 e 26 con una vera uscita analogica.
Il PWM sull'ESP32: LEDC
Sull'ESP32 il PWM è generato da un hardware chiamato LEDC, e la frequenza e la risoluzione le scegli tu. Con il core Arduino 3.x si usano ledcAttach(pin, frequenza, risoluzione) e ledcWrite(pin, valore); le vecchie versioni 2.x avevano i comandi a canali ledcSetup e ledcAttachPin. L'esempio qui sotto sfuma un LED a 5 kHz con 8 bit:
1const int LED_PIN = 2;
2
3void setup() {
4 ledcAttach(LED_PIN, 5000, 8); // 5 kHz, 8 bit (0–255) — ESP32 Arduino core 3.x
5}
6
7void loop() {
8 for (int d = 0; d <= 255; d++) { ledcWrite(LED_PIN, d); delay(5); }
9 for (int d = 255; d >= 0; d--) { ledcWrite(LED_PIN, d); delay(5); }
10}Il PWM sul Raspberry Pi Pico (MicroPython)
Sul Pico ogni GPIO può generare PWM. In MicroPython si usa la classe PWM: la frequenza si imposta con freq() e il duty cycle con duty_u16(), che accetta valori da 0 a 65535:
1from machine import Pin, PWM
2import time
3
4led = PWM(Pin(15))
5led.freq(1000) # 1 kHz
6
7while True:
8 for d in range(0, 65536, 512): # yavaşça yan / fade in
9 led.duty_u16(d)
10 time.sleep_ms(5)
11 for d in range(65535, -1, -512): # yavaşça sön / fade out
12 led.duty_u16(d)
13 time.sleep_ms(5)Idee di progetti con il PWM
- LED che respira: una spia di stato che si accende e si spegne lentamente, come i dispositivi in standby.
- Lampada da scrivania dimmerabile: una lampada LED con la luminosità regolata da un potenziometro.
- Ventola in base alla temperatura: fai girare più veloce la ventola quando sale la temperatura misurata da un DHT11.
- Miscela di colori: crea milioni di colori su un LED RGB con tre canali PWM.
- Auto robot: rendi più morbide le curve regolando separatamente la velocità di due motori.
- Lampada alba: aumenta lentamente la luce per 15 minuti prima della sveglia.
Errori comuni e come risolverli
- analogWrite su un pin senza PWM: sull'Uno i pin senza ~ possono essere solo accesi o spenti; da 128 in su conta come acceso, sotto come spento.
- Pin 9 e 10 con la libreria Servo: sull'Uno la libreria Servo usa il Timer1 e disattiva il PWM su questi due pin; sposta il LED o il motore su un altro pin PWM.
- Pin 3 e 11 con tone(): tone() usa il Timer2 e disturba il PWM su questi pin.
- Collegare un motore direttamente a un pin: usa sempre un transistor, un MOSFET o un driver per motori.
- Overflow nel calcolo gamma: v * v supera il limite di int; aggiungi il cast (long).
- Scambiare il PWM per un vero segnale analogico: il multimetro mostra la media, ma il segnale continua a oscillare tra 0 e 5 V; per i circuiti sensibili usa un filtro RC o un DAC.
Il PWM è uno dei concetti più utili che imparerai con Arduino: LED, motori, ventole e altoparlanti si controllano tutti con questo semplice trucco. Per le basi dai un'occhiata a Cos'è un LED?; nell'app BlueGrays trovi progetti di dissolvenza LED in PWM, luminosità con potenziometro e transizioni di colore RGB, passo passo con il codice.
Domande frequenti
Cos'è il PWM in breve?
Il PWM regola la potenza media fornita a un carico accendendo e spegnendo un pin molto velocemente e cambiando la percentuale di tempo in cui resta acceso (il duty cycle). Così un pin digitale che fornisce solo 0 o 5 V può attenuare un LED o rallentare un motore.
Quali pin di Arduino Uno supportano il PWM?
Su Uno e Nano supportano il PWM i pin 3, 5, 6, 9, 10 e 11, contrassegnati con ~ sulla scheda. Sul Mega possono generare PWM i pin 2–13 e 44–46.
analogWrite fornisce una vera uscita analogica?
No. analogWrite genera PWM: il pin passa rapidamente tra 0 e 5 V. Regola la tensione media, ma per una tensione davvero stabile bisogna far passare il PWM in un filtro RC o usare un DAC come quello dell'ESP32.
Come si calcola il duty cycle?
Il duty cycle è il tempo in cui il segnale resta HIGH diviso per l'intero periodo: (tempo HIGH / periodo) × 100. Su Arduino lo trovi dividendo il valore di analogWrite per 255 e moltiplicando per 100; per esempio 64 corrisponde a circa il 25%.
Come si cambia la frequenza del PWM su Arduino?
analogWrite non cambia la frequenza. Sull'Uno si può regolare modificando i registri dei timer (per esempio TCCR1B per i pin 9 e 10), ma questo può influire su millis e su alcune librerie. Sull'ESP32 la frequenza si imposta direttamente con ledcAttach, sul Pico con freq().
Il PWM può danneggiare un LED?
No. Il LED si accende a piena corrente durante ogni impulso, ma quella corrente è già limitata dalla resistenza in serie e la corrente media scende in proporzione al duty cycle. Con la resistenza giusta il PWM non accorcia la vita del LED.
Progetti da realizzare dopo questo articolo
Vedi tutti i progetti
Dissolvenza LED ESP32 con PWM
Modificare la luminosità del LED in modo fluido da 0 a max, da max a 0. Controlliamo il PWM con analogWrite() come in Arduino - la stessa sintassi con ESP32 Arduino Core 3.0+ funziona senza problemi. La definizione del pin + pinMode + analogWrite è sufficiente.

Raspberry Pi Pico PWM LED Fade (Effetto Respiro, GP14)
Il LED non lampeggia più — respira! 🌬️ Con il **PWM** (modulazione di larghezza d'impulso) del Raspberry Pi Pico, la luminosità sale e scende lentamente. Impara la classe machine.PWM, duty_u16() (luminosità a 16 bit 0–65535), la frequenza PWM, i cicli range() e l'uscita quasi analogica. Base per miscelazione colori RGB, controllo motori, servo e buzzer.

Luminosità di un LED con Potenziometro su ESP32 (Analogico → PWM)
In questo progetto controlliamo in modo analogico la luminosità di un LED tramite un potenziometro. Il pin ADC dell'ESP32 legge la tensione tra 0 e 3,3 V dal potenziometro; il valore viene convertito in un segnale PWM (Pulse Width Modulation) e inviato al LED. Ruotando il potenziometro, il LED si accende e si spegne gradualmente. Con Arduino Core 3.0+ si usa direttamente `analogWrite()`; su ESP32-S2/S3 la risoluzione dell'ADC è fissata a 12 bit.

Transizione cromatica omogenea con LED RGB
Progetto che crea un morbido effetto arcobaleno commutando gradualmente i colori del LED RGB con analogWrite. Insegna la logica della miscelazione dei colori e l'animazione di transizione con PWM.

Controllo LED RGB ESP32
Generazione illimitata di colori con un singolo LED RGB invece di 3 LED separati. La transizione arcobaleno avviene impostando i valori R/G/B con analogWrite() come in Arduino. La teoria dei colori (come rosso+verde=giallo) viene vista in pratica.

Raspberry Pi Pico LED RGB Ciclo di Colori (PWM a 3 Canali, GP11-13)
Un LED, milioni di colori! 🌈 Un LED RGB contiene 3 LED: rosso, verde e blu. Con un canale PWM del Pico per ciascuno, i colori si mescolano: rosso + verde = giallo, verde + blu = ciano, tutti e tre = bianco. Il LED scorre 8 colori. Impara più canali PWM, funzioni (def), miscelazione RGB, conversione da 8 a 16 bit (x257) e catodo comune vs anodo comune.

Servomotore ESP32 (controllo tramite potenziometro)
In questo progetto controlliamo un servomotore SG90 tramite un potenziometro. Regoliamo l'angolo del servomotore mappando il valore analogico letto dal potenziometro su un intervallo compreso tra 0 e 180 gradi. Grazie alla libreria ESP32Servo, qualsiasi GPIO dell'ESP32 può generare un segnale PWM. Si tratta di un metodo di controllo fondamentale per bracci robotici, gimbal per telecamere e meccanismi di porte automatiche.

Lampada con miscelatore di colori ESP32 (3 potenziometri + LED RGB + OLED)
Una lampada mista colori intelligente che, ruotando i 3 potenziometri con l'ESP32, permette di miscelare il colore desiderato! Man mano che si ruotano i potenziometri rosso, verde e blu, il LED RGB a catodo comune cambia colore istantaneamente. Sul display OLED SSD1306 vengono visualizzati in tempo reale i valori compresi tra 0 e 255 per ogni colore, le barre di riempimento visive e il codice colore HEX (#FF8040, ad esempio). Un mini studio di colore professionale: insegna la teoria dei colori R
Altri articoli
Impara come un pin digitale può attenuare un LED e rallentare un motore, cosa significano duty cycle e frequenza, come usare bene analogWrite e come funziona il PWM su ESP32 e Pico.

