MicroPython – Gerando PWM em ESP8266 e ESP32

A modulação por largura de pulso (PWM) é uma das cinco funcionalidades básicas de qualquer microcontrolador. Os outros quatro são entrada digital, saída digital, entrada analógica e comunicação serial de dados. A maioria dos microcontroladores não possui um conversor digital para analógico integrado para emitir sinais analógicos. No entanto, a maioria dos microcontroladores possui uma ou mais interfaces de saída PWM. Os sinais PWM são sinais retangulares periódicos com duração de pulso ON e OFF programável. Com uma largura de pulso modulada, esses sinais podem aproximar-se da saída analógica verdadeira. Os sinais PWM não se destinam à comunicação analógica de dados, ao fornecimento de energia elétrica ou ao trabalho com circuitos analógicos. No entanto, esses sinais são muito úteis para fornecer potência de saída para componentes externos, como luzes LED e alto-falantes. Esses sinais também podem ser usados ​​como sinais de controle para atuadores como servo motores.

Os sinais PWM são usados ​​para controlar dispositivos em vez de fornecer energia a eles. A potência de saída de um microcontrolador GPIO é muito pequena para acionar praticamente qualquer atuador ou dispositivo. Por exemplo, a corrente máxima que as placas ESP32 e ESP8266 podem absorver ou fornecer é de apenas 40 mA e a tensão operacional é de apenas 3,3V. Circuitos amplificadores de potência externos são necessários para acionar componentes como alto-falantes e campainhas com sinais PWM.

O que é modulação por largura de pulso?
A modulação por largura de pulso altera a potência média fornecida por um sinal, dividindo o sinal de onda quadrada em partes discretas. Não é um sinal contínuo real. Em vez disso, a duração de ON e OFF de um sinal digital periódico é modulada para reduzir a tensão/potência efetiva de saída. Por exemplo, se o GPIO de um microcontrolador emitir 3,3 V na saída digital enquanto gera um sinal PWM de 50% do ciclo de trabalho do pino, ele produzirá uma tensão efetiva de aproximadamente 1,65 V, ou seja, 3,3/2.

PWM vs. saída analógica
Os sinais PWM não são sinais analógicos verdadeiros. Os verdadeiros sinais analógicos são contínuos e podem ter qualquer valor flutuante. Os sinais PWM são gerados dividindo a duração da saída dos sinais digitais por valores discretos. Portanto, os sinais PWM podem aproximar-se das saídas analógicas esperadas, mas nunca podem ter valores flutuantes semelhantes. O quão próximo um sinal PWM pode se aproximar de um valor de ponto flutuante depende de sua resolução. Por exemplo, ESP8266 tem uma resolução PWM de 10 bits com tensão operacional em seu GPIO de 3,3V. Assim, as tensões que o controlador PWM ESP8266 pode aproximar serão em passos de 3,3/1023 V ou 3,22 mV.

Além disso, observe que os sinais PWM são sinais periódicos. Eles não podem aproximar sinais contínuos não periódicos; mesmo sendo sinais periódicos, os sinais PWM não conseguem aproximar com precisão todas as frequências. O quão próximo um sinal PWM pode corresponder a uma frequência de saída depende da frequência base do microcontrolador e da resolução PWM. Por exemplo, a frequência base no ESP32 pode variar de 1 Hz a 40 MHz, e a resolução PWM pode ser definida de 1 a 16 bits. Deixe-o ser definido como 10 bits. Suponha que você queira emitir uma frequência de 300 KHz. Se a frequência base for definida como 40 MHz, o divisor necessário para gerar a frequência de 300 KHz será 40.000.000/300.000, ou seja, 133,33. Se usarmos 133 como divisor, a frequência real do sinal que obtemos é 40.000.000/133, ou seja, 300.751 Hz. Isto não é precisamente 300 KHz.

Além disso, observe que a saída PWM depende em grande parte do comportamento específico do microcontrolador/porta específico. Por exemplo, as placas Arduino usam um relógio de hardware dedicado para gerar sinais PWM. As placas ESP utilizam temporizadores e interrupções para geração de PWM, começando com frequência base teórica de 80 MHz. O controlador PWM no ESP32 consiste em dois submódulos – Controle de LED (LEDC) e Modulador de Largura de Pulso de Controle de Motor (MCPWM). No MicroPython, o IoT Development Framework (IDF) do Expressif é usado como kit de desenvolvimento de software. O kit usa a mesma API para implementação PWM em ESP8266 e ESP32. No ESP32, o firmware MicroPython utiliza um periférico LEDC para geração de PWM. As frequências mínimas e máximas do Arduino dependem apenas da frequência base do clock e da resolução PWM. Mas, no caso das placas ESP, depende não apenas da implementação de hardware, como as frequências base suportadas no IDF do Expressif, mas também da implementação de software no firmware MicroPython. Discutiremos isso em detalhes posteriormente neste artigo.

Biblioteca de máquinas MicroPython
O módulo de máquina gerencia muitas funções relacionadas a hardware no MicroPython. Este módulo consiste em várias classes que são escritas para controlar entrada/saída digital, controlar sinais de saída de dispositivos externos, modulação por largura de pulso, conversão de analógico para digital, controlar periféricos ADC, UART, SPI, I2C, I2S, Timer, RTC, Watchdog timer e gerenciar o cartão SD. O controlador PWM é gerenciado pela classe PWM do módulo da máquina.

Classe MicroPython PWM
A classe PWM foi escrita para fornecer modulação por largura de pulso em placas suportadas por MicroPython. Esta classe pode ser importada para um script MicroPython usando as instruções a seguir.
da importação da máquina PWM

Após a importação, um objeto deve ser instanciado da classe PWM. Para isso, o método machine.PWM é fornecido. Este método possui a seguinte sintaxe.
máquina de classe.PWM (destino, *, frequência, dever_u16, dever_ns)

Esta construção retorna um objeto PWM. O destino parâmetro é o pino PWM no qual a saída PWM deve ser gerada. Isso pode ser especificado por um identificador específico da porta que pode ser um número inteiro, uma string ou uma tupla, dependendo da porta específica. O frequencia, dever_u16, e dever_ns são parâmetros opcionais. O frequencia parâmetro é a frequência em Hz para o ciclo PWM. O dever_u16 parâmetro especifica o ciclo de trabalho como proporção duty_cycle/65535. O dever_ns parâmetro especifica a duração do pulso em nanossegundos. Se a frequência for especificada, somente duty_u16 ou somente duty_ns deverá ser fornecido. Alguns dos exemplos válidos de instanciação de objetos PWM são os seguintes.
pwm0 = máquina.PWM(Pino(0))
pwm0 = PWM(Pino(0))
pwm0 = PWM(Pino(0), 5000)
pwm0 = PWM(Pin(0), 5000, 2**16*1//2) //ciclo de trabalho de 50%
pwm0 = PWM(Pino(0), 5000, 250_000)

A classe inclui os seguintes métodos para configurar a saída PWM.

PWM.freq : Este método é usado para obter ou definir a frequência atual da saída PWM. Se chamado sem argumentos, retorna a frequência em Hz. Um único argumento inteiro pode ser passado para a chamada do método para definir a frequência em Hz. A faixa de frequência aceitável depende do microcontrolador/porta específico.

PWM.duty : Este método obtém ou define o ciclo de trabalho como proporção duty_cycle/1023. Se chamado sem argumentos, ele retorna o ciclo de trabalho como um valor inteiro sem sinal entre 0 e 1023. Um argumento inteiro sem sinal com um valor de 0 a 1023 deve ser passado para definir o ciclo de trabalho. Por exemplo, pwm0.duty(512) define o ciclo de trabalho do objeto PWM pwm0 para 50%.

PWM.duty_u16 : este método obtém ou define o ciclo de trabalho como o valor não assinado de 16 bits no intervalo de 0 a 65535. Se chamado sem argumentos, ele retorna o ciclo de trabalho como um número não assinado de 16 bits entre 0 e 65535. Um argumento longo não assinado com um valor de 0 a 65535 deve ser passado para definir o ciclo de trabalho.

PWM.duty_ns : Este método define ou obtém a largura de pulso atual da saída PWM em nanossegundos. Quando chamado sem argumentos, retorna a largura do pulso em nanossegundos. Um valor na faixa de 0 a 1000.000.000 deve ser passado para definir a largura do pulso.

PWM.init(*, frequência, dever_u16, dever_ns): Modifica as definições de configuração do objeto PWM depois que o objeto já foi construído. Ele aceita os mesmos parâmetros do objeto construtor, exceto o pino PWM.

PWM.deinit : Este método desativa o objeto PWM.

Vale a pena notar que a resolução da frequência e do ciclo de trabalho são interdependentes. Quanto maior for a frequência, menor será a resolução do ciclo de trabalho disponível.

PWM em ESP8266
ESP8266 possui quatro interfaces de saída PWM dedicadas. Essas interfaces PWM estão listadas abaixo.

MicroPython permite especificar uma faixa de frequência de 1 Hz a 1 KHz e uma resolução PWM de 10 bits para ESP8266. No MicroPython, até 8 saídas PWM podem ser executadas no ESP8266. Dê uma olhada na captura de tela a seguir de esppwm.c no firmware MicroPython. No ESP8266 também é possível implementar PWM por software. Isto envolve o uso de interrupções de temporizador. O software PWM no ESP8266 pode ter uma resolução de até 44 nanossegundos. A faixa de frequência PWM pode ser ajustada de 1 microssegundo a 10.000 microssegundos, ou seja, 100 Hz a 1KHz. O software PWM no ESP8266 permite uma resolução de ciclo de trabalho de 14 bits a uma frequência de 1 KHz. No ESP8266, o PWM pode ser emitido em todos os GPIO, exceto GPIO16.

Módulo MicroPython PWM para ESP32

Captura de tela do módulo MicroPython PWM para porta ESP8266

Para ESP8266, o objeto PWM pode ser instanciado usando o construtor machine.PWM . Observe que os parâmetros duty_u16 ou duty_ns não são aceitáveis ​​para a porta ESP8266. A frequência PWM pode ser definida ou obtida usando o método PWM.freq . O valor aceitável para definir a frequência está entre 1 e 1000. O ciclo de trabalho PWM pode ser definido ou obtido usando o método PWM.duty . O método aceita um valor de 10 bits como parâmetro e define a frequência como razão duty_cycle/1023. Observe que você não pode usar duty_u16 ou duty_ns para definir ou obter o ciclo de trabalho do ESP8266, pois a placa permite apenas resolução PWM de 10 bits. Um objeto PWM pode ser desabilitado chamando o método PWM.deinit .

PWM no ESP32
O controlador PWM no ESP32 consiste em dois submódulos diferentes – Controle de LED (LEDC) e Modulador de Largura de Pulso de Controle de Motor (MCPWM). O firmware MicroPython utiliza apenas o módulo LEDC para geração PWM. Isso fica evidente na captura de tela a seguir de ports/esp32/machine_pwm.c no firmware MicroPython.

Módulo PWM MicroPython para ESP8266

Captura de tela do módulo MicroPython PWM para porta ESP8266

Existem 16 canais PWM independentes no ESP32. Esses canais são divididos em dois grupos – um grupo de oito canais de alta velocidade e outro grupo de 8 canais de baixa velocidade. Os canais PWM podem ser multiplexados para qualquer GPIO, exceto os pinos somente de entrada, ou seja, GPIO34~39. Para cada grupo, existem quatro temporizadores por oito canais. Isso significa que cada temporizador está acoplado a dois canais PWM. Portanto, apenas oito frequências PWM diferentes podem ser geradas por vez a partir de 16 canais PWM. Contudo, é possível ter diferentes ciclos de trabalho em todos os 16 canais PWM. MicroPython permite usar o software PW para gerar uma frequência PWM diferente de 8 canais PWM.

O módulo LEDC do controlador PWM do ESP32 pode usar um dos três relógios de origem diferentes listados abaixo.

O firmware MicroPython utiliza apenas duas fontes de relógio APB_CLK e REF_TICK. Se a frequência de um objeto PWM estiver definida abaixo de 10 Hz, REF_CLK é usado pelo firmware; caso contrário, APB_CLK será usado como fonte de relógio. Dê uma olhada na captura de tela a seguir de ports/esp32/machine_pwm.c no firmware MicroPython.

A frequência PWM também é limitada pela resolução do ciclo de trabalho, além da fonte do clock. Tanto a frequência PWM quanto a resolução do ciclo de trabalho são inversamente proporcionais. Quanto maior a frequência, menor será a resolução do ciclo de trabalho disponível.

Finalmente, a resolução PWM e a resolução do ciclo de trabalho também são limitadas pela implementação PWM do MicroPython. Enquanto o clock base APB_CLK usado pelo IDF da Expressif usa uma frequência teórica de 80 MHz, a frequência PWM máxima definida para ESP32 é de 40 MHz com uma resolução de ciclo de trabalho de 1 bit. Isto significa que um sinal PWM de 40 MHz pode ser gerado com um ciclo de trabalho de 50% ou 100%. A frequência PWM máxima que pode ser emitida com resolução de 8 bits é 312,5 KHz. A frequência PWM máxima que pode ser emitida com resolução de 10 bits é 78,125 KHz.

Para ESP32, MicroPython permite especificar frequência PWM de 1KHz a 40 MHz. A resolução do ciclo de trabalho pode ser de 1 bit a 16 bits. Para evitar erros na geração do PWM, primeiro determine a resolução do ciclo de trabalho desejada. Maior será a resolução do ciclo de trabalho, mais precisamente, os níveis de tensão de saída poderão ser controlados. Depois de definir a resolução do ciclo de trabalho, você pode calcular a frequência PWM mais alta possível usando a seguinte equação.
Max_PWM_freq = 80.000.000/2 ^ Bit de resolução do ciclo de trabalho

Por exemplo, se exigirmos uma resolução de ciclo de trabalho de 13 bits, a frequência PWM máxima será a seguinte.
Freq_PWM_máx = 80.000.000/2^13
= 9,765 KHz

Para ESP32, o objeto PWM pode ser instanciado usando o máquina.PWM construtor. O ciclo de trabalho pode ser definido usando PWM.duty , PWM.duty_u16 ou PWM.duty_ns métodos. A frequência PWM pode ser definida usando PWM.freq método. As configurações PWM podem ser alteradas ligando para PWM.init método. As alterações nas configurações do PWM acontecem sem interrupções da CPU. O objeto PWM pode ser desabilitado chamando PWM.deinit método.

Observe que algumas placas ESP32 possuem menos canais PWM. A tabela a seguir lista os canais PWM e suas especificações para diferentes placas ESP32.

Aplicações PWM
Os sinais PWM são usados ​​para diversas aplicações, como desbotamento de LEDs, escurecimento de luzes, controle da direção de um servo motor, ativação de campainhas, controle de velocidade de motores DC, geração de sinais de áudio de alto-falantes, codificação de mensagens para dispositivos de comunicação analógica e produção de tensões analógicas. A tabela a seguir lista algumas das frequências PWM recomendadas e resolução de ciclo de trabalho para muitas aplicações comuns.

LED desbotado no ESP8266 usando firmware MicroPython
O desbotamento das luzes LED é uma das aplicações típicas dos sinais PWM. O desvanecimento do LED é frequentemente usado para monitorar a saída PWM de um microcontrolador. Neste artigo, usaremos MicroPython para desbotar o LED no ESP8266.

Componentes necessários

  1. ESP8266x1
  2. LED de 5mm x1
  3. Resistência de 330Ω x1
  4. placa de ensaio x1
  5. Conectando fios/fios de jumper

Conexões de circuito
Conecte o ânodo do LED ao GPIO14 do ESP8266 e seu cátodo ao terra através de um resistor em série de 330 ohms. Desta forma, o LED é conectado ao ESP32/ESP8266 de forma que brilhe quando a fonte GPIO fornece corrente para o LED enquanto permanece desligado até que o GPIO esteja na lógica LOW.

Observe que o firmware MicroPython já deve estar carregado no ESP8266. Saiba mais sobre o upload do firmware MicroPython no ESP8266 e ESP32.

Circuito de desvanecimento de LED MicroPython PWM para ESP8266

Diagrama de circuito para desbotamento de LED com ESP8266 usando módulo MicroPython PWM

Script MicroPython
da importação da máquina Pin, PWM
do tempo importar sono
frequência = 1000
led = PWM (Pino (14), frequência)
enquanto Verdadeiro:
para duty_cycle no intervalo (0, 1024):
led.duty(duty_cycle)
dormir (0,005)

Como funciona
O LED é conectado ao ESP8266 de forma que brilhe quando a placa fornece corrente para ele. O ESP8266 fornece uma saída PWM para o LED. A frequência PWM é definida como 1 KHz, que é a frequência mais alta disponível para ESP8266. O ciclo de trabalho pode ser ajustado com uma resolução de 10 bits. Portanto, o ciclo de trabalho aumenta de 0 a 1023 em intervalos de cinco milissegundos. Isso proporciona um efeito de desvanecimento e desvanecimento durante cinco segundos.

O código
O código começa importando as classes Pin e PWM da máquina e as classes sleep dos módulos de tempo. A frequência é armazenada em uma variável de 1000. Um objeto PWM é instanciado chamando o método PWM . Em um loop while infinito, o ciclo de trabalho é alterado de 0 a 1023 e aplicado chamando o método PWM.duty para intervalos de 5 milissegundos.

Resultados

Conteúdo Relacionado

Voltar para o blog

Deixe um comentário

Os comentários precisam ser aprovados antes da publicação.