Explorando os Pinos PWM - ESP32
- automatelabonline
- 1 de mar.
- 4 min de leitura
A Modulação por Largura de Pulso é uma técnica utilizada por muitos microcontroladores para simular sinais analógicos. O ESP32 apresenta duas saídas verdadeiramente analógicas (GPIO25 e GPIO26), que geram uma tensão entre 0V e 3,3V. Porém, a placa também oferece diversas saídas PWM, que podem ser úteis para muitos casos onde uma saída analógica é necessária.
O ESP32 contém 21 portas que podem atuar na função PWM. Porém, só é possível utilizar 16 canais de PWM simultaneamente. A imagem abaixo mostra a pinagem do ESP32. Os pinos com PWM são marcados com um símbolo de ~.

Entendendo o PWM do ESP32
Um termo importante quando tratamos de PWM é o duty cycle. O duty cycle representa a proporção de tempo que o sinal permanece em nível alto. A tensão de saída média do PWM é dada pela equação:

Sendo Vout a tensão média da saída, Vcc a tensão em nível alto, que no ESP32 é de 3,3V e dc o duty cycle, em porcentagem. Na imagem abaixo é mostrado alguns exemplos de sinais para diferentes duty cycles.

A resolução do PWM do ESP32 é configurável, podendo ser entre 1 e 16 bits. Ou seja, existem até 2¹⁶ = 65536 possibilidades de tensões. Como essa tensão varia entre 0V e 3,3V, o mínimo intervalo entre tensões é de:

Funções para os Pinos PWM do ESP32
Configurando o Pino
O primeiro passo para utilizar um pino é associar esse pino com um canal PWM. Para isso, é necessário utilizar a função:
ledcAttachPin(PINO, CANAL);
Onde PINO representa o número do pino do ESP32 e CANAL o número o canal PWM, que pode ir de 0 a 15.
O próximo passo é configurar esse canal, selecionando sua frequência de saída e sua resolução. Isso é feito com a função:
ledcSetup(CANAL, FREQUENCIA, RESOLUCAO);
CANAL representa o canal PWM que está sendo configurado, FREQUENCIA a frequência do sinal modulado, podendo ir de 1Hz até 40kHz, e RESOLUÇÃO a quantidade de bits que representará o sinal da saída, indo entre 1 e 16 bits.
Enviando um Sinal para o Pino
Para escrever nos pinos PWM, é utilizada a função:
ledcWrite(CANAL, VALOR);
VALOR é um número inteiro que varia entre 0 e 2ⁿ -1, sendo n o número de bits configurado na resolução. Esse valor representa o duty cycle que será enviado. Dado um valor de tensão desejado Vd. O valor que deve ser preenchido (vamos chamá-lo de D ) é dado por:

Outra fórmula útil é o valor de D em função do duty cycle que se deseja obter.

Sendo dc o duty cycle dado em porcentagem.
Projeto - Controlando o Brilho de um LED
Para aplicar o conhecimento sobre os pinos PWM, vamos criar um projeto para controlar o brilho de um LED através de um potenciômetro. Na imagem abaixo é mostrado a ligação dos componentes com o ESP32. O pino 4 é utilizado para ler o potenciômetro. O pino 14 é utilizado para gerar o sinal PWM que alimenta o LED.

Segue abaixo o código desse projeto.
#define PIN_LED 14 // define o pino do LED
#define PIN_POTENTIOMETER 4 // define o pino do potenciômetro
#define CHANNEL_LED 0 // define o canal PWM do LED
void setup() {
pinMode(PIN_POTENTIOMETER, INPUT); // configuração dos pinos
pinMode(PIN_LED, OUTPUT);
ledcAttachPin(PIN_LED, CHANNEL_LED);
ledcSetup(CHANNEL_LED, 1000, 12); // opcional
}
void loop() {
int ledIntensity = analogRead(PIN_POTENTIOMETER);
ledcWrite(CHANNEL_LED, ledIntensity); // Manda o sinal para o LED
delay(10);
}
Entendendo o Código
Primeiro, são definidos os pinos de entrada e saída, junto com o canal PWM que será utilizado. Como entrada analógica, o pino 4 é utilizado. Já como saída PWM, temos o pino 14, que está associado ao canal PWM 0.
#define PIN_LED 14 // define o pino do LED
#define PIN_POTENTIOMETER 4 // define o pino do potenciômetro
#define CHANNEL_LED 0 // define o canal PWM do LED
Logo depois, na função setup(), esses pinos são configurados. O pino 4 é definido como entrada e o 14 como saída. É feita a associação do pino 14 com o canal 0 do PWM, utilizando a função ledcAttachPin(PINO, CANAL). Esse canal é configurado utilizando a função ledcSetup(CANAL, FREQUENCIA, RESOLUCAO), onde é definida a frequência do PWM para 1000Hz e 12 bits de resolução.
void setup() {
pinMode(PIN_POTENTIOMETER, INPUT); // configuração dos pinos
pinMode(PIN_LED, OUTPUT);
ledcAttachPin(PIN_LED, CHANNEL_LED);
ledcSetup(CHANNEL_LED, 1000, 12); // opcional
}
Já na função loop(), o pino do potenciômetro é lido e salvo na variável ledIntensity. Depois, utilizando a função ledcWrite(CANAL, VALOR), o canal PWM 0 (e consequentemente o pino 14) recebe um sinal referente ao valor da leitura do potenciômetro. Como a leitura das portas analógicas também é de 12 bits, não é preciso fazer nenhuma transformação nesse valor.
void loop() {
int ledIntensity = analogRead(PIN_POTENTIOMETER);
ledcWrite(CHANNEL_LED, ledIntensity); // Manda o sinal para o LED
delay(10);
}
Conclusões
Em conclusão, os pinos PWM do ESP32 são uma ferramenta poderosa e versátil para a criação de projetos eletrônicos que exigem controle preciso de intensidade de sinal, como no caso de motores, LEDs e outros dispositivos. A flexibilidade do ESP32 em termos de configuração e a alta precisão de sua modulação tornam-no uma excelente escolha para uma ampla gama de aplicações.
Além disso, sua fácil integração com outras funcionalidades do microcontrolador, como Wi-Fi e Bluetooth, amplia ainda mais seu potencial em projetos de automação e Internet das Coisas (IoT). Ao explorar e compreender o funcionamento dos pinos PWM do ESP32, os desenvolvedores podem tirar proveito de suas capacidades para criar sistemas mais eficientes e dinâmicos, proporcionando soluções inovadoras e de alto desempenho.
Comments