Controle de potência via PWM - ESP32
Controle de potência via PWM - ESP32
A modulação por largura de pulso (PWM) é uma técnica amplamente utilizada em diversos meios, principalmente para controle de potência e velocidade. Neste tutorial, você aprenderá a configurar o PWM no ESP32 através do recurso LED PWM e fazer um LED "respirar" (fade) ou acender com metade do brilho.
[toc]
Pulse Width Modulation
Com o PWM, podemos controlar a tensão média em um componente, e por consequência a potência, como um LED, a velocidade de um motor DC ou até converter o sinal PWM criado (onda quadrada) para uma onda senoidal com a adição de alguns poucos itens.
As imagens (GIF) abaixo mostram o duty cycle variando, que altera a tensão média entregue ao componente. Em alguns casos como motores, também é preciso configurar corretamente a frequência de chaveamento e ter atenção ao nível de pico máximo aceito na alimentação, entretanto isso ficará de "lição de casa" para pesquisarem.
![Controle de potência via PWM - ESP32](https://portal.vidadesilicio.com.br/wp-content/uploads/2017/12/pwm_fade.gif)
![Controle de potência via PWM - ESP32](https://portal.vidadesilicio.com.br/wp-content/uploads/2017/12/PWMan.gif)
Mãos a obra - Variando o brilho do LED
Componentes necessários
- 1x - LED (Usaremos o LED Onboard).
- 1x - ESP32 (Usaremos o NodeMCU-32).
Código do projeto
void setup() { pinMode(2, OUTPUT);//Definimos o pino 2 (LED) como saída. ledcAttachPin(2, 0);//Atribuimos o pino 2 ao canal 0. ledcSetup(0, 1000, 10);//Atribuimos ao canal 0 a frequencia de 1000Hz com resolucao de 10bits. } void loop() { for (int i = 0; i < 1024; i++) { ledcWrite(0, i);//Escrevemos no canal 0, o duty cycle "i". delay(2); } for (int i = 1023; i > 0; i--) { ledcWrite(0, i); delay(2); } }
Colocando para funcionar
O código fará um "fade" no LED, dando a sensação de "respiração", aumentando e diminuindo o brilho gradativamente.
Entendendo a fundo
Software
-Função ledcAttachPin()
ledcAttachPin(PINO, CANAL);
Esta função apenas atribui um pino a um canal. Podemos escolher qualquer pino a qualquer canal, este vai de 0 a 15, totalizando 16 canais.
Cada canal é independente do outro, mas você também pode atribuir vários pinos a um mesmo canal.
Pino: Qualquer.
Canal: 0 - 15.
-Função ledcSetup()
ledcSetup(CANAL, FREQUENCIA, RESOLUCAO);
Esta função configura um canal para trabalhar a uma determinada frequência e resolução.
Canal: 0 - 15.
Frequência: 1 - 40MHz.
Resolução: 1 - 16 bits.
-Função ledcWrite()
ledcWrite(CANAL, DUTY CYCLE);
Esta função "escreve" o duty cycle ao canal. Lembramos que o valor colocado no parâmetro duty cycle não é em porcentagem e sim em decimal.
Exemplo: para um duty cycle de 50% com 10bits (2^10 = 1024) de resolução, devemos escrever 512.
Canal: 0 - 15.
Duty cycle: 0 - 100% (em decimal).
Indo além com PWM
Tensão média
Podemos calcular a tensão média (V) entregue ao componente através de uma simples conta que relaciona o sinal HIGH com o duty cycle.
Sinal HIGH do ESP32 (Vcc): ~3.3V.
Duty cycle: 32%.
Ao efetuar a conta de 3.3*0.32, chegamos a conclusão que a tensão média (Vm) entregue será de 1.056V!
Vamos testar este código e verificar as tensões com um multímetro.
void setup() { pinMode(23, OUTPUT);//Definimos o pino 23 como saída. pinMode(22, OUTPUT);//Definimos o pino 22 como saída. pinMode(21, OUTPUT);//Definimos o pino 21 como saída. pinMode(19, OUTPUT);//Definimos o pino 19 como saída. ledcAttachPin(23, 0);//Atribuimos o pino 23 ao canal 0. ledcSetup(0, 1000, 10);//Atribuimos ao canal 0 a frequencia de 1000Hz com resolucao de 10bits. ledcWrite(0, 256);//Escrevemos um duty cycle de 25% no canal 0. ledcAttachPin(22, 1);//Atribuimos o pino 22 ao canal 1. ledcSetup(1, 1000, 10);//Atribuimos ao canal 1 a frequencia de 1000Hz com resolucao de 10bits. ledcWrite(1, 512);//Escrevemos um duty cycle de 50% no canal 1. ledcAttachPin(21, 2);//Atribuimos o pino 21 ao canal 2. ledcSetup(2, 1000, 10);//Atribuimos ao canal 2 a frequencia de 1000Hz com resolucao de 10bits. ledcWrite(2, 768);//Escrevemos um duty cycle de 75% no canal 2. ledcAttachPin(19, 3);//Atribuimos o pino 19 ao canal 3. ledcSetup(3, 1000, 10);//Atribuimos ao canal 3 a frequencia de 1000Hz com resolucao de 10bits. ledcWrite(3, 1023);//Escrevemos um duty cycle de 100% no canal 3. } void loop() { }
Testando este código e verificando o pino respectivo com um multímetro, podemos perceber que as contas são iguais ou próximas. Lembrando que o próprio multímetro tem sua faixa de precisão (erro), que neste caso é (+-0.5% + 3D com 1mV de resolução).
Todos os testes a seguir tem Vcc teórico de 3.3V, as imagens são as leituras do nosso multímetro.
Caso 1, 25% = 0.825V
![](https://portal.vidadesilicio.com.br/wp-content/uploads/2017/12/20171201_114327.jpg)
Caso 2, 50% = 1.65V
![](https://portal.vidadesilicio.com.br/wp-content/uploads/2017/12/20171201_114335.jpg)
Caso 3, 75% = 2.475V
![](https://portal.vidadesilicio.com.br/wp-content/uploads/2017/12/20171201_114347.jpg)
Caso 4, 100% = 3.3V
![](https://portal.vidadesilicio.com.br/wp-content/uploads/2017/12/20171201_114401.jpg)
Todos os valores lidos, mesmo estando próximos aos teóricos, há o erro do multímetro. Aplicando a formula de erro ao valor lido, todos os valores obtidos estão dentro da faixa tolerável de erro, ou seja, estão corretos!
Frequência X resolução
Um problema recorrente com alguns componentes é a frequência necessária de funcionamento. Motores por exemplo, é bastante usado entre 20kHz e 200kHz.
O recurso "LED PWM" do ESP32 é baseado em um clock de 80MHz, logo podemos fazer algumas contas básicas para se chegar a frequência máxima com a resolução escolhida.
Nos exemplos acima, foi usado uma frequência de 1kHz com 10bits de resolução, entretanto pode ser necessário o uso de uma frequência muito maior e a resolução é uma das barreiras para isso. Vamos fazer essa conta com os dados citados para chegar na frequência máxima (Fm).
A resolução deve ser em decimal e não "bits".
80MHz / 10bits
80000000 / 1024 = 78125Hz
A frequência máxima que conseguimos chegar com uma resolução de 10bits no ESP32 é de ~78kHz. Vamos testar!
Caso 1, 32kHz com 10bits
![](https://portal.vidadesilicio.com.br/wp-content/uploads/2017/12/20171201_122721.jpg)
Caso 1.1, 80kHz com 10bits
![](https://portal.vidadesilicio.com.br/wp-content/uploads/2017/12/20171201_122803.jpg)
Como feito nas contas, a frequência máxima realmente foi de ~78kHz para 10bits, mesmo atribuindo 80kHz no código. Agora vamos brincar com frequências mais altas deixando a resolução em 3bits e ver a frequência máxima.
80MHz / 3bits = Fm
80000000 / 8 = 10MHz
Caso 2, 2MHz com 3bits
![](https://portal.vidadesilicio.com.br/wp-content/uploads/2017/12/20171201_123523.jpg)
Caso 2.1: 11MHz com 3bits
![](https://portal.vidadesilicio.com.br/wp-content/uploads/2017/12/20171201_123551.jpg)
Novamente, as contas mostraram um máximo de 10MHz e mesmo atribuindo 11MHz, ficou limitado a 10MHz.
Considerações finais
O PWM é extremamente útil em diversos projetos, permitindo o controle de potência, velocidade, brilho e até inversores (DC-AC) através da modulação da tensão. Apesar de parecer simples apenas "inverter o estado do pino", com frequências um pouco mais altas, não é qualquer microcontrolador que aguenta se manter com uma frequência estável ou se quer chegar em frequências acima de 10MHz. O ESP32 com 1bit de resolução nos permite chegar a 40MHz, dando uma vasta gama de possibilidades em aplicações.