🎯 PCA9685

Em poucas palavras

O PCA9685 é um circuito integrado de 16 canais de PWM com resolução de 12 bits, controlado por I2C. Ele tira do microcontrolador a responsabilidade de gerar os sinais de PWM diretamente, o que é especialmente útil quando se precisa controlar vários servos ao mesmo tempo (o número de pinos PWM de um microcontrolador comum não seria suficiente).


📝 Notas e Desenvolvimento

O que é

  • Fabricado pela NXP Semiconductors.
  • 16 canais de saída independentes, cada um com PWM de 12 bits de resolução (4096 passos por período).
  • Comunicação via I2C — o microcontrolador só manda “qual duty cycle eu quero em qual canal”, e o próprio chip sustenta o sinal PWM sozinho, em hardware.
  • Endereço I2C padrão 0x40, mas configurável de 0x40 a 0x7F através de 6 pinos de endereço (A0-A5) — o que permite colocar várias placas no mesmo barramento I2C sem conflito.

Por que isso importa na prática

Gerar PWM por software, “na unha”, em vários canais ao mesmo tempo consome tempo de CPU e tende a gerar jitter (variação indesejada no sinal). Delegar isso a um chip dedicado como o PCA9685 libera o microcontrolador para outras tarefas e garante um sinal mais estável — importante sobretudo para servos, que são sensíveis a ruído no pulso.

Alimentação: dois circuitos, não um

Um ponto que costuma confundir quem usa a placa pela primeira vez: existem dois pinos de alimentação diferentes, que não podem set tratados como equivalentes.

PinoAlimentaObservação
VCCA lógica do chip (I2C, registradores)Pode vir do próprio microcontrolador (3.3V ou 5V)
V+ (bloco de terminais separado)A saída de força para os servos/LEDsPrecisa de fonte externa; não alimentar pela USB/3.3V do microcontrolador

Ligar os servos direto na saída de 3.3V/5V de uma placa de microcontrolador costuma set o motivo por trás de resets aleatórios ou comportamento errático — os servos puxam mais corrente do que essa saída consegue entregar com estabilidade.

O pino OE (Output Enable)

  • Pino ativo em nível baixo: OE = LOW habilita as saídas normalmente; OE = HIGH força todas as saídas desligadas, independente do que estiver escrito nos registradores.
  • Em algumas placas breakout genéricas, esse pino não vem aterrado internamente por padrão — ele fica flutuando. Nesse estado, o chip continua respondendo perfeitamente aos commandos I2C (os registradores são escritos, a comunicação “funciona”), mas nenhum PWM real chega aos servos.

Sintoma característico

Se a comunicação I2C parece perfeita (o chip responde, os commandos são aceitos) mas nada se move fisicamente, o pino OE é o primeiro lugar a checar — basta um jumper ligando-o a qualquer GND da placa.

Como o chip guarda o PWM: registradores principais

RegistradorEndereçoFunção
MODE10x00Modo de operação geral; inclui o bit de sleep, necessário para alterar o prescaler
PRESCALE0xFEDefine a frequência do PWM; só pode set alterado com o chip em modo sleep
LED0_ON_L (e seguintes)a partir de 0x06Cada canal usa 4 registradores (ON_L, ON_H, OFF_L, OFF_H) que definem em que ponto do período o pulso liga e desliga

O cálculo do prescaler, para uma frequência de atualização desejada (por exemplo, 50 Hz para servos), segue a fórmula do datasheet:

prescale = round(25_000_000 / (4096 * freq_hz)) - 1

Onde 25_000_000 é a frequência do oscilador interno (25 MHz) e 4096 é a resolução (12 bits).

Exemplo prático: traduzindo ângulo em PWM para servo

Para um servo de 180°, o ângulo desejado é convertido primeiro em uma largura de pulso (tipicamente entre 500µs e 2500µs, embora isso varie por modelo de servo) e depois em “ticks” dentro do período de 4096 passos:

def set_angle(angle_deg):
    angle_deg = max(0, min(180, angle_deg))
    pulso_us = 500 + (2500 - 500) * (angle_deg / 180.0)
    periodo_us = 1_000_000 / 50  # 50 Hz
    ticks = int(pulso_us * 4096 / periodo_us)
    # grava `ticks` no par de registradores OFF do canal desejado

📚 Referências e Fontes

🔗 Conexões do Cofre

🌐 Referências Externas