Raspberry PI - PWM com Python

Introdução

 

Este artigo apresentará os conceitos básicos da Modulação por largura de Pulso, PWM (Pulse Width Modulation) sendo a sua sigla em inglês, e como utilizar e manipular os comandos GPIO da linguagem de programação Python no Raspberry Pi 3.

 

Ao final da leitura e aplicando os conceitos teóricos e práticos apresentados sobre o PWM na Raspberry, o leitor será capaz de realizar as seus próprios projetos e aplicações.

 

Este artigo é continuidade aos dois artigos sobre entrada e saída de dados no Raspberry publicado pelo Cleiton Bueno.

 

O que é PWM?

 

A Modulação por largura de Pulso ou Pulse Width Modulation, é uma maneira de se manipular uma forma de onda quadrada mantendo a frequência constante e  se variando intervalo de tempo em que se permanece em nível lógico alto durante o período de frequência.

 

Existem inúmeras aplicações como, controle de velocidade rotação ou torque em motores DC, controle de luminosidade, controle de atuadores e etc.

 

A razão entre o tempo em estado lógico alto pelo período da frequência é chamado de duty cycle. A equação 1, apresenta essa definição:

 

Figura 1 - Duty Cycle no PWM

 

Vamos analisar a situação  apresentado na figura 01 para melhor entendermos o conceito de PWM e o duty cycle. A frequência do sinal neste exemplo é 500 Hz e foram fornecidos 5 valores diferentes de duty cycle, 0%, 25%, 50%, 75% e 100%, lembrando que o valores podem variar entre  0% e 100%. Vamos realizar os cálculos utilizando a equação 01 e iremos encontrar o valor do tempo em nível lógico alto.

 

Antes de tudo, deve-se calcular o valor do período da frequência desejada que é dado pela equação 02.

Para um sinal com frequência de 500 Hz, temos um período de 2 ms como calculado abaixo:

Agora então vamos realizar o cálculo do tempo em nível lógico alto para as cinco situações.

Para duty cycle de 0%:

Pode-se ver que quando o duty cycle é de 0%, o tempo em nível lógico alto é de 0s e  comprovando o que é apresentado na Figura 01 no intervalo de tempo anterior a 0 s.

Para duty cycle de 25%:

 

Pode-se ver que quando o duty cycle é de 25%, o tempo em nível lógico alto é de 500 us e comprovando o que é apresentado na Figura 01 no intervalo de tempo entre 0 e 2 ms .

Para duty cycle de 50%:

Pode-se ver que quando o duty cycle é de 50%, o tempo em nível lógico alto é de 1 ms e comprovando o que é apresentado na Figura 01 no intervalo de tempo entre 2 e 4 ms.

Para duty cycle de 75%:

Pode-se ver que quando o duty cycle é de 75%, o tempo em nível lógico alto é de 1,5 ms e comprovando o que é apresentado na Figura 01 no intervalo de tempo entre 4 e 6 ms.

 

Para duty cycle de 100%:

 

Pode-se se ver que quando o duty cycle é de 100%, o tempo em nível lógico alto é de 2 ms, que é o mesmo tempo do período da freqüência, e comprovando o que é apresentado no intervalo de tempo entre 6 e 8 ms.

 

Comandos Python para PWM na Raspberry Pi

 

Os comandos Python utilizados para realizar a manipulação PWM da forma de onda quadrada fazem parte da biblioteca RPi.GPIO e devemos usar o comando import para poder utilizar esses comandos nos nossos códigos.

 

Há seguir serão apresentados as funções que nos ajudaram na manipulação PWM da forma de onda:

 

  • pwm =GPIO.PWM(canal, frequência):

Nesta função se cria um objeto chamado “pwm”, mas poderia ser dado qualquer outro nome a este objeto, como poderemos ver no exemplo 01.O argumento “canal” é o pino em que será utilizado como saída PWM e o argumento “frequência” define a frequência do sinal aplicada na saída do pino definido no argumento “canal”.

 

  • pwm.start(DCInicio):

Esta função inicializa o sinal PWM com um valor do duty cycle, deevendeo estar entre 0 a 100, respectivamente representando 0% a 100% .

 

  • pwm.ChangeDutyCycle(DC):

Esta função é utilizada durante a execução do código para variar o valor do duty cycle entre 0% e 100%. Nos exemplos apresentados mais abaixo, entenderemos melhor o seu uso.

 

Exemplos:

 

Para ilustrar tudo que foi apresentada até o momento, vamos apresentar dois códigos simples desenvolvidos que se utilizam dos conceitos e definições da PWM e como as funções da biblioteca RPi.GPIO do Python são aplicadas no decorrer do código. Vamos então a eles:

 

Exemplo 01

 

Neste exemplo é realizada a variação da luminosidade de dois leds, um vermelho e outro azul,  conectados na saídas dos terminais do Raspberry Pi 3. Vamos então analisar o código passo-a -passo para melhor entendimento do que está sendo realizando no código Python.

 

Circuito

 

Figura 02 - Circuito Exemplo 01

 

O circuito acima apresenta as conexões a serem realizadas em um protoboard para que o circuito definido no exemplo 02 funcione corretamente. Os dois resistores de 1 kΏ em das suas extremidades conectadas respectivamente ao pino 38 e 40 da Raspberry Pi 3. Nas duas extremidades cada uma está conectada ao anodo do led. Os catodos dos led estão conectados ao pino 6 de GND Raspberry Pi.

 

Código Python

 

#Define Libraries
import RPi.GPIO as gpio
import time

#Configuring don’t show warnings 
gpio.setwarnings(False)

#Configuring GPIO
pio.setmode(gpio.BOARD)
gpio.setup(38,gpio.OUT)
gpio.setup(40,gpio.OUT)

#Configure the pwm objects and initialize its value
pwmBlue = gpio.PWM(38,100)
pwmBlue.start(0)

pwmRed = gpio.PWM(40,100)
pwmRed.start(100)
 
#Create the dutycycle variables
dcBlue = 0
dcRed  = 100

#Loop infinite
while True:
   
    #increment gradually the luminosity
    pwmBlue.ChangeDutyCycle(dcBlue)
    time.sleep(0.05)
    dcBlue = dcBlue + 1
    if dcBlue == 100:
        dcBlue = 0

    #decrement gradually the luminosity
    pwmRed.ChangeDutyCycle(dcRed)
    time.sleep(0.05)
    dcRed = dcRed - 1
    if dcRed == 0:
        dcRed = 100
    
#End code
gpio.cleanup()
exit()

 

As linhas 2 e 3, importam para o código as bibliotecas que permitem o uso das funções manipulação das GPIOs e de tempo.

 

A linha 6, faz que não se mostre os warnings no shell do Python.

 

As linhas 9, 10 e 11 definem respectivamente que configuração dos pinos se dará pelo números destes e que os pinos 38 e 40 serão saídas.

 

As linhas 14 e 17 criam dois objetos chamados pwmBlue e pwmRed, define que eles irão trabalhar na frequência de 100 Hz e respectivamente definem osn seus canais sendo os pinos 38 e 40.

 

As linhas 15 e 18 definem os valores iniciais do duty cycle dos objetos pwmBlue como 0% e pwmRed como 100%.

 

As linhas 21 e 2 definem as variáveis dcBlue e dcRed recebendo respectivamente os valores 0% e 100%.

 

Alinha 25 defini o loop infinito.

 

Entre as linhas 28 e 32 são executados os comandos que realizam ativam e incrementam o duty cycle do pino 38, e quando se alcança o valor máximo este é retornado a 0%. Isso faz com que o led azul aumente a sua luminosidade gradualmente.

 

Entre as linhas 35 e 39 são executados os comandos que realizam ativam e decrementam o duty cycle do pino 40, e quando se alcança o valor mínimo este é retornado a 100%. Isso faz com que o led vermelho diminua a sua luminosidade gradualmente.

 

As linhas 43 e 44 finalizam o código.

 

Exemplo 02

 

Neste exemplo, o controle do duty cycle é realizado por duas chaves, uma para incrementar e outra decrementar, e este representado por led que tem a sua luminosidade alterada de acordo com o seu valor. Vamos então analisar o código passo-a -passo para melhor entendimento do que está sendo realizando no código Python.

 

Circuito

 

Figura 03 - Circuito Exemplo 02

 

O circuito acima apresenta as conexões a serem realizadas em um protoboard para que o circuito definido no exemplo 02 funcione corretamente. As duas chaves push-button tem um dos seus terminais conectados ao pino 1 que fornece a tensão de 3,3 V e o outro terminal de cada uma deve ser conectados respectivamente nos pinos 11 e 12. No pino 40 é conectado um dos terminais do resistor de 1 kΏ e no outro terminal deve ser conectado ao terminal do anodo do led. O terminal cátodo do led deve ser conectado ao terminal do pino 6 que é o GND da Raspberry.

 

Código Python

#Define Libraries
import RPi.GPIO as gpio
import time

#Configuring GPIO 
gpio.setwarnings(False)
gpio.setmode(gpio.BOARD)
gpio.setup(11,gpio.IN, pull_up_down = gpio.PUD_DOWN)
gpio.setup(12,gpio.IN, pull_up_down = gpio.PUD_DOWN)
gpio.setup(40,gpio.OUT)

#Configuring GPIO as PWM
pwm = gpio.PWM(40,100)

#Initializing PWM
pwm.start(50)
dc = 50
print("Duty Cycle:",dc)
pwm.ChangeDutyCycle(dc) 

#Defining the detection in rising edge
gpio.add_event_detect(11,gpio.RISING,bouncetime = 300)
gpio.add_event_detect(12,gpio.RISING,bouncetime = 300)

while True:
        
    # Increasing the duty cycle of the PWM waveform
    if gpio.event_detected(11):
        dc = dc + 10
        if dc == 110:
            dc = 0
        print("Duty Cycle:",dc)        
        pwm.ChangeDutyCycle(dc)
        
    # Decreasing the duty cycle of the PWM waveform     
    elif gpio.event_detected(12):
        dc = dc - 10
        if dc == -10:
            dc = 100
        print("Duty Cycle:",dc)        
        pwm.ChangeDutyCycle(dc)         
    
    time.sleep(0.1)

gpio.cleanup()
exit()

 

As linhas 2 e 3 importam para o código as bibliotecas que permitem o uso das funções manipulação das GPIOs e de tempo.

 

Entre as linhas 6 e 10 são definidos que os pinos 11 e 12 serão entradas e utilizam um resistor de pull-down interno e que o pino 40 é uma saída.

 

A linha 13 é definido o objeto “pwm” e também que o seu canal será o pino 40 e a frequência será de 100 Hz.

 

Na linha 16 define que duty cycle iniciará em 50%.

 

Entre as linhas 17 e 19, é criada uma variável chamada “dc” que recebe o valor 50 representando o valor de duty cycle de 50% e esse valor é mostrada na tela do shell do Python. E este valor é aplicado na pino 40 onde está conectado o led.

 

Entre as linhas 22 e 23 definem que os pinos 11 e 12 interpretem como nível lógico alto uma borda de subida e é aplicado um debounce de 300 ms.

 

A linha 25 implementa o loop infinito.

 

Entre as linhas 28 e 33 é interpretado se o evento da borda de subida no pino 11 aconteceu, sendo verdadeiro, a variável “dc” é incrementada em 10 unidades causando um aumento no duty cycle  de 10%, também é mostrado no shell essa alteração e consequentemente a luminosidade do led aumenta. Caso o valor do variável “dc” ultrapasse o valor 100, ela é recebe ao valor 0.

 

Entre as linhas 36 e 41 é interpretado se o evento da borda de subida no pino 12 aconteceu, sendo verdadeiro, a variável “dc” é decrementada em 10 unidades causando um diminuição no duty cycle  de 10%, também é mostrado no shell essa alteração e consequentemente a luminosidade do led aumenta. Caso o valor do variável “dc” seja menor o valor 0, ela é recebe ao valor 100.

 

A linha 43 causa um atraso de 100 ms segundo na execução do próxima iteração do loop infinito.

 

As linhas 45 e 46 finalizam o código.

 

Conclusão

 

Pode-se observar que a PWM é uma aplicação que é utilizada para inúmeras aplicações e que as funções contidas na biblioteca Python para o Raspberry Pi 3 são simples de serem manipuladas e aplicadas, o que pode ser observado pelos exemplos de códigos apresentados neste artigo.

 

Referências

 

Raspberry PI-GPIO - output com Python - https://www.embarcados.com.br/raspberry-pi-gpio-output-com-python/

Raspberry PI–GPIO input com Python -  https://www.embarcados.com.br/raspberry-pi-gpio-input-com-python/

PWM na Raspberry Pi com Python - https://www.embarcados.com.br/pwm-raspberry-pi-python/

Figura 01 - http://www.hho4free.com/pulse_width_modulator__pwm.html

 

 

Outros artigos da série

<< Raspberry PI – GPIO input com PythonRaspberry Pi - Display LCD com Python >>
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Roniere Rezende
Natural de Cachoeira de Minas, cidade localizada no extremo sul de Minas Gerais. Graduado em engenharia elétrica pela PUC MINAS campus Poços de Caldas e técnico de telecomunicações pela Escola Técnica de Eletrônica "Francisco Moreira da Costa" - ETE "FMC" em Santa Rita do Sapucaí-MG. Atualmente atua como Analista Programador na Nexcode System na cidade de São Caetano do Sul-SP. Possui conhecimentos em eletrônica analógica, digitais, e de potência, em sistemas de telecomunicações e radiofrequência, em sistemas embarcados e linguagem de programação como C / C ++, Python e Matlab. Pesquisa e estuda sobre microcontroladores 8 e 32 bits, Arduino, Raspberry, STM32 Nucleo, desenvolvimento de dispositivos eletrônicos, sistemas embarcados, software e hardware.

2
Deixe um comentário

avatar
 
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
EmersonVanessa Hanhela Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
Emerson
Visitante
Emerson

Boa tarde! Não consigo encontrar esta informação em outro lugar, por favor qual a quantidade de canais PWM que o Raspberry possui e quais são esses canais nos GPIOs? Desde já, obrigado!

Vanessa Hanhela
Visitante
Vanessa Hanhela

Que sucesso! Excelente artigo! Que venham outros! Recomendo a leitura ?