Controlando um motor DC com driver TB6612FNG e RaspberryPi
Desde que foi lançado há alguns anos, o “computador do tamanho de um cartão de crédito” Raspberry Pi, tem conquistado a imaginação e criatividade de designers, hobbystas, engenheiros, estudantes, etc.
Com um generoso poder de processamento, memória, facilidade para conexão com dispositivos externos (sensores, motores e outros circuitos, só para mencionar alguns) a placa RaspberryPi pode ser usada em uma infinidade de projetos para estudos e novas tecnologias.
Entre as aplicações mais comuns estão a automação e robótica. Aproveitando esse contexto, a seguir veremos como controlar motores DC usando a Raspberry Pi com um circuito driver e a técnica PWM.
Para acompanhar esse post você precisa de alguns conhecimentos mínimos:
- Eletrônica básica;
- RaspberryPi: configurações, acesso ssh, instalação de pacotes;
- Python;
Antes de passarmos para o circuito e software usados, vamos ver alguns pontos importantes sobre o controle do motor em dois aspectos: método de controle e hardware.
PWM – Pulse width modulation (modulação por largura de pulso)
Para o controle do motor vamos modular a aplicação de tensão sobre o mesmo.
Simplicando ao extremo, a modulação PWM permite controlar a tensão média sobre uma carga aumentando ou diminuindo a largura de um ciclo ativo. Para isso aplicamos sobre a carga uma tensão com valor e frequência constantes. Ao modificarmos o período da aplicação da tensão (largura do pulso) modificamos o valor médio da tensão sobre a carga. O efeito, no caso do motor, é uma aceleração ou desaceleração do giro do eixo do motor.
O driver TB6612FNG
Trata-se de um circuito integrado com duas pontes H internas usando transistores MOSFET. O TB6612FNG pode controlar dois motores DC (motores pequenos usados em pequenas caixas de redução, brinquedos e outros aparelhos eletrônicos) independentemente.
A principal vantagem e indicação para o uso desses circuitos é a conexão protegida entre o(s) motor(es) e o microcontrolador/RPi. Visto que motor(es) consome(m) muita corrente há o risco de danos nas portas de I/O do microcontrolador, no nosso caso a GPIO da RPi.
Você pode encontrar mais detalhes aqui: https://www.pololu.com/product/713
O circuito
No circuito vamos usar as seguintes portas (GPIO) da RaspberryPi para a conectarmos ao driver:
- GPIO 16 -> STBY
- GPIO 19 -> PWM
- GPIO 21 -> AIN_1
- GPIO 22 -> AIN_2
Do driver, por sua vez, faremos a conexão com o motor DC. Na figura 2 podemos ver a disposição dos terminais do driver. Encontramos dois canais PWM: cada um pode controlar um motor DC, independentemente. O canal 1 pode ser identificado pelo número “1” nas entradas (AIN1, AIN2) e nas saídas (AO1, AO2). O mesmo acontece para o canal 2.
Note a presença de um terminal “VMOT”. Nele vamos aplicar a tensão que o motor precisa para funcionar. O driver aceita tensões de até 12V.
Variando a largura do pulso em canais diferentes podemos acelerar 2 motores diferentes o que pode ser útil em aplicações mecânicas e/ou robóticas, como fazer uma plataforma girar em torno do próprio eixo.
Escrevendo o software
Para o controle do motor o script Python precisa acessar a biblioteca GPIO da Rpi. Essa biblioteca concede acesso ao hardware do dispositivo permitindo que seu programa interaja com os terminais de I/O, e, por conseguinte, com o hardware conectado neles. Assim você poderá ler informações provenientes de sensores ou enviar comandos para o hardware.
Para instalar o lib de acesso a GPIO, digite os seguintes comandos no terminal da RPi:
sudo apt-get update sudo apt-get install rpi.gpio
Depois disso podemos usar um editor de texto comum (nano, leafpad, vi, vim) para editar o código:
nano pwm_motor.py
Nosso programa começa com alguns imports.
#coding: utf-8 import time import RPi.GPIO as GPIO # API de acesso ao hardware GPIO import sys import traceback (...)
Depois, definimos os terminais de I/O nos quais vamos conectar o driver.
# Niveis de tensao HIGH = 1 LOW = 0 # Terminais STBY = 16 PWM_PIN = 19 DIRECOES = { 'AIN_1': 21, 'AIN_2': 22 } (...)
Nas duas primeiras linhas do código acima definimos constantes para os níveis de tensão usados no programa/circuito.
A própria GPIO já possui variáveis para esse fim: HIGH e LOW. Mas, para fins didáticos usaremos a definição acima. Isso vai permitir que o restante de código abaixo seja mais compreensível.
Em seguida especificamos os terminais que usaremos para enviar os sinais de STBY (Standby) e o sinal PWM; respectivamente 16 e 19. Esses terminais serão usados para aplicarmos o sinal de freio (break) e sinal de modulação PWM.
Finalmente, usamos um dicionário para definirmos as direções (esquerda/direita) de giro do motor: DIRECOES.
Controles do driver
Para funcionar corretamente há especificações de níveis de tensão que devem ser aplicados nos terminais do driver TB6612FNG.
Na Figura 4 encontramos uma tabela que especifica como operar o driver.
O que o nosso script precisa fazer é enviar os sinais corretos para o driver de acordo com o que desejamos fazer com o motor; por exemplo, giro para a esquerda ou direita, acelerar (PWM) e parar.
Assim, defiremos um conjunto de funções que serão responsáveis para cada uma das operações.
# "Liga" o dispositivo def turn_on(): print ">>> STBY on [LIGANDO...]" GPIO.output(STBY,HIGH) # "Desliga" o dipositivo def turn_off(): print ">>> STBY off [DESLIGANDO...]" GPIO.output(STBY,LOW) # Habilita o giro do motor no sentido anti-horário: direita def ccw(): GPIO.output(DIRECOES['AIN_2'],HIGH) GPIO.output(DIRECOES['AIN_1'],LOW) # Habilita o giro do motor no sentido horário: esquerda def cw(): GPIO.output(DIRECOES['AIN_1'],HIGH) GPIO.output(DIRECOES['AIN_2'],LOW) # "Freio" def short_break(): GPIO.output(DIRECOES['AIN_1'],HIGH) GPIO.output(DIRECOES['AIN_2'],HIGH)
Em geral o que as funções acima fazem é aplicar cada linha da tabela da figura 4 na GPIO.
Por fim, o nosso programa, que será dotado de um loop infinito, vai precisar apenas chamar cada função para operar o motor.
O clico básico consiste em:
- Liga o motor (turn_on);
- Gira sentido anti-horário/horário (ccw/cw);
- Para o motor (shor_break);
- Desliga (turn_off);
- Tempo
- Retorna ao passo 1
Uma observação: o loop principal não é obrigado a implementar todas as chamadas de funções acima. O loop vai ser algo semelhante a:
turn_on() # funcao que "liga" o motor while count < 100: ccw() # eixo do motor para a esquerda PWM.ChangeDutyCycle(count) # envia o sinal PWM (varia a largura do pulso PWM, (des)acelera o motor) time.sleep(0.1) count += 1 print '>>> Ciclo: {ciclo}'.format(ciclo=count) turn_off() # funcao que "desliga" o motor
Repare que na linha,
while count < 100: (...)
configuramos o loop para ser executado 100 vezes. Se desejarmos um loop permanente (o que inspira cuidados visto que podemos “travar” o programa) podemos fazer:
while 1: (...)
Outro detalhe importante no código acima, é a linha:
PWM.ChangeDutyCycle(count) # envia o sinal PWM (varia a largura do pulso PWM, (des)acelera o motor)
Esse trecho de código apresenta o comando que altera a largura do ciclo ativo do sinal PWM. Fazendo isso, o programa altera o valor médio da tensão sobre o motor (carga) aumentando a velocidade de giro do eixo.
Antes do script invocar as funções de controle/operação do motor precisamos configurar os canais da GPIO como canais de saída. O trecho de código a seguir executa essa função:
def setup(): GPIO.setmode(GPIO.BOARD) # configura o modo de operação da GPIO # setup ports GPIO.setup(STBY,GPIO.OUT) GPIO.setup(PWM_PIN,GPIO.OUT) GPIO.setup(DIRECOES['AIN_1'],GPIO.OUT) GPIO.setup(DIRECOES['AIN_2'],GPIO.OUT)
Abaixo o código completo em Python 2.7
#coding: utf-8 import time import RPi.GPIO as GPIO import sys import traceback # Niveis de tensao HIGH = 1 LOW = 0 # Terminais STBY = 16 PWM_PIN = 19 PWM = object DIRECOES = { 'AIN_1': 21, 'AIN_2': 22 } # Configuramos as portas def setup(): GPIO.setmode(GPIO.BOARD) # setup ports GPIO.setup(STBY,GPIO.OUT) GPIO.setup(PWM_PIN,GPIO.OUT) GPIO.setup(DIRECOES['AIN_1'],GPIO.OUT) GPIO.setup(DIRECOES['AIN_2'],GPIO.OUT) def turn_on(): print ">>> STBY on [LIGANDO...]" GPIO.output(STBY,HIGH) def turn_off(): print ">>> STBY off [DESLIGANDO...]" GPIO.output(STBY,LOW) def ccw(): GPIO.output(DIRECOES['AIN_2'],HIGH) GPIO.output(DIRECOES['AIN_1'],LOW) def cw(): GPIO.output(DIRECOES['AIN_1'],HIGH) GPIO.output(DIRECOES['AIN_2'],LOW) def short_break(): GPIO.output(DIRECOES['AIN_1'],HIGH) GPIO.output(DIRECOES['AIN_2'],HIGH) def main(): setup() count = 0 turn_on() PWM = GPIO.PWM(PWM_PIN,100) PWM.start(50) while count < 100: ccw() PWM.ChangeDutyCycle(count) time.sleep(0.1) count += 1 print '>>> Ciclo: {ciclo}'.format(ciclo=count) turn_off() try: main() except: traceback.print_exc(file=sys.stdout) finally: GPIO.cleanup() print 'Close everthing. END'
Funcionamento
Depois de revisarmos as conexões no protoboard, conectarmos a Rpi, e acessar o terminal, podemos rodar o script:
sudo python pwm_motor.py
Abaixo um breve vídeo com o resultado:
Referências
Sobre o driver TB6612FNG – https://www.pololu.com/product/713/pictures
Artigo muito bem escrito e detalhado sobre PWM: https://www.embarcados.com.br/pwm-raspberry-pi-python/
Detalhes importantes, manuais e mais um monte coisas sobre RaspberryPi: https://www.raspberrypi.org/
Deixe um comentário