Fundamentos · 7 min de leitura

O que é PWM? Guia de analogWrite, ciclo de trabalho e frequência no Arduino

O que é PWM (modulação por largura de pulso) e como funciona? Ciclo de trabalho e frequência, pinos PWM do Arduino, brilho de LED e velocidade de motor com analogWrite, a diferença dos servos, LEDC do ESP32 e PWM no Raspberry Pi Pico.

Os pinos digitais do Arduino só conhecem duas coisas: 0 V ou 5 V. Então, como deixar um LED com metade do brilho ou fazer um motor girar devagar? A resposta é o PWM (Pulse Width Modulation, modulação por largura de pulso). O pino é ligado e desligado muito rápido e, mudando a proporção do tempo em que ele fica ligado, você define a potência média entregue à carga. Controle de brilho de LEDs, controle de velocidade de motores, acionamento de servos, geração de som e até carregadores de celular usam essa técnica.

LED acionado com PWM por um Arduino
Com PWM você liga e desliga um LED centenas de vezes por segundo para deixar o brilho no nível que quiser.

Como funciona o PWM?

Um sinal PWM é uma onda quadrada: ele fica em HIGH por um tempo, depois em LOW, e o ciclo se repete sem parar. A duração de um ciclo liga-desliga é o período, e a proporção do período em que o sinal fica em HIGH é o ciclo de trabalho (duty cycle). Com um ciclo de trabalho de 25%, o sinal fica ligado um quarto do tempo, então um pino de 5 V se comporta, em média, como 1,25 V. O LED pisca cerca de 490 vezes por segundo; seu olho não acompanha isso e só vê o brilho médio. Um motor, graças à inércia, suaviza os pulsos e gira na velocidade média.

Ciclo de trabalhoValor no analogWriteTensão média (5 V)LED
0%00 VApagado
25%641,25 VFraco
50%1272,5 VMeio brilho
75%1913,75 VForte
100%2555 VBrilho máximo

Nossos olhos não respondem à luz de forma linear: eles percebem muito bem as mudanças em níveis baixos e bem menos as mudanças em níveis altos. Por isso um LED com ciclo de trabalho de 50% parece muito mais forte do que a metade. Para um controle de brilho que pareça natural, usa-se a correção gama mostrada abaixo.

Frequência: quão rápido é o PWM?

A frequência é quantas vezes por segundo o sinal liga e desliga. No Arduino Uno, os pinos 5 e 6 funcionam em cerca de 980 Hz e os pinos 3, 9, 10 e 11 em cerca de 490 Hz. Para LEDs, essas frequências são mais do que suficientes. Com motores, porém, 490 Hz fica na faixa que você consegue ouvir, e o motor pode chiar um pouco; no ESP32 e no Pico você pode subir a frequência para 20 kHz para acabar com o ruído. Subir a frequência muito além do necessário, no entanto, faz transistores e MOSFETs esquentarem.

PlacaPinos PWMFrequência padrãoResolução
Arduino Uno / Nano3, 5, 6, 9, 10, 11490 Hz (5 e 6: 980 Hz)8 bits (0–255)
Arduino Mega2–13, 44–46490 Hz (4 e 13: 980 Hz)8 bits (0–255)
ESP32Quase todos os pinos de saídaAjustável (analogWrite: 1 kHz)1–16 bits
Raspberry Pi PicoTodos os pinos GPIOAjustável16 bits (0–65535)

Brilho de LED com analogWrite

No Arduino, você gera PWM com analogWrite(pin, value), em que o valor fica entre 0 e 255. Apesar do nome enganoso, esse comando não produz uma tensão analógica de verdade; ele produz PWM. Ele só funciona nos pinos marcados com ~. O código abaixo aumenta e diminui o brilho de um LED devagar, para um efeito de "respiração":

C++ (Arduino IDE)
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}
Para um controle de brilho mais natural, escale o valor elevando-o ao quadrado: analogWrite(LED_PIN, (long)v * v / 255);. O (long) é importante aqui: no Uno, um int não guarda números acima de 32.767, então 255 × 255 estoura.

Controle de brilho com um potenciômetro

Se você ligar um potenciômetro no A0, pode ajustar o brilho do LED à mão. analogRead() devolve um valor de 0 a 1023; dividir por 4 dá a faixa de 0–255 que o analogWrite espera. A ligação do potenciômetro é explicada em O que é potenciômetro?

C++ (Arduino IDE)
1void loop() {
2  int pot = analogRead(A0);   // 0–1023
3  analogWrite(9, pot / 4);    // 0–255
4}

Velocidade de motor CC com PWM

Até um motor CC pequeno puxa centenas de miliampères, enquanto um pino do Arduino só fornece com segurança cerca de 20 mA. Por isso o motor é acionado através de um transistor, MOSFET ou um driver de motor como o L298N, e o sinal PWM vai para a entrada de velocidade do driver. No L298N, essa entrada é o pino ENA (e o ENB para o segundo motor); para usar PWM, você precisa tirar o jumper que fica nele. Os pinos IN1 e IN2 definem o sentido de giro.

Módulo driver de motor L298N
Driver de motor L298N: o PWM nos pinos ENA e ENB define a velocidade de dois motores CC de forma independente.
C++ (Arduino IDE)
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}
Nunca ligue um motor direto em um pino do Arduino; a corrente que ele puxa e a tensão reversa que ele gera vão queimar o pino. Além disso, com valores de ciclo muito baixos, o motor só zumbe em vez de girar; a maioria dos motores precisa de um valor mínimo em torno de 80–120 para começar a se mover.

Servo motor e PWM são a mesma coisa?

Os servo motores também são controlados com pulsos, mas a lógica é diferente: a posição é definida pela largura do pulso, e não pelo ciclo de trabalho. Um servo espera 50 pulsos por segundo (50 Hz); um pulso de 1 milissegundo significa cerca de 0°, 1,5 ms significa 90° e 2 ms significa 180°. O analogWrite não consegue gerar essa temporização, e é por isso que os servos usam a biblioteca Servo. Os detalhes estão em O que é servo motor?

Uma tensão analógica de verdade a partir do PWM: o filtro RC

Às vezes você precisa mesmo de uma tensão estável, por exemplo para dar uma referência a um amplificador operacional ou para ter uma saída de áudio. Nesse caso, você passa o PWM por um filtro passa-baixa feito com um resistor e um capacitor. Com 10 kΩ e 10 µF, a constante de tempo é de 0,1 segundo; a saída fica bem lisa, mas reage devagar às mudanças. Você pode testar valores diferentes com a calculadora de constante de tempo RC. O ESP32 clássico também tem dois DACs, no GPIO 25 e no 26, que dão uma saída analógica de verdade.

PWM no ESP32: LEDC

No ESP32, o PWM é gerado por um hardware chamado LEDC, e você escolhe a frequência e a resolução. No core Arduino 3.x, você usa ledcAttach(pin, frequency, resolution) e ledcWrite(pin, value); as versões antigas 2.x tinham os comandos ledcSetup e ledcAttachPin, baseados em canais. O exemplo abaixo varia o brilho de um LED a 5 kHz com resolução de 8 bits:

C++ (Arduino IDE)
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}

PWM no Raspberry Pi Pico (MicroPython)

Todos os pinos GPIO do Pico podem gerar PWM. No MicroPython, você usa a classe PWM, definindo a frequência com freq() e o ciclo de trabalho com duty_u16(), que recebe valores de 0 a 65535:

MicroPython
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)

Ideias de projetos com PWM

  • LED que respira: uma luz de status que acende e apaga devagar, como em aparelhos em modo de espera.
  • Luminária de mesa com dimmer: uma luminária de LED com o brilho ajustado por um potenciômetro.
  • Ventilador controlado pela temperatura: acelere um ventilador conforme a temperatura medida por um DHT11 sobe.
  • Mistura de cores: crie milhões de cores em um LED RGB com três canais PWM.
  • Carrinho robô: deixe as curvas mais suaves definindo a velocidade de cada motor separadamente.
  • Luminária do amanhecer: aumente aos poucos o brilho de uma luz durante 15 minutos antes do despertador da manhã.

Erros comuns e como resolvê-los

  • analogWrite em um pino sem PWM: no Uno, os pinos sem ~ só ficam ligados ou desligados; 128 ou mais conta como ligado e qualquer valor menor como desligado.
  • Pinos 9 e 10 com a biblioteca Servo: no Uno, a biblioteca Servo usa o Timer1 e desativa o PWM nesses dois pinos; passe o LED ou o motor para outro pino PWM.
  • Pinos 3 e 11 com tone(): tone() usa o Timer2 e atrapalha o PWM nesses pinos.
  • Ligar um motor direto em um pino: use sempre um transistor, MOSFET ou driver de motor.
  • Estouro no cálculo da correção gama: v * v passa do limite do int; acrescente a conversão (long).
  • Tratar o PWM como analógico de verdade: o multímetro mostra a média, mas o sinal continua oscilando entre 0 e 5 V; use um filtro RC ou um DAC em circuitos sensíveis.

O PWM é uma das ideias mais úteis que você vai aprender no Arduino: LEDs, motores, ventiladores e alto-falantes são todos controlados com esse truque simples. Para o básico, dê uma olhada em O que é LED?; no app BlueGrays você encontra projetos de LED com PWM, brilho com potenciômetro e transição de cores com LED RGB passo a passo, com código.

Perguntas frequentes

O que é PWM, resumindo?

PWM é uma forma de definir a potência média entregue a uma carga ligando e desligando um pino muito rápido e mudando a proporção do tempo em que ele fica ligado (o ciclo de trabalho). Ele permite que um pino digital, que só fornece 0 ou 5 V, diminua o brilho de um LED ou desacelere um motor.

Quais pinos têm PWM no Arduino Uno?

No Uno e no Nano, os pinos 3, 5, 6, 9, 10 e 11 têm PWM; eles estão marcados com ~ na placa. No Mega, os pinos 2–13 e 44–46 podem gerar PWM.

O analogWrite dá uma saída analógica de verdade?

Não. O analogWrite produz PWM; o pino alterna rapidamente entre 0 e 5 V. Ele define a tensão média, mas, para ter uma tensão realmente estável, você precisa passar o PWM por um filtro RC ou usar um DAC, como o do ESP32.

Como se calcula o ciclo de trabalho?

O ciclo de trabalho é o tempo em que o sinal fica em HIGH dividido pelo período inteiro: (tempo em HIGH / período) × 100. No Arduino, você o encontra dividindo o valor do analogWrite por 255 e multiplicando por 100; por exemplo, 64 dá cerca de 25%.

Como mudo a frequência do PWM no Arduino?

O analogWrite não muda a frequência. No Uno, você pode ajustá-la mudando os registradores dos timers (por exemplo, o TCCR1B para os pinos 9 e 10), mas isso pode afetar o millis e algumas bibliotecas. No ESP32, você define a frequência direto com ledcAttach, e no Pico com freq().

O PWM pode danificar um LED?

Não. O LED acende com a corrente total durante cada pulso, mas essa corrente já é limitada pelo resistor em série, e a corrente média cai na proporção do ciclo de trabalho. Desde que você use o resistor certo, o PWM não encurta a vida do LED.

Ver todos os projetos
Variação gradual do brilho do LED com PWM no ESP32
#110Iniciante

Variação gradual do brilho do LED com PWM no ESP32

Varie suavemente o brilho do LED de 0 ao máximo e do máximo a 0. Controlamos o PWM com analogWrite(), como no Arduino. A mesma sintaxe funciona sem problemas com ESP32 Arduino Core 3.0+. Basta definir o pino e usar pinMode e analogWrite.

4.8(36)
54
Raspberry Pi Pico: variação de brilho do LED com PWM (efeito de respiração)
#160Iniciante

Raspberry Pi Pico: variação de brilho do LED com PWM (efeito de respiração)

O LED não só pisca — ele respira! Com o PWM (modulação por largura de pulso) do Raspberry Pi Pico, o brilho do LED aumenta e diminui lentamente, como a luz de um MacBook em repouso. Aprenda a usar a classe machine.PWM, duty_u16() (brilho de 16 bits, de 0–65535), frequência PWM (freq(1000) — 1.000 ciclos de ligar/desligar por segundo, sem cintilação visível), laços com passos usando range() (crescentes e decrescentes) e saída semelhante à analógica em um pino digital.

0.0(0)
4
Brilho do LED com potenciômetro no ESP32 (analógico → PWM)
#115Intermediário
Premium

Brilho do LED com potenciômetro no ESP32 (analógico → PWM)

Neste projeto, controlamos o brilho de um LED de forma analógica com um potenciômetro. O pino ADC do ESP32 lê a tensão de 0-3,3V do potenciômetro e converte esse valor em um sinal PWM (modulação por largura de pulso), enviado ao LED. Assim, ao girar o potenciômetro, o brilho do LED aumenta e diminui gradualmente. Com Arduino Core 3.0+, você pode usar analogWrite() diretamente; no ESP32-S2/S3, a resolução do ADC é fixada em 12 bits.

4.5(19)
32
Transição suave de cores com LED RGB
#40Iniciante
Premium

Transição suave de cores com LED RGB

Um único LED RGB muda lentamente do vermelho para o verde, do verde para o azul e de volta para o vermelho, repetindo esse ciclo de arco-íris sem parar. Cada transição leva cerca de dois segundos e me

4.8(58)
76
Controle de LED RGB com ESP32
#111Iniciante

Controle de LED RGB com ESP32

Gere inúmeras cores com um único LED RGB em vez de 3 LEDs separados. Como no Arduino, ajustamos os valores R/G/B com analogWrite() para criar uma transição de arco-íris. Você vê a teoria das cores na prática, como vermelho + verde = amarelo.

4.6(29)
51
Ciclo de cores com LED RGB no Raspberry Pi Pico (PWM de 3 canais)
#161Iniciante

Ciclo de cores com LED RGB no Raspberry Pi Pico (PWM de 3 canais)

Um LED, milhões de cores! Um LED RGB contém, na verdade, 3 LEDs: vermelho, verde e azul. Controlar cada um com seu próprio canal PWM do Pico mistura as cores: vermelho + verde = amarelo, verde + azul = ciano, os três = branco. Aqui, o LED alterna entre 8 cores. Aprenda sobre múltiplos canais PWM, definição de funções (def set_color(...)), mistura de cores RGB (como funcionam telas e lâmpadas inteligentes), conversão de 8 bits → 16 bits (x257 converte 0–255 em…

0.0(0)
6
Servo motor com ESP32 (controle por potenciômetro)
#118Intermediário
Premium

Servo motor com ESP32 (controle por potenciômetro)

Neste projeto, controlamos um servo motor SG90 com um potenciômetro. Ajustamos o ângulo do servo mapeando o valor analógico lido do potenciômetro para a faixa de 0 a 180 graus. A biblioteca ESP32Servo gera sinais para o servo nos GPIOs do ESP32 adequados e capazes de operar como saída; este projeto usa o GPIO 18. Esse é um método básico de controle para braços robóticos, estabilizadores de câmera e mecanismos de portas automáticas.

4.3(29)
42
Luminária com mistura de cores e ESP32 (3 potenciômetros + LED RGB + OLED)
#138Avançado
Premium

Luminária com mistura de cores e ESP32 (3 potenciômetros + LED RGB + OLED)

Uma luminária inteligente que permite misturar a cor que você quiser girando três potenciômetros com o ESP32! Ao girar os potenciômetros de vermelho, verde e azul, o LED RGB de cátodo comum muda de cor em tempo real. O display OLED SSD1306 mostra os valores de cada cor na faixa de 0–255, barras de preenchimento e o código HEX da cor para a web, como #FF8040.

4.7(6)
10