PWM no Arduino: controlando brilho e velocidade com analogWrite

Você já quis deixar um LED acendendo aos poucos, tipo aquele "respirar" bonito, ou controlar a velocidade de um motorzinho? O Arduino Uno não tem uma saída analógica de verdade, mas tem um truque genial chamado PWM. Com uma única linha de código, o analogWrite, você controla brilho, velocidade e muito mais. Vamos entender como isso funciona por dentro (é mais simples do que parece) e sair usando na prática.

O que é PWM

PWM é a sigla de Pulse Width Modulation, ou Modulação por Largura de Pulso. O nome assusta, mas a ideia é boba: o pino fica ligando e desligando muito rápido.

Um pino digital do Arduino só sabe fazer duas coisas: ligar (5V, o famoso HIGH) ou desligar (0V, o LOW). Não existe meio-termo. Mas e se ele ligar e desligar centenas de vezes por segundo? Aí entra a mágica.

Imagine um LED. Se o pino fica ligado metade do tempo e desligado a outra metade, o LED pisca tão rápido que seu olho não percebe o piscar — ele só enxerga um brilho médio, mais fraco. Se o pino fica ligado 90% do tempo, o LED fica quase no brilho total. Se fica ligado só 10% do tempo, fica bem fraquinho.

Essa proporção de "tempo ligado" é o que chamamos de duty cycle (ciclo de trabalho):

Duty cycleTempo ligadoResultado no LED
0%nuncaapagado
25%1/4 do tempofraquinho
50%metadebrilho médio
75%3/4 do tempoforte
100%semprebrilho total

No Arduino Uno, esse liga-desliga acontece a cerca de 490 Hz na maioria dos pinos (quase 500 vezes por segundo). Rápido demais para o olho — e para muitos motores — perceberem.

Por que analogWrite não é analógico de verdade

Aqui está a parte que confunde muita gente. A função se chama analogWrite, mas ela não gera uma tensão analógica como 2,5V ou 3,7V no pino. O pino continua chaveando entre 0V e 5V, sempre.

O que muda é só a proporção de tempo em cada estado. Um multímetro comum, que faz média, vai ler algo parecido com uma tensão intermediária — e para um LED ou motor o efeito prático é o mesmo de reduzir a tensão. Mas o sinal, de verdade, é uma onda quadrada digital pulsando. Por isso dizemos que o PWM simula um valor analógico, sem ser um.

Isso importa na prática: se você precisar de uma tensão analógica pura (para um circuito de áudio sensível, por exemplo), o PWM cru não serve sem um filtro. Para brilho de LED e velocidade de motor, funciona perfeitamente.

Como usar analogWrite

A sintaxe é direta:

analogWrite(pino, valor);

O valor vai de 0 a 255, e não de 0 a 100. Por quê? Porque o Arduino usa 8 bits para essa resolução, e 8 bits dão 256 níveis (2⁸ = 256), de 0 a 255. Então:

  • analogWrite(pino, 0) → duty cycle 0% (desligado)
  • analogWrite(pino, 127) → mais ou menos 50%
  • analogWrite(pino, 255) → duty cycle 100% (ligado no máximo)

Só funciona nos pinos com ~

Este é o detalhe que derruba iniciante. Nem todo pino faz PWM. No Arduino Uno, só os pinos marcados com um til (~) na plaquinha conseguem. São exatamente estes seis:

3, 5, 6, 9, 10 e 11

Olhe seu Uno: ao lado desses números tem um ~. Se você chamar analogWrite em um pino sem til (como o 2, 4, 7, 8), não vai dar erro de compilação, mas o pino só vai ligar ou desligar de forma crua — sem controle de brilho de verdade. Frustração garantida se você não souber disso.

Cada placa é diferente. No Arduino Mega, por exemplo, há muito mais pinos PWM. Sempre confie no símbolo ~ impresso na placa.

Exemplo prático: fade de LED

Vamos fazer aquele efeito de LED "respirando", acendendo e apagando suavemente. Monte assim:

  • LED no pino 9 (que tem ~), perninha longa (anodo) no lado do pino
  • Um resistor de 220 Ω em série com o LED (nunca ligue LED direto no pino — o resistor limita a corrente e protege o LED e o Arduino)
  • Outra perna do LED no GND
const int pinoLED = 9;  // pino com ~ (PWM)

void setup() {
  pinMode(pinoLED, OUTPUT);
}

void loop() {
  // Sobe o brilho de 0 até 255
  for (int brilho = 0; brilho <= 255; brilho++) {
    analogWrite(pinoLED, brilho);
    delay(8);
  }

  // Desce o brilho de 255 até 0
  for (int brilho = 255; brilho >= 0; brilho--) {
    analogWrite(pinoLED, brilho);
    delay(8);
  }
}

Cada volta do for muda um pouquinho o brilho e espera 8 ms. O olho junta tudo e vê o LED "respirando". Mude o delay para acelerar ou desacelerar o efeito.

E para controlar velocidade de motor?

O mesmo analogWrite controla a velocidade de um motor DC. Só que tem uma regra de ouro: nunca ligue um motor direto no pino do Arduino.

Um pino do Arduino entrega no máximo cerca de 20 a 40 mA com segurança. Um motorzinho puxa facilmente centenas de miliampères, ou mais. Ligar direto queima o pino na hora — e possivelmente o Arduino inteiro.

A solução é um driver de motor no meio, como o L298N ou o DRV8871. Funciona assim: o Arduino manda o sinal PWM fraquinho para o driver, e o driver usa esse sinal para chavear a corrente forte (da bateria) que vai para o motor. Você controla, o driver faz a força.

Na prática, você conecta o pino PWM do Arduino a uma entrada do driver e faz:

const int pinoVelocidade = 5;  // pino ~ ligado ao driver

void setup() {
  pinMode(pinoVelocidade, OUTPUT);
}

void loop() {
  analogWrite(pinoVelocidade, 128);  // motor a ~50% da velocidade
  delay(2000);
  analogWrite(pinoVelocidade, 255);  // velocidade máxima
  delay(2000);
  analogWrite(pinoVelocidade, 0);    // parado
  delay(2000);
}

Um detalhe real: motores costumam não sair do lugar em valores muito baixos (tipo 30 ou 40), porque falta força para vencer a inércia. Faça testes para achar o valor mínimo que faz o seu motor começar a girar.

Erros comuns

  • Usar pino sem ~. Só 3, 5, 6, 9, 10 e 11 no Uno fazem PWM. O resto não controla brilho.
  • Achar que o valor vai até 100. A escala é 0 a 255. Passar de 255 não faz nada além de saturar em 100%.
  • Esquecer o resistor do LED. Sempre use um resistor em série (220 Ω é um bom começo). LED direto no pino queima o LED e maltrata o Arduino.
  • Ligar motor direto no pino. Sempre use um driver. O pino não aguenta a corrente.
  • Confundir com analogRead. analogWrite escreve PWM na saída; analogRead lê tensão nos pinos analógicos (A0–A5). São coisas diferentes.
  • Esperar tensão analógica pura no multímetro. O sinal é uma onda quadrada pulsando; a "tensão média" é só a leitura do aparelho.

Fechando

PWM é uma daquelas ferramentas que abrem um mundo: com um simples analogWrite você faz LEDs pulsarem, ajusta a velocidade de motores, controla a intensidade de aquecedores e até gera tons. Entender que por baixo é só um liga-desliga muito rápido tira todo o mistério — e te deixa no controle.

Se você quer aprender eletrônica e Arduino do jeito certo, sem decoreba e com a mão na massa, dá uma olhada no Curso Maker. A gente monta os circuitos juntos, passo a passo, até virar natural.