Curso Arduino – #5 – PWM, Servomecanismos e Bibliotecas
No artigo anterior foi discutido o conversor analógico-digital (ADC). Desta vez, vamos abordar um sinal muito específico: o PWM (pulse width modulation). Pode parecer complicado, mas depois de alguns exemplos práticos não restarão quaisquer dúvidas!
O que é o sinal PWM?
Suponha que liga um LED ao microcontrolador e programa-o para piscar em loop. O LED fica ligado por um segundo, no próximo permanece desligado e assim em diante:
void setup() { pinMode(3, OUTPUT); //Configuração do LED como saída } void loop() { digitalWrite(3, HIGH); //Liga o LED delay(1000); //Espera 1 segundo digitalWrite(3, LOW); //Desliga o LED delay(1000); //Espera 1 segundo }
Se desenhássemos um gráfico que desmonstrasse a mudança de tensão em função do tempo do pino 3, obteríamos a seguinte onda:
O valor marcado como x é o tempo em que o LED está ligado. De forma oposta, T é o período de tempo em que o LED está desligado. Por sua vez, o seu inverso, isto é, 1/T, indica a frequência. A relação entre o tempo que o LED está ligado e o tempo que o LED está desligado é 1:1. Por outras palavras, o LED está ativo durante 50% da operação do programa. Este aspeto é denominado duty cycle.
Para resumir as informações do sinal acima:
- Amplitude (valor máximo): 5V;
- Período (ciclo): 2 segundos;
- Frequência: 1/2 = 0,5 Hz;
- Duty cycle: 50%.
Agora outro exercício semelhante. No entanto, com um duty cycle diferente, ainda que mantendo o período. Como fazê-lo? Basta prolongar o tempo de operação do LED, reduzindo o tempo em que desligado. Por exemplo:
void setup() { pinMode(3, OUTPUT); //Configuração do LED como saída } void loop() { digitalWrite(3, HIGH); //Ligar o LED delay(1667); digitalWrite(3, LOW); //Desligar o LED delay(333); }
Desta vez, o LED fica ligado cerca de 5/6 do tempo. Então o duty cycle é cerca de 83%. Apresentando a situação num gráfico obtemos:
De forma oposta, se trocarmos os delays, o duty cycle do sinal fica cerca de 17%. Vejamos:
Dê uma vista de olhos nos exemplos acima. Qual dos parâmetros mudou em cada exemplo? A resposta é fácil: o duty cycle. A frequência permaneceu igual.
Agora imagine que os delays inseridos nos códigos acima eram muito mais pequenos, graças aos quais a frequência do sinal é muito maior… Parabéns! Acabou de entender o princípio do PWM. É um método de modular um sinal retangular através do ajuste da largura de pulso.
Para que é que o sinal PWM é usado?
Este sinal é usado com muita frequência. Com este, pode controlar o brilho de um LED, a posição de um servo e a velocidade à qual um motor funciona! Como terá oportunidade de ver, possui inúmeras aplicações em robótica, bem como noutros projetos DIY.
Exercício Prático de PWM – Controlo do brilho de um LED
Está na hora do primeiro exemplo prático de aplicação do PWM. Para já, vamos criar um programa muito simples, cujo objetivo será colocar regular o brilho de um LED.
Material necessário:
- 1x Arduino UNO e cabo USB;
- 1x Breadboard;
- 1x LED;
- 1x Resistência de 330Ω;
- 2x Cabos jumper.
Como já vimos no segundo artigo do curso, o Arduino está equipado com 6 canais PWM. Cada saída, na qual podemos obter o sinal PWM, foi marcada na placa com um til “~”.
Cada canal PWM disponível no Arduino UNO é de 8 bits. Isto significa que, o sinal que queremos receber na sua saída, pode ser definido por um número de 0 a 255, onde 255 significa 100% de duty cycle.
Para realizar o primeiro exercício, é necessário ligar o LED ao pino 3 da seguinte forma:
Agora vamos escrever o código. O objetivo é o LED acender lentamente.
#define pinoLED 3 int dutyCycle = 0; int mudanca = 5; void setup() { pinMode(pinoLED, OUTPUT);//Configuração do LED como saída } void loop() { analogWrite(pinoLED, dutyCycle); //Gerar um sinal com determinado duty cycle if (dutyCycle < 255) { //Se o duty cycle for menor do que 100% dutyCycle = dutyCycle + mudanca; //Aumenta o duty cycle } else { dutyCycle = 0; //Se o duty cycle for igual a 100%, volta ao início } delay(50); //Pequeno atraso para tornar o efeito visível }
Esperamos que tenha ficado claro. Podemos agora discutir a nova função inserida: analogWrite (pino, duty cycle). O seu objetivo é gerar o sinal PWM no pino selecionado com o duty cycle indicado.
O programa acima pretende aumentar periodicamente o duty cycle de zero para o momento em que o seu valor é imediatamente menor do que 255 (100%). Quando é alcançado o duty cycle máximo, o LED desliga e o processo é repetido.
Trabalho de Casa nº12
Simplifique o código acima, de forma a que não tenha de usar a função condicional if. Pense no efeito da variável dutyCycle no programa.
Trabalho de Casa nº13
Escreva um programa que, após aumentar o duty cycle até 255, reduza-o gradualmente até zero (em loop).
Servo Motor
Está na altura de usar o servo motor! O que vamos utilizar é o SG90, do tipo micro, um dos mais pequenos disponíveis no mercado. Contudo, o seu tamanho não afeta o modo de controlo. Depois de entender o princípio de operação, poderá aplicá-lo em servos maiores, mais potentes e mais rápidos.
Se ainda não adquiriu o seu servo motor, pode fazê-lo aqui.
O que é um servo?
Um servomecanismo é um motor, caixa de velocidades e controlador num só dispositivo. No entanto, estes motores não são projetados para executar rotações completas. Na maioria das vezes, os servos possuem um ângulo de rotação de 0-180º. É importante saber que eles conhecem a sua posição atual, por isso não precisa de se preocupar com erros de posição.
Os princípios mais importantes da utilização dos servos:
- Não se deve girar manualmente a posição do eixo, sem necessidade. Pode danificar as delicadas engrenagens de plástico;
- Não se deve alimentar o servo diretamente da fonte de alimentação usada no restante sistema. Cada motor recebe uma corrente relativamente alta, especialmente no início do movimento. Isso pode perturbar o funcionamento dos outros dispositivos e, em casos extremos, danificá-los.
Como é que o servo funciona?
Como é que o servomecanismo sabe para qual posição girar? Graças ao driver integrado. É ele que, com base no sinal PWM fornecido, controla o motor.
Um padrão aceitável é o envio de um sinal com um período de 20ms para o servo. O duty cycle é interpretado como a posição para a qual o servo deve ser movido. O duty cycle do sinal gerado deve encontrar-se entre 5 e 10%. Estes valores serão convertidos em duas posições extremas no servo (máximo esquerdo e máximo direito).
Fios de ligação do servo:
- Vermelho – alimentação;
- Amarelo ou laranja – controlo do sinal;
- Preto ou castanho – GND.
Dependendo do fabricante, as cores dos fios podem variar. No entanto, dois serão definitivamente preto/castanho e vermelho. O restante será o fio de sinal.
Alimentação do servo
Como foi referido anteriormente, não deve alimentar o servo diretamente da mesma fonte que alimenta o microcontrolador. Portanto, devido ao fato de o motor consumir uma grande corrente, deve ser utilizada uma fonte adequada para alimentação do sistema.
Infelizmente, a alimentação a partir da porta USB, como havíamos feito até agora, não é suficiente. Portanto, pela primeira vez, vamos alimentar a placa com uma bateria de 9V!
Exercício Prático – Servomecanismo
Vamos passar ao primeiro programa com o servo motor. Para isto, ligue o sistema de acordo com o diagrama de montagem abaixo.
Material necessário:
- 1x Arduino UNO e cabo USB;
- 1x Breadboard;
- 1x Servo Motor SG90;
- 1x Regulador de tensão LM7805;
- 1x Bateria de 9V;
- 1x Ligador para bateria de 9V;
- 7x Cabos jumper.
Em primeiro lugar, é necessário ligar a bateria. Em segundo, é preciso incluir um regulador de tensão LM7805. Pode comprar o seu aqui.
Agora o código que fará o servo mover-se gradualmente:
#include <Servo.h> //Biblioteca responsável pelo servo motor Servo servomecanismo; //Declaração do servo como servomecanismo int posicao = 0; //Posição atual do servo de 0-180 graus int mudanca = 6; //Qual deve ser a posição do servo? void setup() { servomecanismo.attach(9); //Servo ligado ao pino 9 } void loop() { if (posicao < 180) { //Se a posição for inferior a 180 graus servomecanismo.write(posicao); //Move-se } else { //Caso contrário, volta ao início posicao = 0; } posicao = posicao + mudanca; //Aumentar a posição atual do servo delay(200); //Atraso para melhor efeito }
Desta vez, adicionámos uma biblioteca que vai expandir as capacidades do programa com as nossas funções. O comando usado é:
#include Servo.h
Neste caso, adicionamos o arquivo Servo.h, que contém instruções adicionais do servo. Graças a este, não precisámos de ser nós a controlar o sinal PWM. É suficiente indicar as posições (ângulo) para as quais queremos que o servo gire.
Para controlar o servo, é necessário declará-lo:
Servo servomecanismo;
A função attach (pino) – para o objeto Servo – funciona de maneira semelhante ao pinMode. A partir desta instrução, será gerado, na saída indicada (neste caso 9), um sinal PWM.
Depois de iniciar o programa, o servo deve mover-se suavemente de uma posição extrema para a outra em loop. A instrução chave é:
servomecanismo.write(posicao);
A posição deverá ser um ângulo entre 0 e 180º.
Trabalho de Casa nº14
Com base no código anterior, escreva o seu próprio programa, em que o movimento para a nova posição seja realizado passado mais tempo (200ms, 250ms, etc.).
Trabalho de Casa nº15
Escreva um código que faça o servo girar para a posição enviada para o Arduino via UART. Os números enviados deverão encontrar-se entre 0 e 180, caso contrário será enviada uma mensagem apropriada.
Trabalho de Casa nº16
Ligue um potenciómetro ao sistema. Use o ADC para medir a tensão dada pelo potenciómetro. Quanto maior for, mais chegado à direita o servo deverá estar.
Sumário
Esperamos que este capítulo do curso tenha sido do seu interesse, e que tenha permitido entender o que é o sinal PWM e como pode usá-lo nos seus projetos.
No capítulo seguinte, vamos abordar alguns truques úteis relacionados à comunicação UART. Também vamos mostrar como é que pode usar o servo com um indicador analógico, e como usar o Arduino e o sistema L293D para controlar um motor DC!
___________
O que achou deste artigo? Deixe o seu comentário abaixo, e partilhe nas Redes Sociais que certamente será útil e interessante para os seus amigos!
Curso Arduino – #0 – Introdução
Curso Arduino – #1 – O Básico do Arduino e o Software de Programação
Curso Arduino – #2 – O Básico da Programação e as Portas I/O
Curso Arduino – #3 – UART e Variáveis
Curso Arduino – #4 – Conversor Analógico-Digital
Curso Arduino – #5 – PWM, Servomecanismos e Bibliotecas
Curso Arduino – #6 – UART (continuação) e Servos
Curso Arduino – #8 – Controlo de Motores DC
Curso Arduino – #9 – Sensor de Distância Ultrassónico HC-SR04 e Novas Funções
Curso Arduino – #10 – Gráficos, Números Aleatórios e Condições