Postagem em destaque

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte I

Este post é o primeiro de uma série de seis que escrevi tratando de controle de potência e PID (controle proporcional, integral e derivativo...

domingo, 26 de maio de 2013

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte VI

Nesse último artigo da nossa série sobre PID, vamos estudar um caso prático de uso dessa técnica em um sistema de controle. Os outros posts podem ser lidos em:

Controle de Pot. em CA - PID, Arduino e TRIAC - Parte I
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte II
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte III
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte IV
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte V

Como é comum nessa plataforma tão versátil que é o Arduino, existe uma biblioteca pronta para quem quer implementar controles baseados em PID. Essa biblioteca é a PID Library. Ela nos livra do trabalho de calcular a função PID, todo o cálculo já está implementado "dentro" do objeto PID definido. O cálculo não é complicado, quem tiver lido e entendido esses posts que fiz e quiser dar uma espiadinha no arquivo PID_v1.cpp vai entender perfeitamente a implementação. O jeito de usar é simples, tb. De posse dos valores de KpKi e Kd, vc tem que começar um fonte do Arduino assim:

#include "PID_v1.h"
 
// Carga (pino onde será aplicado o output)
#define loadR 3    
 
// Constantes do PID
#define kp 50
#define ki 10
#define kd  0
 
// Variáveis do PID: a nomenclatura é a mesma descrita no post III
double SetPoint, PresentValue, ManipulatedValue;
 
// O último parâmetro indica se o controle é inversa ou 
// diretamente proporcional, ou seja, se a uma alteração do PV
// deve corresponder uma alteração de mesmo sinal (DIRECT) ou 
// de sinal trocado (REVERSE).
PID pid(&PresentValue, &ManipulatedValue, &SetPoint, kp, ki, kd, DIRECT);
 
volatile int power = 100;  
 
long t;
 
void setup()
{
  Serial.begin(9600);
  pinMode(loadR, OUTPUT);
  attachInterrupt(0, zero_crosss_int, RISING); 
// Os valores 10 e 240 foram definidos empiricamente usando-se
// o osciloscópio para ver onde o controle da onda é estável.
  pid.SetOutputLimits(10, 240);
  pid.SetMode(AUTOMATIC); 
  SetPoint=60;
  t=millis();
}
 
void zero_crosss_int()  
{
// Cálculo do ângulo de disparo: 60Hz-> 8.33ms (1/2 ciclo)
// (8333us - 8.33us) / 256 = 32 (aprox).
// Ou seja, cada 1 unidade em power corresponde a 32 microssegundos
// na onda de meio ciclo.
  int powertime = (32*(256-power));      
// Mantém o circuito desligado por powertime microssegundos 
  delayMicroseconds(powertime);   
// Envia sinal ao TRIAC para que ele passe a conduzir 
  digitalWrite(loadR, HIGH);  
// Espera alguns microssegundos para que o TRIAC perceba o pulso
  delayMicroseconds(8.33);      
// Desliga o pulso
  digitalWrite(loadR, LOW);   
}
 
 
// Função que lê o PV. É uma função que lê a saída  
// de um LM35 cinco vezes e acumula, depois tirando a média das
// 5 leituras e calculando a temperatura em °C.
int GetTemp(int sensor)
{
  float temp = 0;
  for(int i=0; i< 5;i++)
  {
    temp += analogRead(sensor);
    delay(20);
  }
  temp = (temp * 0.48875855)/5;
  return (int)temp;
}
 
void loop()
{
  float temp = GetTemp(A0);
  PresentValue=temp;// Calcula o valor manipulado   
  pid.Compute();
// Valor de power, que vai ser usado em
// zero_crosss_int() para atuar no processo.
  power = ManipulatedValue;
// Exibe os valores usados de 1 em 1s.
  if ((millis()-t) > 1000)
  {
    Serial.print(millis()/1000);
    Serial.print(",");
    Serial.print(PresentValue);
    Serial.print(",");
    Serial.println(ManipulatedValue);
    t=millis();
  }
  delay(300);
}
Esse exemplo é bem simples, e mostra como, usando-se a biblioteca pid_v1.h, fica fácil a gente implementar esse tipo de controle nos nossos projetos, ou seja, o pulo do gato está em entender o que se quer do PID e escolher as constantes certas para obter o resultado desejado.

Um outro exemplo, combinando o controle por TRIAC e o PID, segue abaixo. Esse circuito "junta tudo": combina os primeiros posts de controle de potência com os post de PID, num circuito sofisticado e prático para controle em geral, indo de aplicações de controle de processo propriamente dito até robótica, por exemplo, um simples robozinho segue-faixa pode ser muito beneficiado pelo uso desse tipo de algoritmo.

Para terminar, resolvi escrever sobre esse assunto porque não achei na net bons textos práticos em português sobre ele. Aliás, nem em inglês eu vi algo que fosse simples mas ao mesmo tempo descrevesse com rigor os conceitos envolvidos, por isso resolvi dedicar um tempo a isso.

Espero que essa série posts, que tomou mais de um mês para ser feita, seja útil a vcs. Por favor, escrevam sobre o que acharam, para que eu tenha o feedback de como me saí nessa empreitada. Abracadabraço!

#include "PID_v1.h"

// Carga (pino onde será aplicado o output). Esse pino deve ser
// ligado ao MOC. No primeiro circuito do post III dessa série
// o MOC está ligado ao pino 4.
#define loadR 4    

// Constantes do PID
#define kp 50
#define ki 10
#define kd  0

// Variáveis do PID: a nomenclatura é a mesma descrita no post III
double SetPoint, PresentValue, ManipulatedValue;

// O último parâmetro indica se o controle é inversa ou 
// diretamente proporcional, ou seja, se a uma alteração do PV
// deve corresponder uma alteração de mesmo sinal (DIRECT) ou 
// de sinal trocado (REVERSE).
PID pid(&PresentValue, &ManipulatedValue, &SetPoint, kp, ki, kd, DIRECT);

volatile int power = 100;  

long t;

void setup()
{
  Serial.begin(9600);
  pinMode(loadR, OUTPUT);
attachInterrupt(0, zero_crosss_int, RISING); // Os valores 10 e 240 foram definidos empiricamente usando-se // o osciloscópio para ver onde o controle da onda é estável. pid.SetOutputLimits(10, 240); pid.SetMode(AUTOMATIC); SetPoint=60; t=millis(); } void zero_crosss_int() { // Cálculo do ângulo de disparo: 60Hz-> 8.33ms (1/2 ciclo) // (8333us - 8.33us) / 256 = 32 (aprox). // Ou seja, cada 1 unidade em power corresponde a 32 microssegundos // na onda de meio ciclo. int powertime = (32*(256-power)); // Mantém o circuito desligado por powertime microssegundos delayMicroseconds(powertime); // Envia sinal ao TRIAC para que ele passe a conduzir digitalWrite(loadR, HIGH); // Espera alguns microssegundos para que o TRIAC perceba o pulso delayMicroseconds(8.33); // Desliga o pulso digitalWrite(loadR, LOW); } // Função que lê o PV. É uma função que lê a saída // de um LM35 cinco vezes e acumula, depois tirando a média das // 5 leituras e calculando a temperatura em °C. int GetTemp(int sensor) { float temp = 0; for(int i=0; i< 5;i++) { temp += analogRead(sensor); delay(20); } temp = (temp * 0.48875855)/5; return (int)temp; } void loop() { float temp = GetTemp(A0); PresentValue=temp;// Calcula o valor manipulado pid.Compute(); // Valor de power, que vai ser usado em // zero_crosss_int() para atuar no processo. power = ManipulatedValue; // Exibe os valores usados de 1 em 1s. if ((millis()-t) > 1000) { Serial.print(millis()/1000); Serial.print(","); Serial.print(PresentValue); Serial.print(","); Serial.println(ManipulatedValue); t=millis(); } delay(300); }

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte V


No último post escrevi uma introdução sobre PID (controle Proporcional, Integral e Derivativo), onde descrevi a teoria envolvida e o "P", ou seja, o controle Proporcional.

Os posts que compõem essa série podem ser clicados abaixo:

Controle de Pot. em CA - PID, Arduino e TRIAC - Parte I
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte II
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte III
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte IV

Neste post, vamos falar dos controles Integral e Derivativo.

O controle Derivativo procura fazer com que o nosso sistema atue mais rápido ou mais devagar segundo a taxa de resposta do PV. Ou seja, a resposta do sistema será inversamente proporcional à taxa de variação (derivada, aí o nome) do PV. Quanto mais devagar o PV estiver variando, maior será a correção calculada.

Por fim, o controle Integral procura levar em conta quanto tempo estivemos afastados do set point. Ele é importante para tentar evitar que o sistema fique oscilando em torno do set point, oscilação que é causada pelas componentes Integral e Derivativa.

Resumindo:

Controle Proporcional: calcula o MV levando em conta a distância entre o set point e o valor da variável PV em um determinado instante.

Controle Integral: calcula o MV levando em conta o tempo em que o sistema fica distante do set point (SP). 

Controle Derivativo: calcula o MV levando em conta a taxa de variação (velocidade com que varia, ou derivada) do PV.

Definindo parâmetros

A chave do controle PID é a gente definir qual é a proporção relativa de cada componente em nosso sistema de controle. Essa proporção, ou peso, é dada pelas contantes KpKi e Kd.

Agora, como escolher o valor de cada constante no nosso controle? Bom, cada caso é um caso. Eu acho (e é minha opinião mesmo) que a gente tem que considerar vários fatores, já que o que importa é a curva que a gente quer de controle. Vc então tem que responder perguntas como: 

- É necessário que o controle responda o mais rápido possível a uma perturbação? 

- Ou isso não é tão importante, mas sim o valor presente deve evitar ao máximo ultrapassar o set point? Quando VP ultrapassa SP tempos uma sobrecarga, que pode ser importante ou não.

- O set point muda ou é constante? 

- Se ele se altera às vezes, qual a faixa de valores em que ele varia? Ele varia bruscamente ou suavemente?

Todas essas questões vão influenciar a escolha dos parâmetros, que no fim é o que determina a forma da curva.

Como são três parâmetros que atuam de forma "coordenada", quer dizer, o valor de um parâmetro influencia no comportamento das outras componentes, o ajuste pode ser difícil. Pode-se adotar três caminhos:

- Ajuste manual (no popular, tentativa e erro): vai-se testando diferentes valores e verificando o resultado até que o sistema funcione do jeito que queremos.

Ao usar essa técnica, devemos levar em conta a seguinte tabela. Ela mostra o reflexo que um aumento num determinado parâmetro provoca no sistema: 









Ou seja, vamos "mexendo" nos parâmetros considerando o seu efeito conforme a tabela acima.

- Cálculo dos parâmetros: nesse caso, a gente usa alguma regra para calcular os valores dos parâmetros de maneira a obter o resultado desejado.

Vou descrever um dos métodos para se calcular KpKi e Kd, o método de Ziegler-Nichols. Consta que é o mais utilizado.

Esse método é heurístico, ou seja, uma vez que vc o use, não há garantia matemática que a solução é a melhor possível (nesse caso, o método seria chamado determinístico).  Contudo, é bastante eficaz na maioria dos casos.

O método Z-N consiste em:

- Primeiro, zera-se Ki e Kd. Em seguida, varia, começando de zero, o valor de Kp até obter o valor de Ku,  definido como o menor valor de Kp em que o sistema fica oscilando em torno do SP com uma velocidade constante. No gráfico abaixo vc vê o comportamento do circuito com Kp=KuKi=0, Kd=0.










O período Tu da onda e o valor de Ku serão usados para calcular os outros parâmetros, conforme a tabela abaixo:









Se vc usar o Z-N para calcular seus parâmetros, tenha em mente que:

Os valores de Kp  Ki e Kd calculados com o Z-N tendem a levar o comportamento do sistema para um ganho agressivo (o sistema se aproxima rapidamente do SP) e com isso, a tendência a sobrecarga. Se a sobrecarga for muito problemática, esse não é o método adequado para estimar os parâmetros, mas mesmo assim pode servir como ponto de partida.

Mistura das técnicas acima: primeiro a gente calcula os parâmetros usando Z-N, mede o efeito. Em seguida, vamos tentando um ajuste fino "brincando" com as constantes para chegar ao resultado desejado.

Agora já temos todas as ferramentas para implementar um controle PID como se deve. No próximo e último post da série, vamos ver uma implementação prática do PID com o Arduino, baseada no circuito de controle que discutimos na parte III do nosso circuito.


segunda-feira, 20 de maio de 2013

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte IV

Em três posts anteriores nesse blog, eu discuti os circuitos necessários para se controlar uma carga resistiva monofásica em CA. Vc pode acessá-los aqui:

Controle de Pot. em CA - PID, Arduino e TRIAC - Parte I
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte II
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte III

Agora sim, vamos entrar no assunto principal dessa série de posts: o Controle Proporcional , Integral Derivativo, PID. A ideia é explicar a teoria da coisa e dar pelo menos um exemplo de como usar o PID na prática. O texto abaixo é quase uma tradução de parte do texto sobre PID da Wikipedia em inglês, então sugiro que aqueles que conseguem ler bem na língua de Sir Paul McCartney que leiam o texto por lá.

O controle PID é um mecanismo genérico de controle do tipo "loop feedback", ou seja, é um sistema que leva em conta a resposta do processo durante o ajuste para modificar o seu comportamento. É muito usado em sistemas de controle industriais. O PID calcula um erro, que é a diferença entre o valor corrente da variável a ser controlada no tempo t e o set point. Ele tenta então minimizar o erro ajustando o input do processo de controle.

O algoritmo envolve o cálculo de três parâmetros, o que faz com que o PID também seja chamado de controle de três termos: os termos proporcional, integral e derivativo, o que dá a sigla PID.  Heuristicamente, esses valores podem ser interpretados em termos de tempo: P depende do erro presente, I da acumulação de erros passados e D é uma tentativa de predição dos erros futuros, baseado na taxa atual de mudança.
O peso de cada termo deve ser ajustado para cada processo.

Quando não se conhece as especificidades de um processo, o PID é considerado o melhor algoritmo de controle. Ajustando-se os três parâmetros do PID fazemos com que ele consiga atender às demandas específicas de cada processo a ser controlado. A reposta do controle pode ser descrita em termos da responsividade do controle a um erro, do tanto que o controle ultrapassa o set point e do grau de oscilação do sistema. É importante observar que o PID por si só não garante o controle ótimo do sistema nem a sua estabilidade. Cada caso é um caso.

Algumas aplicações podem necessitar do uso de apenas uma ou duas ações para propiciar o sistema de controle apropriado. Isso é obtido zerando-se os parâmetros que devem ser desativados. Um controle PID pode então ser chamado de de controle PI, PD, P ou I. Controles PI são muito comuns, desde que a ação derivativa é muito sensível a ruídos na medida. Já a ausência do termo derivativo pode impedir o sistema de atingir o set point devido à ação do controle.

Introdução - Controle por laço (loop control)

Quando tomamos banho, principalmente num dia frio, tomamos o cuidado de ajustar a temperatura da água, nem tão fria que nos seja desconfortável, nem tão quente que nos queime a pele. Esse ajuste é feito com a gente atuando na quantidade de água que passa pela resistência do chuveiro. Quanto menos água passa pelo chuveiro mais quente ela fica. Se o chuveiro não for elétrico (o que, assim como a jabuticaba, é uma coisa exclusiva do Brasil), ou seja, se houver um aquecedor central, a gente atua nas torneiras de água fria e quente, de maneira a obtermos a temperatura de nosso agrado. Esse é um exemplo de um loop control, que tem esse nome porque a malha forma um laço fechado entre o sensor de temperatura (nossa mão), o processamento (nosso cérebro) e os atuadores, nossa(s) mão(s) que aciona(m) a(s) torneira(s).

A temperatura é a variável de processo (VP) o valor desejado é o set point (SP). As voltas que damos na torneira representam a variável manipulada (MV). A diferença de temperatura medida e o SP é o erro (e) e quantifica se a água está muito quente ou fria e o quanto está longe do SP.

Depois de medir a temperatura num determinado instante (PV) e calcular o erro, o controlador decide atuar na torneira (MV) e quanto atuar. Se a temperatura está mais quente e perto do que desejamos, abrimos pouco a torneira, se está muito quente abrimos mais. Esse é um exemplo simples de controle proporcional.  No caso da temperatura demorar a baixar, podemos abrir mais e mais a torneira. Esse é um exemplo de controle derivativo, ou seja, a ação de controle depende da taxa (velocidade) de variação do PV.

Abrir muito a torneira quando o erro é pequeno é equivalente ter um alto ganho no controlador, e irá levar a VP a ultrapassar o SP, o que em inglês é chamado de overshoot. Se o controle faz atuações muito grandes repetidamente, o VP irá oscilar em torno do SP em uma forma sinusóide constante, crescente ou decadente. Se a oscilação cresce com o tempo então o sistema é dito instável, se ela decai o sistema é dito estável. Se a curva se mantém numa amplitude constante em torno da média o sistema está marginalmente estável.

Com o objetivo de convergir para o set point, o controle pode tentar antecipar futuras oscilações. Para compensar esse efeito, o controlador pode decidir modificar os seus ajustes. Esse é o controle derivativo.

Se um controle parte de um estado estável com zero erro (PV = SP), poderá ocorrer mudanças no controle em resposta a mudanças em outras variáveis, medidas ou não, que impactem o processo, perturbando o PV. Variáveis que impactam o processo e não são o PV são chamadas de distúrbios. Geralmente os circuitos de controle tem como objetivo rejeitar os distúrbios. No nosso exemplo, uma mudança na temperatura da água que está entrando no chveiro consiste em um distúrbio.

Em tese, um circuito controlador pode ser usado para controlar qualquer processo em que haja um PV que possa ser medido, um SP e uma variável manipulável (MV) que possa alterar o PV. Esse tipo de controle é usado na indústria para regular temperatura, pressão, vazão, composição química, velocidade, ou seja, praticamente qualquer variável passível de medição.

A teoria do PID

O esquema do controle PID é constituído da soma de manipuladores da variável manipulada (MV). Os termos proporcional, integral e derivativo são somados para calcular a saída do controle PID. Se chamarmos u(t) de saída do controle, a forma final da equação é:


Pode-se observar que é uma equação de três termos adicionados para calcular u, que é a correção a ser aplicada (MV) num determinado instante t.

Os termos são, pela ordem, da esquerda para a direita na equação:

O termo proporcional, Kpe(t), produz um valor de saída que é proporcional ao erro em um dado momento. Ou seja, quanto mais distante PV estiver de SP, maior será esse termo. A resposta proporcional pode ser ajustada pela constante Kp, chamada de constante de ganho proporcional.

Um alto ganho proporcional resulta numa grande mudança na saída para uma dada mudança no erro. Se o ganho proporcional é muito grande, o sistema pode ficar instável. Se o ganho proporcional é muito pequeno, a ação do controle pode ser tão pequena que o SP não chegará a ser atingido. Num dos testes que andei fazendo, só com o controle proporcional (Kp = 7, Ki = 0 e Kd = 0), para um set point igual a 60 °C, obtive o seguinte resultado:


No gráfico acima, e em outros que vão aparecer aqui, a curva em azul é o PV (temperatura), a curva em marrom é o output que controla a quantidade de energia que o TRIAC libera para a resistência. O eixo x é número da medida, que tem a ver com o tempo. Para indicar o tempo em segundos precisamente a gente tem que usar um RTC (relógio de tempo real), colocar no circuito e ir lendo o tempo que ele fornece. Vou ver se adoto essa prática no futuro, até porque eu acho que tenho um RTC por aqui.

O eixo y da esquerda é o output, o da direita é a temperatura em °C, medida junto à resistência.

No gráfico dá prá ver como o controle proporcional atua, começando com um output máximo (240) pelo fato do VP estar longe do SP. É medida que o erro e vai caindo, o controle vai diminuindo a potência buscando fazer com que a temperatura se estabilize no SP, Acontece que eu usei um Kp tão pequeno que a temperatura se estabilizou em 49 °C, e não no SP, que era 60 °C.

Alterando o Kp para 50 e mantendo os outros dois coeficientes iguais a zero, o comportamento muda bastante:


Agora o sistema atinge o SP e fica oscilando em torno deste. O primeiro pico acima do SP é mais forte, depois ele se estabiliza em um valor menor, sugerindo uma condição de sistema marginalmente estável.

No próximo post, vamos falar dos controles integral e derivativo e mostrar códigos em Arduino usando esses conceitos.

sábado, 18 de maio de 2013

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte III

IMPORTANTE: como o segundo circuito abaixo taca gerando muita confusão, troquei-o para um desenho mais simples.

No primeiro post a respeito desse assunto, escrevi sobre a teoria por trás do controle de potência em corrente alternada. No segundo post, mostrei o circuito e o programa responsáveis pela indicação de zero na onda senóide de CA.

Agora vamos ver o circuito para controle de uma carga 110 ou 220V. Para fazer isso, usaremos um circuito baseado em TRIAC. O software que roda no Arduino conta com um mecanismo de interrupção semelhante ao descrito no outro post, que monitora a passagem por zero no ciclo. Dentro da rotina que é executada a cada zero, o sistema liga o TRIAC em instantes distintos, de acordo com tensão que deseja-se enviar à carga. O TRIAC se desliga sozinho na próxima passagem pelo zero.



Acima, fritzing dos dois circuitos, o de zero (esquerda) e o de controle (direita).

Lista de componentes:
CI MOC3020
TRIAC BTA12-600
CI H11AA1
Resistores de 180, 2,4k, 10k, 33k.
Capacitor de 0,01 uF, 400 V, de poliéster ou outro material. Não pode ser eletrolítico.

ATUALIZAÇÃO: esse CI, o H11AA1, funciona como um "sensor de zero de onda completa". Ele tem dois diodos, ligados em contraparalelo, que conseguem captar a passagem da corrente por zero nos dois sentidos. Aqui no datasheet vc pode ver como funciona.

Acontece que esse CI não é muito fácil de se achar. Como alternativa, segue abaixo outro circuito que usa como opto o 4N25 (pode ser usado tb o 4N35). Esse CI é mais fácil de ser encontrado (datasheet). Por outro lado, ele é de meia-onda, ou seja, para que vc monitore as duas passagens por zero de um ciclo é necessário o uso de uma ponte retificadora antes do 4N. Abaixo, esquema do circuito com o 4N35, incluindo a ponte. A ponte tb é bem fácil de ser encontrada, e é bem barata.


Nesse circuito, a saída que informa a passagem por zero é a Zerocrossing signal output, que deve ser conectada ao pino 2 digital do Arduino. Já a entrada do sinal de disparo do dimmer, dimmer signal in, deve ser conectada ao pino 4, para ficar compatível com o código abaixo. O circuito funcionará também para 110 V.

Esse LED que tem na entrada de sinal do dimmer pode ser excluído (nesse caso, claro, vc deve conectar a entrada direto no positivo da entrada do MOC). Se vc usá-lo e a sua lâmpada e/ou ele ficarem piscando, tire fora.

Na figura:

T1 - TRIAC TIC206 ou BR136 (ou algum outro equivalente)
BR1 - ponte retificadora 400V, ou então vc pode montar uma ponte com 4 1N4004 ou equivalentes. Dê um Google e vc acha como fazer uma, caso não ache a ponte pronta. Aqui tem algo sobre.


Agora, o código:

#define loadR 4    

volatile int power = 100;  

void zero_crosss_int()  
{
  // Cálculo do ângulo de disparo: 60Hz-> 8.33ms (1/2 ciclo)
  // (8333us - 8.33us) / 256 = 32 (aprox)
  int powertime = (32*(256-power));      
  // Mantém o circuito desligado por powertime microssegundos 
  delayMicroseconds(powertime);   
  // Envia sinal ao TRIAC para que ele passe a conduzir 
  digitalWrite(loadR, HIGH);  
  // Espera alguns microssegundos para que o TRIAC perceba o pulso
  delayMicroseconds(8.33);      
  // Desliga o pulso
  digitalWrite(loadR, LOW);   
}

void setup()
{
  Serial.begin(9600);
  pinMode(loadR, OUTPUT);
  // Inicializa interrupção. O número zero indica a porta 2 do Arduino,
  // zero_crosss_int é a função que será chamada toda vez que o pino 2
  // "subir" (RISING) de valor de 0 para 1.  
  attachInterrupt(0, zero_crosss_int, RISING);  
}

void loop()
{
  // Seta a potência para diferentes níveis. Se o sistema estiver conectado a uma lâmpada,
  // esta vai variar de brilho.
  power=10;
  delay(10000);
  power=60;
  delay(10000);
  power=120;
  delay(10000);
  power=180;
  delay(10000);
  power=240;
  delay(10000);
}




Abaixo, vídeo do circuito funcionando, onde vcs podem ver a variação da onda no osciloscópio, com a correspondente variação no brilho da lâmpada.




sexta-feira, 17 de maio de 2013

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte II

O primeiro post que escrevi sobre esse assunto descreve a primeira parte da teoria por trás do controle de potência com Arduino. Lá está escrito que o Arduino deve controlar a forma da senóide de tensão de corrente alternada para que possa ter um controle preciso da energia enviada ao circuito a ser controlado.

Agora vamos ver o circuito que faz esse controle. O circuito é dividido em duas partes:

1) um "sensor de zero", que informa ao Arduino onde a senóide começa (ou seja, a passagem da curva senóide pelo ponto zero).

2) um circuito de controle que permita, comandado pelo Arduino, que apenas uma determinada parte da onda senóide seja enviada ao circuito a ser controlado (que pode ser uma resistência, lâmpada, motor etc).

Abaixo, a parte do circuito responsável pelo item 1:


Como vcs podem ver, é um circuito muito simples, composto de um optoacoplador e dois resistores.

O optoacoplador por sua vez é composto de um fotodiodo e de um fototransistor, como na figura abaixo:


Ele funciona da seguinte forma: toda vez que a tensão entre os pólos do fotodiodo (em vermelho) chega a um determinado valor positivo, que varia com o modelo de opto, o diodo passa a conduzir eletricidade e consequentemente a emitir luz. Assim que ele passa a emitir luz o fototransistor passa a conduzir entre o coletor e o emissor. Assim, a gente fica tendo um circuito onde a presença de uma tensão do lado esquerdo é detectada pelo lado direito apenas pela passagem da luz, e não de corrente elétrica, o que significa que se houver uma sobretensão do lado esquerdo essa não vai se propagar para o lado direito, preservando o circuito mais sensível.

Assim, o optoacoplador serve para acoplar oticamente (ou desacoplar eletricamente) dois circuitos. Nesse caso, o circuito de baixa tensão (lado direito) está conectado ao lado esquerdo pelo opto sem que haja passagem de corrente de um lado pro outro, conforme descrito acima.

No nosso caso, usaremos o optoacoplador para informar ao Arduino a passagem por zero da senóide. A ideia é que, a toda vez que a senóide da rede elétrica passar pelo ponto zero, seja gerado um pulso elétrico no pino 2 do Arduino. Foi usado o opto 4N25.

Para isso, ligamos o sinal de alta tensão ao fotodiodo, através de um resistor de 33 kohms Se for um circuito 110V, ligamos o fase e neutro aos terminais, se for 220V ligamos as duas fases. Em seguida, montamos o circuito de baixa conforme o esquema acima, usando um resistor de 1 a 10kohms e conectando o pino 5 do opto ao pino 2 digital do Arduino e ao resistor. A outra ponta do resistor vai no +5V do Arduino.

Para identificar os pinos do opto: se vc usar algum 4N (25, 35 etc), ele tem 6 "pernas", conforme a figura abaixo:


O pino 1 pode ser identificado por um marcador (ponto preto acima) próximo a ele.

O código é bem simples, mas usa um recurso que aparece pouco em circuitos com Arduino, apesar da grande utilidade. Aprender a usar as interrupções simplifica muito os nossos códigos.

Basicamente o recurso consiste em fazer com que uma rotina seja chamada quando um pino do Arduino muda de estado (de 0 para 5V ou vice-versa). Nesse caso, a rotina é executada a cada mudança de estado.  Abaixo, o fonte devidamente comentado.
// Programa que conta os "meio-ciclos" da onda senoidal fornecida pela
//concessionária de energia elétrica.
 
// Variável que armazena os pulsos. Como será chamada dentro da rotina
// ContaPulsos(), que é uma rotina de interrupção,
// tem que ter o comando volatile.
volatile unsigned int pulsos = 0;
 
// Rotina que é chamada a cada meio ciclo, incrementando a variável pulsos.</pre>
void ContaPulso()
{
   pulsos++;
}
 
void setup()
{
   Serial.begin(9600);
// Essa instrução faz com que, a cada vez que o pino 2 passa muda de 0 para 5V
// (RISING), a rotina ContaPulso() é chamada. O número 0 define o pino 2,
// o número 1 define o pino 3. 
   attachInterrupt(0, ContaPulso, RISING);
}
 
void loop()
{
   volatile unsigned long t=millis();
// Espera um segundo...
   while((millis()-t) <= 1000)
   {
   }
// Durante a espera, a interrupção ocorre a cada vez que o pino 2 muda de
    
// zero para 5V. Como isso acontece a cada meio ciclo, após um segundo</pre>
// a variável pulsos vai conter o valor 120, que será impresso repetidas</pre>
// vezes. 
   Serial.println(pulsos);
// Zera a variável para contar os pulsos do próximo ciclo.
   pulsos=0;
}

Quando executamos esse programa, o sistema conta as passagens por zero a cada segundo, que são 120, duas por ciclo. Assim, a saída mostrada no Serial Monitor é algo como:

120
120
120
...

No próximo post, o circuito de controle de potência, com o respectivo código fonte.

segunda-feira, 13 de maio de 2013

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte I

Este post é o primeiro de uma série de seis que escrevi tratando de controle de potência e PID (controle proporcional, integral e derivativo) com o Arduino.

Os posts são os seguintes:

Controle de Pot. em CA - PID, Arduino e TRIAC - Parte I
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte II
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte III
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte IV
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte V
Controle de Pot. em CA - PID, Arduino e TRIAC - Parte VI

Quem estiver interessado em controle de potência por ângulo de fase pode ler só a parte correspondente (posts I, II e III). Quem quiser aprender sobre PID deve ler a série toda, para poder entender os exemplos da parte de PID.

Procurei descrever de forma simples ambos os processos, mas usando a terminologia correta que se usa em Engenharia de Controle e Automação. Acho esses tópicos dos mais importantes em mecatrônica, e na net não tem muita coisa em português. Mesmo em inglês não tem material prático e que ao mesmo tempo explique a teoria por trás desses tópicos. Boralá?

Um grupo de alunos da FATESF me procurou para ajudá-los com um trabalho muito interessante na área de controle. Como o processo envolvia controle de temperatura de uma resistência ligada em 220V, resolvi estudar a ideia de como controlar potência com o Arduino.

Para se controlar corrente alternada, temos duas alternativas:

- A primeira seria colocar um relé ou algo parecido que ligasse e desligasse a energia na resistência comando pelo Arduino. Esse tipo de controle, bem simples, deveria funcionar para controle de temperatura.  É o tipo de controle da geladeira: o motor (compressor) é ligado sempre que a temperatura sobre acima de um determinado valor e desliga quando a temperatura cai abaixo de outro valor.
Como no caso do projeto a ideia é controlar uma resistência (que foi adaptada de um chuveiro, inclusive), esse controle tipo relé daria pro gasto, eu acho. Mas como é um TCC, foi indicado pelo professor que se utilizasse uma forma de controle mais sofisticada: o chamado Controle Proporcional-Integral-Diferencial, ou PID para os mais chegados.

- O PID é basicamente o que a gente faz com o chuveiro da casa da gente quando está fazendo frio, o que aliás é o caso por esses dias aqui em São José dos Campos: se a água tá fria a gente fecha um pouco a torneira e ela esquenta mais, se fica quente demais a gente abre a torneira, tentando manter a temperatura num valor confortável (o "set point", na linguagem técnica).  Ou seja, nesse caso, em vez de ficar desligando e ligando a resistência do chuveiro a gente fica tentando ajustar o fluxo de água de maneira que seja atingido o equilíbrio próximo ao set-point. Normalmente a gente consegue, ou seja, conseguimos achar um ponto de equilíbrio entre a quantidade de água que entra no chuveiro e a temperatura da água na saída. Aí o banho rola sossegado.
Eventualmente a gente fica o banho todo abrindo e fechando a torneira, o "relógio cai" (disjuntor desarma, em engenheirês) e a gente passa aperto etc. Isso pode acontecer com esse tipo de controle quando ele não está bem ajustado ou as condições para o controle são muito adversar (por exemplo, o dia está muito frio).

Para implementar isso precisamos de um mecanismo de controle que nos permita variar a quantidade de energia enviada à resistência, de maneira a variar a taxa de aquecimento dela, ou seja, a rapidez com que ela vai esquentar (e a temperatura que irá atingir) precisam ser devidamente controlados.

Ocorre que o fato da resistência ser ligara à rede de distribuição de energia (220V em SJC), traz as seguintes implicações.

1) IMPORTANTE: A TENSÃO DE  220V MATA! Se vc resolver, a partir das informações que leu aqui montar um circuito igual ou semelhante, preste muita atenção ao que for fazer, e peça ajuda a profissionais mais experientes caso não se sinta confortável com o desafio. Se ocorrer algum acidente vc pode se machucar seriamente, e certamente vai danificar algum equipamento que já estiver ligado ao circuito (incluindo o seu computador).
O circuito que eu vou sugerir é seguro, tem opto-acopladores para isolar a parte de potência (onde rolam os 220V) da parte de controle, onde estarão conectados o Arduino e consequentemente o seu PC, ou seja, fazendo com o devido cuidado não deverá haver surpresas.

2) Além da tensão ser alta, ela é CA (corrente alternada). Isso complica um bocado o mecanismo de controle. Par entender como vai funcionar a bagaça, precisamos de um pouco de teoria.



No gráfico acima, temos a relação entre o tempo e a tensão em corrente alternada. Dá prá ver que a tensão fica variando, num mesmo fio, entre +220V e -220V, passando por 0V no meio do caminho. Isso significa, grosso modo, que a tensão se alterna entre "indo e voltando" pelo fio. O caminho percorrido de 0V até o próximo 0V corresponde a meio ciclo, ou seja, duas passagens pelo eixo X compõem um ciclo.

No rede elétrica brasileira esses ciclos acontecem 60 vezes por segundo. Por isso se diz que a frequência da  corrente alternada no Brasil é de 60 ciclos/segundo, ou 60 Hertz (Hz).

O que tem isso a ver com o nosso projeto? É que, para controlar efetivamente a energia enviada à resistência (ou qualquer outra carga, uma lâmpada, por exemplo), temos que cortar, proporcionalmente ao controle que queremos fazer, um "pedaço" da onda. Veja nas fotos abaixo. Elas foram tiradas da tela de um osciloscópio, que é um equipamento que permite que a gente examine a forma de onda de pontos de um circuito elétrico.


Essa é a onda completa, ou seja, quase como vem na tomada de energia das nossas casas. Ela tem uma pequena flutuação perto do zero (que não ocorre na energia da concessionária, só dentro desse tipo de circuito), depois eu explico porque.


Aqui vc vê a onda onde apenas em mais ou menos metade de cada meio ciclo tem energia, ou seja. a tensão cai em direção ao zero e permanece aí por um quarto de ciclo, em seguida dando um salto para -220V e seguindo em direção a zero. O mesmo acontece com o meio ciclo positivo.



 Aqui a forma de onda onde a quantidade de energia enviada ao resistor é bem baixa, ou seja, a tensão fica em zero quase todo tempo, dando apenas um pequeno pico ao final de cada meio ciclo.

Bom, e como é que se faz esse controle?

Primeiro a gente tem que fazer um circuito que faça com que o Arduino seja informado a cada ciclo, para que um segundo circuito comandado pelo Arduino faça o controle da forma da onda.

No próximo post a gente discute essa parte do circuito.

domingo, 12 de maio de 2013

Projeto Decolar: últimas duas semanas

Seguindo com a turminha do projeto Decolar, tivemos dois encontros nos dois últimos sábados. No primeiro, a galera montou o seu primeiro robô, usando o Lego MindStorms. Deu prá ver como a ferramenta é poderosa: eu apresentei um roteiro em inglês de montagem de um carrinho a ser controlado por um botão de acionamento (liga/desliga os motores). Eles montaram com alguma orientação, afinal de contas o manual não era lá essas coisas e ainda por cima não corresponde exatamente à mesma versão do Lego MS que a gente tem.
Acho que eles conseguiram interagir bem, porque era um carrinho só a ser montado e eles eram oito. Além disso, o Lego se mostrou uma ferramenta e tanto. Eles partiram logo para aperfeiçoar o brinquedo construído, adicionando novas funcionalidades. Para isso, alteraram também os programas para que obtivessem os resultados almejados. Eu propus também alguns desafios, por exemplo que o carinho se movimentasse em curva. Ou seja, objetivo plenamente atendido.




O primeiro robô a gente nunca esquece:




Aí, no último sábado, resolvi mudar um pouco o rumo da coisa. Eu quero ver se consigo abrir mais frentes com a meninada, para fazer com que a coisa fique mais interessante. Assim, levei duas impressoras jato de tinta, uma delas multifuncional, e ferramentas para que a turma pudesse desmontar. A ideia mostrar a eles os componentes que podem ser aproveitados e como retirá-los sem estragar, e assim foi feito. Levei ferramentas minhas e do Hacker Clube, e o Alex Porto, um dos mentores do HC também ajudou com a atividade.






A turma conseguiu tirar todos os motores das impressoras, bem como alguns encoders, cabos, parafusos etc. Na realidade se aproveita bem pouco desse tipo de equipamento, e a produção de sucata é grande, ou seja, fica-se com o ônus de providenciar o descarte adequado. Por outro lado, a meninada se diverte bastante, e pode-se se ensinar como fazer esses desmontes de maneira correta. Eles também puderam testar os motores, chaves de fim de curso, LEDs e baterias de celulares (foram desmontados alguns tb)  e também motores de vibra-call. Guardei a sucata aproveitável para montarmos algo mais tarde.