ÍNDICE DE CONTEÚDO
- Franzininho WiFi: Display 7 Segmentos TM1637
- Franzininho WiFi: Primeiros passos na Arduino IDE
- Franzininho WiFi: Explorando as GPIOs com Arduino
- Franzininho WiFi: Leitura de entradas analógicas com Arduino
- Franzininho WiFi: PWM (Pulse Width Modulation) com Arduino
- Franzininho WiFi: Comunicação Serial (UART) com Arduino
- Franzininho WiFi: Servo Motor com Arduino
- Franzininho WiFi: Web Server
- Franzininho WiFi: Display OLED
- Franzininho WiFi: Sensor de temperatura e umidade DHT22
- Franzininho WiFi: Sensor de temperatura DS18B20
- Franzininho WiFi: Display LCD 16×2 com comunicação I2C
PWM, do inglês Pulse Width Modulation, é uma técnica utilizada por sistemas digitais para variação do valor médio de uma forma de onda periódica. A técnica consiste em manter a frequência de uma onda quadrada fixa e variar o tempo que o sinal fica em nível lógico alto. Esse tempo é chamado de duty cycle, ou seja, o ciclo ativo da forma de onda.
O PWM é usado em diversas aplicações que necessitam controlar a potência, por exemplo: velocidade de motor DC, brilho da lâmpada, temperatura de resistência e muitas outras aplicações. Quase todas as GPIOs da Franzininho WiFi possuem suporte para gerar sinais PWM, apenas a GPIO 0 (Boot) e GPIO 46 não possuem esse recurso.
Nesse artigo aprenderemos usar o PWM na Franzininho WiFi com a API do Arduino. A partir desse exemplo você poderá aplicar a técnica PWM em diversos projetos.
API Analog do Arduino
Nesta sessão apresentaremos as funções usadas para configurar e gerar os sinais PWM.
Seminário Linux Embarcado 2024: Evento Presencial em São Paulo
Participe do Seminário Linux Embarcado 2024 em São Paulo. Conhecimento técnico, palestras, workshops e oportunidade de networking com profissionais experientes.
analogWrite
Função para gerar um sinal PWM no pino desejado.
1 |
void analogWrite(uint8_t pin, int value); |
- pin : pino selecionado
- value: configura o valor do Duty Cycle do sinal PWM, o valor está numa faixa de 0 (sempre desligado) a 255 (sempre ligado).
analogWriteResolution
Função usada para configurar a resolução em bits para todos os canais com PWM
1 |
void analogWriterResolution(uint8_t bits); |
- bits : quantidade de bits para configurar o PWM ( 1 – 13)
analogWriteFrequency
Função usada para configurar a frequência em todos os canais com PWM
1 |
void analogWriterFrequency(uint32_t freq); |
- freq : valor da frequência do PWM ( 1 Hz – 40 MHz)
Ao configurar as GPIOs com suporte ao PWM é necessário que se leve em consideração a aplicação desejada pelo projetista, sabendo balancear a relação entre a resolução e a frequência. De acordo com a documentação da Espressif, para frequências de 5 kHz pode ter o máximo de resolução (13 bits), em aplicações que envolvem processamento de imagem é possível utilizar na frequência máxima de 40 MHz com um 1 bit de resolução (50% de Duty Cycle).
Materiais necessários
Os materiais utilizados nesse artigo foram:
- Placa Franzininho WiFi
- Potenciômetro
- Jumpers
- Arduino IDE
Circuito Exemplo para PWM na Franzininho WiFi
O circuito proposto para esse artigo envolve apenas um componente externo, potenciômetro, um LED da placa Franzininho WiFi, mas caso deseje utilizar um LED externo para aplicação conecte a GPIO 33 e terá acesso à saída do sinal PWM gerado.
Código
O projeto proposto é controlar a intensidade do LED a partir da rotação do eixo potenciômetro. Como mencionado anteriormente, vamos alterar Duty Cycle do sinal PWM mapeando as leituras analógicas do canal ADC, utilizando a função nativa do Arduino , map().
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
/* Autor : Equipe Embarcados */ #define MAX_ADC_VALUE 4096 #define MIN_ADC_VALUE 0 #define MAX_DUTY_CYCLE 255 #define MIN_DUTY_CYCLE 0 #define MAX_RESOLUTION 13 int adc_signal; int duty_cycle; const int potentiometer = 4; const int led_yelllow = 33; void setup() { /*Configura a resolução do sinal PWM */ analogWriteResolution(MAX_RESOLUTION); /*Configura o led como saída digital*/ pinMode(led_yelllow, OUTPUT); } void loop() { /* Pega a leitura do canal ADC*/ adc_signal = analogRead(potentiometer); /*Mapea as leituras ADC para valores entre MIN_DUTY_CYCLE - MAX_DUTY_CYCLE */ duty_cycle = map(adc_signal,MIN_ADC_VALUE,MAX_ADC_VALUE,MIN_DUTY_CYCLE,MAX_DUTY_CYCLE); /*Gera o sinal PWM com o duty_cycle*/ analogWrite(led_yelllow, duty_cycle); } |
Simule esse projeto no Wokwi: https://wokwi.com/projects/363007792774465537
Explicação do Código
Nesta seção vamos abordar cada trecho do código a fim de esclarecer o uso das funções.
Define os máximos e mínimos do canal ADC e do Duty Cycle do PWM, além disso adicionou uma definição de resolução máxima.
1 2 3 4 5 6 7 |
#define MAX_ADC_VALUE 4096 #define MIN_ADC_VALUE 0 #define MAX_DUTY_CYCLE 255 #define MIN_DUTY_CYCLE 0 #define MAX_RESOLUTION 13 |
Variáveis para armazenar os valores ADC (adc_signal) e para armazenar os valores mapeados do Duty Cycle (duty_cycle).
1 2 |
int adc_signal; int duty_cycle; |
Declarando as cosntantes para mapeamento dos pinos físicos.
1 2 |
const int potentiometer = 4; const int led_yelllow = 33; |
No void setup() , configura a resolução do sinal PWM e o LED Azul on board como OUTPUT.
1 2 3 4 5 6 7 |
void setup() { /*Configura a resolução do sinal PWM */ analogWriteResolution(MAX_RESOLUTION); /*Configura o led como saída digital*/ pinMode(led_yelllow , OUTPUT); } |
No void loop(), utilizamos a função map() para realizar um reajuste de escala de valores compatíveis para o duty cycle, visto que seu intervalo é de 0 – 255 e do canal ADC é 0 – 4096. Ao realizar a leitura do potenciômetro e mapear o valor, vamos gerar o sinal PWM de acordo com o valor da variável duty_cycle.
1 2 3 4 5 6 7 8 9 |
void loop() { /* Pega a leitura do canal ADC*/ adc_signal = analogRead(potentiometer); /*Mapea as leituras ADC para valores entre MIN_DUTY_CYCLE - MAX_DUTY_CYCLE */ duty_cycle = map(adc_signal,MIN_ADC_VALUE,MAX_ADC_VALUE,MIN_DUTY_CYCLE,MAX_DUTY_CYCLE); /*Gera o sinal PWM com o duty_cycle*/ analogWrite(led_yelllow, duty_cycle); } |
Conclusão
Nesse artigo abordamos sobre uma técnica de modulação por largura de pulso (PWM), configuramos os canais e escrevemos na saída da GPIO o sinal PWM. Para realizar o controle de outros componentes que exigem uma potência maior, deve-se utilizar um circuito adicional de potência para garantir a entrega de corrente e tensão adequada. No exemplo de projeto apresentamos uma forma de abstrair uma aplicação bem comum em ambientes residenciais, o dimmer.
Para assegurar a compreensão do tema, recomendamos fortemente que faça a acionamento de motores DC e LEDs, LEDs RGB, etc.
Saiba mais
Franzininho WiFi: A placa versátil para iniciantes e desenvolvedores experientes