Você está na página 1de 9

Departamento de Engenharia Elétrica

Controle Digital de Processos

Experimento 3 (PARTE 1 DE 2) – Controle Digital de Velocidade de Rotação

Aluno Nº matrícula Data:

TEORIA ENVOLVIDA: Em muitos casos, controlar um sistema dinâmico envolve aplicar o seguinte passo-a-passo:
• Passo 1) Conhecer em detalhes a planta a ser controlada (suas partes físicas, sua entrada, sua saída, etc)
• Passo 2) Desenhar um esboço de como será o sistema de controle em malha fechada (planta+controlador)
• Passo 3) Identificar a planta (encontrar um modelo matemático que represente o seu comportamento)
• Passo 4) Projetar o controlador
• Passo 5) Simular computacionalmente o sistema em malha fechada
• Passo 6) Implementar na prática o controlador projetado
• Passo 7) Validar os resultados obtidos e, se necessário, refazer partes do projeto.

PASSO 1) CONHECENDO O SISTEMA

Nesse experimento, controlaremos a velocidade de rotação de um motor DC. Como motor DC, usaremos um Cooler
de laptop (ventoinha) alimentado com alimentação nominal de 5 Vcc/0.2 A. O Cooler é, essencialmente, um motor DC
com hélices conectadas ao seu eixo de rotação. Com esses valores nominais de tensão e corrente, é possível alimentar o
cooler diretamente com o próprio Arduino.

Para facilitar a aquisição e o controle da velocidade de rotação do cooler, usaremos um Cooler de 4 fios, conforme
ilustrado no diagrama abaixo (Se o seu cooler possui um fio verde, então provavelmente o esquema de cores é: Amarelo (+Vcc), Preto (GND), Verde (Velocidade), Azul
(PWM)).

Conforme ilustrado acima, os fios vermelho e preto são usados para alimentar o motor. Conecte esses dois fios aos pinos
correspondentes no Arduino, mantendo os fios azul e amarelo desconectados.

O Cooler começou a girar? (SIM/NÃO)

MEDINDO A VELOCIDADE DE ROTAÇÃO (RPM)

A velocidade de rotação do cooler pode ser medida usando o fio amarelo, que encontra-se conectado à saída de um
Sensor de Efeito Hall, presente no interior do cooler. Isso significa que usaremos o sensor de efeito Hall como
tacômetro (medidor de velocidade). Tipicamente, quando um motor dá 1 volta (rotação) completa, dois pulsos
retangulares são gerados no fio amarelo, conforme mostrado a seguir.

1
Departamento de Engenharia Elétrica
Controle Digital de Processos

(OBS: curva obtida por meio de osciloscópio)

Para detectarmos as bordas de subida (ou de descida) do sinal acima e com isso calcularmos a velocidade de rotação do
motor, ligaremos o fio amarelo do cooler à porta digital 2 do Arduino e habilitaremos uma interrupção para essa
porta. Como as bordas possuem um aspecto parecido, torna-se indiferente optar por uma interrupção com base na borda
de subida ou de descida. Selecionado-se, por exemplo, a borda de subida, então, toda vez que uma borda de subida
ocorrer, o microcontrolador passará a executar uma função associada a essa interrupção. Internamente ao Arduino, a
borda é detectada verificando-se o cruzamento pela tensão de 5/2=2,5 V.

Por exemplo, o trecho de código abaixo ativa a interrupção do pino 2 do Arduino. Toda vez que uma ocorre uma borda
de subida (“rising”) uma unidade é adicionada à variável contador.
#define pino_sensorhall 2
int contador = 0;
void setup() {
attachInterrupt(digitalPinToInterrupt(pino_sensorhall),soma_um_pulso,RISING); // habilita interrupção
do pino 2. Ocorrerá uma interrupção sempre que houver borda de subida. Quando ocorre uma interrupção, a
função 'soma_um_pulso' é chamada
}

void loop() {
}

void soma_um_pulso() {
contador = contador + 1;
}

Existem diversos métodos para se usar esse tipo de interrupção para medir a velocidade. Na sequência deste roteiro,
iremos estudar 2 métodos diferentes, sendo o Método 2 mais adequado para aplicações de controle de velocidade.

2
Departamento de Engenharia Elétrica
Controle Digital de Processos

MÉTODO 1 PARA MEDIR VELOCIDADE

Uma maneira bem simples de medirmos a velocidade de rotação do motor em RPM consiste em contarmos a quantidade
de pulsos gerados pelo Sensor de Efeito Hall durante 1 segundo, dividirmos essa quantidade por 2, já que são gerados 2
pulsos por volta, e multiplicarmos o resultado por 60, já que temos 60 segundos em 1 minuto. Ou seja,

𝑛ú𝑚𝑒𝑟𝑜 𝑑𝑒 𝑝𝑢𝑙𝑠𝑜𝑠 𝑒𝑚 1 𝑠𝑒𝑔𝑢𝑛𝑑𝑜


𝑅𝑃𝑀 = 60 ×
2

Tipicamente, o circuito interno de um Cooler a 4 fios é conforme abaixo:

• Note que a figura acima explica o motivo pelo qual uma volta completa do rotor gera dois pulsos no fio amarelo
(Velocidade). Isso acontece porquê existem 2 imãs acoplados ao rotor. Quando um deles passa pela entrada do
Sensor de Efeito Hall, um pulso é gerado. Ou seja, são gerados dois pulsos por rotação.
• Também note o seguinte: quando o transistor 𝑇𝐻𝑎𝑙𝑙 opera como chave fechada, o fio amarelo (Velocidade) é
conectado ao GND, portanto, sua tensão é próxima de zero. Por outro lado, quando o transistor 𝑇𝐻𝑎𝑙𝑙 opera
como chave aberta, o fio amarelo ficará “flutuando”, ou seja, sem uma tensão definida. Portanto, uma medição
adequada de velocidade por meio do fio amarelo exige que conectemos um resistor de pullup entre o fio
amarelo e a alimentação (5V) – ESSE RESISTOR NÃO APARECE NA FIGURA ACIMA. Assim, quando o
transistor 𝑇𝐻𝑎𝑙𝑙 opera como chave aberta, a tensão no fio amarelo irá para 5V, e deixará de flutuar.

Se você quiser, pode conectar um resistor externo de 10 kΩ entre os fios amarelo e vermelho. Entretanto, uma forma
mais prática de resolver esse problema consiste em ativar o próprio resistor interno de pullup que existe no Arduino
por meio da seguinte linha de código:

pinMode(pino_sensorhall, INPUT_PULLUP); // Habilita um resistor de pullup da porta


selecionada para a tensão de alimentação (no caso, 5V). Quando fazemos isso, não
precisamos inserir nenhum resistor externo.

OBS: a medição da velocidade provavelmente não funcionará caso não haja um resistor de pullup.

Com base nessas informações e usando o software SerialPlot, faça a medição da velocidade de rotação do motor para
os casos abaixo (mantenha o pino PWM do cooler desconectado):

Situação Velocidade medida usando SerialPlot (RPM)


Cooler alimentado normalmente com 5 V
Cooler com alimentação subnominal de 3.3 V
Cooler alimentado normalmente com 5 V mas com
objeto limitando sua rotação
3
Departamento de Engenharia Elétrica
Controle Digital de Processos

Exemplo de código para Arduino Uno:


// Nesse primeiro método, iremos medir a velocidade contando a quantidade de pulsos em 1 segundo.
// Para cada rotação, são gerados dois pulsos pelo sensor de efeito Hall.

#define pino_sensorhall 2
int contador = 0;
unsigned long start_time;
int rpm;

void setup() {
// Initializing serial communication
Serial.begin(2000000); // Velocidade da comunicação serial. USAR O MÁXIMO DO ARDUINO, QUE ESTÁ POR VOLTA DE 1.000.000 bits/seg
pinMode(pino_sensorhall, INPUT_PULLUP); // Habilita um resistor de pullup da porta selecionada para a tensão de alimentação (no caso, 5V). Quando fazemos
isso, não precisamos inserir nenhum resistor externo.
attachInterrupt(digitalPinToInterrupt(pino_sensorhall),soma_um_pulso,RISING); // habilita interrupção do pino 2. Ocorrerá uma interrupção sempre que
houver borda de subida. Quando ocorre uma interrupção, a função 'soma_um_pulso' é chamada
}

void loop() {
start_time = millis();
contador = 0;
while((millis() - start_time) < 1000){ // durante o intervalo de 1 segundo vamos ficar contando quantos pulsos tivemos.
}
rpm = contador * 60 / 2; // divide por dois pois temos dois pulsos por volta.
Serial.println(rpm);
}

void soma_um_pulso() {
contador = contador + 1;
}

O que o código acima implementa? Descreva detalhadamente o seu funcionamento, assim como cada linha presente no
código.
Comentários/Observações/Comparações/Gráficos/Deduções (utilize o verso se necessário):

MÉTODO 2 PARA MEDIR VELOCIDADE

No Método 1 que acabamos de estudar, a medição da velocidade era feita contando-se a quantidade de pulsos durante
o intervalo de 1 segundo. Entretanto, para aplicações onde deseja-se controlar a velocidade do motor, uma medida de
velocidade por segundo acaba sendo muito lento. Surge então uma segunda ideia para medirmos a velocidade:

“Ao invés de calcularmos a quantidade de pulsos durante 1 segundo, iremos calcular o período de tempo entre
dois pulsos e com isso calcular a velocidade”

Para exemplificarmos a ideia, considere novamente a figura que mostra os pulsos gerados no fio amarelo quando o
Cooler gira:

4
Departamento de Engenharia Elétrica
Controle Digital de Processos

Sabendo que dois pulsos são gerados durante cada rotação do motor, prove que a relação entre o período 𝑇 da onda
quadrada presente no fio amarelo e a velocidade de rotação do motor (em RPM, ou seja, rotações por minuto) é dada
por

60
𝑅𝑃𝑀 =
2𝑇

Conhecendo essa relação e levando em conta os marcadores de tempo 𝑡1 , 𝑡2 , 𝑡3 presentes na figura acima, preencha a
seguinte tabela:

Período 𝑇 (segundos) 60
𝑅𝑃𝑀 = (rotações por minuto)
2𝑇

𝑡2 − 𝑡1 = 0.006384 ms

𝑡3 − 𝑡2 = 0.006340 ms

Note que existe uma variação significativa no cálculo da velocidade dependendo de qual período é utilizado para se
fazer este cálculo. Isso ocorre pois os dois pulsos consecutivos gerados pelo motor durante uma volta completa
tipicamente possuem uma assimetria indesejada, ou seja, possuem períodos significativamente distintos (existe,
provavelmente, uma pequena assimetria geométrica relacionada ao posicionamento dos dois imãs no eixo do rotor). É
possível resolver este problema medindo-se sempre 2𝑇 ao invés de 1𝑇. Assim, estamos levando sempre em conta o
mesmo imã para calcularmos a rotação. Com isso, somos capazes de obter uma medida mais precisa da velocidade:

2𝑇 (segundos) 60
𝑅𝑃𝑀 = 2𝑇 (rotações por minuto)

𝑡3 − 𝑡1 = 0.006384 ms

Na prática, o intervalo 2𝑇 pode ser medido ignorando-se pulsos intermediários (gerados pelo outro imã). A figura abaixo
ilustra a diferença entre os métodos 1T e 2T. Note que o ruído de medição é bem menor ao usar-se o Método 2T.

5
Departamento de Engenharia Elétrica
Controle Digital de Processos

Com base nessas informações e usando o software SerialPlot, faça a medição da velocidade de rotação do seu motor
(usando o Método 2T) para os casos abaixo (mantenha o pino PWM do cooler desconectado):

Situação Velocidade medida usando SerialPlot (RPM)


Cooler alimentado normalmente com 5 V
Cooler com alimentação subnominal de 3.3 V
Cooler alimentado normalmente com 5 V mas com
objeto limitando sua rotação

Exemplo de código para Arduino Uno (note que o exemplo abaixo implementa um período de amostragem de
Ts=50000 us = 0.05 s):
// Nesse terceiro método, Iremos contar o intervalo de tempo sempre pulando um dos pulsos geradorados pelo sensor de efeito hall. Isso elimina possíveis
assimetrias existentes entre pulsos adjacentes (devido à assimetrias geométricas, por exemplo).
// Lembrando que, para cada rotação, são gerados dois pulsos pelo sensor de efeito Hall.

#define pino_sensorhall 2
long Ts = 50000; // Período de amostragem desejado em us
unsigned long tempo; // variável auxiliar de tempo
unsigned long t1; // variável auxiliar de tempo
long periodo;
double freq;
double RPM;
int contador = 0; // variável auxiliar de contagem de pulsos. Iremos contar o intervalo de tempo sempre pulando um dos pulsos geradorados pelo sensor de
efeito hall. Isso elimina possíveis assimetrias existentes entre pulsos adjacentes (devido à assimetrias geométricas, por exemplo).
// Quando contador == 0, ignoramos o pulso atual.
// Quando contador == 1, contabilizamos o período e resetamos o contador.

void setup(){
Serial.begin(2000000);
pinMode(pino_sensorhall, INPUT_PULLUP); // Habilita um resistor de pullup da porta selecionada para a tensão de alimentação (no caso, 5V). Quando
fazemos isso, não precisamos inserir nenhum resistor externo.
attachInterrupt(digitalPinToInterrupt(pino_sensorhall), calcula_periodo, FALLING); // habilita a interrupção no pino digital 2. Ocorrerá uma
interrupção sempre que houver borda de descida. Quando ocorre uma interrupção, a função 'calcula_periodo' é chamada

void loop() {
tempo = micros(); // adquire tempo atual

freq = 1000000.0/periodo; // calcula a frequência em segundos (lembrando que o período está em us)
RPM = freq*60; // a velocidade de rotação (em rotações por minuto) é dada pela quantidade de voltas por segundo (rotação por segundo) vezes 60.
Serial.println (RPM, 2);

while( tempo + Ts > micros() ) { } // Mantém o microcontrolador "sem fazer nada" até que o período de amostragem desejado seja atingido.
}

void calcula_periodo() {
if (contador==1){
periodo = micros()-t1; // calcula o tempo que demorou entre dois pulsos adjacentes no sensor de efeito hall (esse periodo está em us)
t1 = micros(); // Redefine nova referência de tempo para t1 para que essa referência seja usada da próxima vez que o período for recalculado.
contador = 0; // Reseta-se o contador para que o próximo pulso seja ignorado
}
else{
contador++; // faz com que a variável contador vá de 0 para 1, fazendo com que, no próximo pulso, o período seja contabilizado.
}
}

O que o código acima implementa? Descreva detalhadamente o seu funcionamento, assim como cada linha presente no
código.
Comentários/Observações/Comparações/Gráficos/Deduções (utilize o verso se necessário):

Com relação à medição da velocidade, cumpre ainda destacar o seguinte:


• A velocidade com que somos capazes de obter uma nova medida para o motor depende das interrupções que,
por sua vez, dependem da própria velocidade de rotação.
• Quando o motor gira mais rapidamente, temos mais interrupções e, portanto, mais atualizações acerca dessa
grandeza.
• Analogamente, quando o motor gira mais lentamente, temos menos interrupções e, portanto, menos atualizações
para a medida de velocidade.
6
Departamento de Engenharia Elétrica
Controle Digital de Processos

• Quando usamos o Método 2T, por exemplo, temos uma nova medida de velocidade a cada 2T segundos. Ou
60
seja, levando em conta a expressão 𝑅𝑃𝑀 = , isso significa que, se o motor estiver rodando com 4800 rpm,
2𝑇
temos uma nova medida a cada 0.0125 s. Por outro lado, se o motor estiver rodando com apenas 1500 rpm,
temos uma nova medida a cada 0.0400 s
• Isso deve ser levado em conta no momento em que selecionamos o nosso período de amostragem. Por exemplo,
se usamos um período de amostragem de 𝑇𝑠 = 0.05 s, então, mesmo que o motor esteja rodando com apenas
1500 rpm, teremos uma nova medida de velocidade ao longo de cada período de amostragem, já que 𝑇𝑠 =
60
0.05 > 0.04 s. A condição crítica de amostragem para esse 𝑇𝑠 ocorre para uma velocidade de 𝑇 = 1200 rpm.
𝑠
Para velocidades abaixo dessa, não teremos garantia de uma atualização da medida para cada novo período de
amostragem.
• Esse problema de amostragem é naturalmente resolvido se decidirmos operar o Cooler apenas com velocidades
mais elevadas (por exemplo, ≥ 2000 rpm).

USANDO O PINO “PWM” PARA CONTROLAR A VELOCIDADE

Agora que já sabemos medir a velocidade do Cooler adequadamente, estamos prontos para tentar controlar sua
velocidade usando o fio azul (PWM). Considere, novamente, o circuito interno do Cooler a 4 fios:

Note que podemos usar o pino PWM (fio azul) para chavearmos a fonte de alimentação de 5V. Isso significa que,
controlando a razão cíclica desse PWM, seremos capazes de controlar a tensão média que alimenta o motor e, por
conseguinte, a sua velocidade de rotação. Tipicamente, coolers a 4 fios exigem uma frequência de PWM alta para que
o controle seja efetivo (em torno de 𝑓𝑃𝑊𝑀 =25 kHz). Configure uma saída digital do seu microcontrolador para que ela
seja um PWM com frequência elevada, conecta-a ao fio azul do Cooler e faça as medições abaixo:

PWM (valor inteiro entre 0 Razão cíclica em % Velocidade medida usando


e 255 que define sua razão SerialPlot (RPM)
cíclica)
0
50
100
150
200
255

Olhando os resultados acima e definindo como 𝒚(𝒕) o sinal de velocidade de rotação e como 𝒖(𝒕) o valor inteiro que
define a razão cíclica do PWM, um incremento Δ𝑢 no valor da razão cíclica sempre produz um mesmo incremento Δ𝑦
na velocidade? Pensando nisso, este sistema é linear ou não?

7
Departamento de Engenharia Elétrica
Controle Digital de Processos

Comentários/Observações/Comparações/Gráficos/Deduções (utilize o verso se necessário):

Exemplo de código para Arduino Uno (note que você pode atualizar o valor da variável PWM enviando um
comando via porta serial):
#define pino_sensorhall 2
long Ts = 50000; // Período de amostragem desejado em us
unsigned long tempo; // variável auxiliar de tempo
unsigned long t1; // variável auxiliar de tempo
long periodo;
double freq;
double RPM;
int contador = 0; // variável auxiliar de contagem de pulsos. Iremos contar o intervalo de tempo sempre pulando um dos pulsos geradorados pelo sensor de efeito hall. Isso elimina
possíveis assimetrias existentes entre pulsos adjacentes (devido à assimetrias geométricas, por exemplo).
// Quando contador == 0, ignoramos o pulso atual.
// Quando contador == 1, contabilizamos o período e resetamos o contador.

int pino_PWM = 9;
float PWM = 255.0; // razão cíclica de 0 a 255
const int freqPWMdesejada = 25000; // Frequência desejada para o PWM em Hz. Lembrando que coolers em geral exigem uma frequência de PWM em torno de 25 kHz. É aceitável frequências entre
21 kHz e 28 kHz.

void setup(){
Serial.begin(2000000);
Serial.setTimeout(50);//tempo de espera dos dados de leitura na serial (em ms)

pinMode(pino_sensorhall, INPUT_PULLUP); // Habilita um resistor de pullup da porta selecionada para a tensão de alimentação (no caso, 5V). Quando fazemos isso, não precisamos inserir
nenhum resistor externo.
attachInterrupt(digitalPinToInterrupt(pino_sensorhall), calcula_periodo, FALLING); // habilita a interrupção no pino digital 2. Ocorrerá uma interrupção sempre que houver borda de
descida. Quando ocorre uma interrupção, a função 'calcula_periodo' é chamada

pinMode(pino_PWM, OUTPUT);
// Alterando a frequência do PWM das portas 9 e 10 (ver link http://domoticx.com/arduino-pwm-frequency-and-timers/)
TCCR1B = TCCR1B & B11111000 | B00000001; // set timer 1 divisor to 1 for PWM frequency of 31372.55 Hz
// Não há garantia de que esse valor de frequência resultará numa boa operação do Cooler. Caso seja um valor de frequência muito elevado, uma frequência mais baixa deve ser
utilizada.
}

void loop() {
tempo = micros(); // adquire tempo atual

if (Serial.available() > 0) { // if there's any serial character available, read it


serialRead(); //verifica se há dados na serial e efetua a leitura para atualização do PWM
}

freq = 1000000.0/periodo; // calcula a frequência em segundos (lembrando que o período está em us)
RPM = freq*60; // a velocidade de rotação (em rotações por minuto) é dada pela quantidade de voltas por segundo (rotação por segundo) vezes 60. Entretanto, temos que lembrar que o
nosso sensor gera 2 pulsos por rotação. Por isso multiplicamos por 30 e não por 60.

PWM = constrain(PWM, 0, 255); // mantém PWM sempre dentro do intervalo [50 255]. Observar que alguns coolers apresentam um valor mínimo de PWM para que este funcione. Para o
Cooler em questão, observou-se ser necessário PWM>=50
analogWrite(pino_PWM, round(PWM)); // implementa valor atualizado do PWM (arredondado)

Serial.print(RPM, 2);

Serial.print(" ");

Serial.print(PWM);

while ( tempo + Ts > micros() ) { } // Mantém o microcontrolador "sem fazer nada" até que o período de amostragem desejado seja atingido.
Serial.println(" ");
}

void calcula_periodo() {
if (contador==1){
periodo = micros()-t1; // calcula o tempo que demorou entre dois pulsos adjacentes no sensor de efeito hall (esse periodo está em us)
t1 = micros(); // Redefine nova referência de tempo para t1 para que essa referência seja usada da próxima vez que o período for recalculado.
contador = 0; // Reseta-se o contador para que o próximo pulso seja ignorado
}
else{
contador++; // faz com que a variável contador vá de 0 para 1, fazendo com que, no próximo pulso, o período seja contabilizado.
}
}

void serialRead(){
char received = Serial.read();

switch (received) {

case 'p':
case 'P':
PWM = Serial.parseFloat();

if (Serial.read() == '\n' || Serial.read() == '\r') {}

break;

default :
if (Serial.read() == '\n' || Serial.read() == '\r') {};
}
}

O que o código acima implementa? Descreva detalhadamente o seu funcionamento, assim como cada linha presente no
código.

8
Departamento de Engenharia Elétrica
Controle Digital de Processos

Comentários/Observações/Comparações/Gráficos/Deduções (utilize o verso se necessário):

Você é capaz de definir um valor de PWM que leve o motor a seguir uma velocidade fixa de, por exemplo, 3000 rpm?
Supondo que você mantenha fixo o valor de PWM que faz isso acontecer, o que ocorre se um objeto passar a limitar a
rotação do Cooler? Haverá um ajuste automático do PWM para que a rotação volte a ser 3000 rpm? Qual é a relação
disso com o conceito de controle em malha aberta? Use o quadro abaixo para responder a essas questões.

Comentários/Observações/Comparações/Gráficos/Deduções (utilize o verso se necessário):

Você também pode gostar