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, 27 de novembro de 2016

Conceitos em automação: threshold (limiar) e calibração

Sabadão estivemos mais uma vez no parque Santos Dumont para o nosso Automação no Parque.

Um projeto interessante que apareceu foi um "míssil" (na verdade uma maquete) a ser controlado por uma fonte de calor. O sensor infravermelho acabou sendo substituído por um LDR, porque o aluno apanhou do funcionamento dos primeiros. Isso, claro, não muda o conceito.

O protótipo está muito bem feito, como vcs podem ver na imagem abaixo.

Do lado esquerdo é a "ogiva", onde estão localizado os quatro sensores LDR, um pra cima, outro pra baixo, e um pra cada lado.

Em seguida vem uma plaquinha especializada que o aluno construiu para lidar com os infravermelhos. Como ele não tá usando mais esse sensor (eu sugeri que ele volte a usar), usamos um Arduino Uno em nossos testes.

Seguindo o corpo do "míssil" vcs podem ver em seguida o servo que controla as aletas de direcionamento esquerda/direita (se clicarem na figura ela dá um zoom e fica mais fácil de ver), depois vem o mecanismo de engrenagem dos eixos vertical e horizontal, e por fim vem o servo que controla o eixo da inclinação horizontal.

O aluno já trouxe um "pograminha" pronto, que não funcionava. A ideia é que eu achasse o motivo e ajudasse-o a consertar.

O aluno em questão faz parte de um programa de especialização em automação e controle aqui de SJC.

Ao analisar o programa do cabra, constatei que ele não funcionava porque ele não tinha atentado para dois conceitos básicos de automação industrial: threshold e calibração. Sem entrar na discussão sobre o porque disso, muitas vezes os alunos me procuram no Parque por esse tipo de demanda, quer dizer, está faltando um pouco de atenção talvez com o currículos desses cursos por aqui.

Como no Automação no Parque a gente mata a cobra e mostra o pau, quer dizer, ajuda a resolver os pepinos, abacaxis e outros vegetais de duplo sentido e ainda ensina a mágica, resolvemos a questão juntos e o camarada entendeu direitinho os dois conceitos, que passo a explicar aqui. Observe que minha intenção não é esgotar o assunto, mas dar uma visão geral e ao mesmo tempo prática para que os leitores possam entender e usar esses conceitos essenciais na ciência de automação.

Calibração


Podemos classificar os sensores de várias formas: ativos e passivos, elétricos, pneumáticos eou mecânicos etc. Para efeito de calibração, podemos dizer que existem sensores que precisam de calibração e os que não precisam.

Como exemplo, vamos comparar dois sensores de temperatura, um termistor e um LM35.

Resumindo o que vc pode ler nos dois links, o termistor é um sensor passivo (ou seja, não demanda energia de alimentação para funcionar) enquanto que o LM35 é um sensor ativo que possui um pequeno circuito integrado dentro.

O que mais diferencia os dois? O termistor apresenta uma variação na resistência elétrica em função da variação da temperatura, ou seja, se vc precisar fazer uma leitura da temperatura vc tem que calibrá-lo. Isso significa ser necessário determinar a resistência dele em função da temperatura em alguns pontos gerando uma curva, ajustar uma equação para essa curva e então usar a equação ajustada no seu programa para calcular a temperatura em função da resistência.

Já no caso do LM35 a leitura "já sai" calibrada e linearizada, ou seja, junto com o sensor vem publicada uma constante de mV/°C, então basta vc multiplicar a saída do sensor em mV pela constante e pronto. No caso do Arduino, vc usa o seguinte código, supondo que o sensor está

 // supondo que o sensor está ligado à porta 0 analógica  
 int mv = (analogRead(0)/1024.0)*5000;   
 int temperatura = mv * 10;  

Muito mais simples, sem necessidade de calibração.

No caso dos LDRs, sensores de luz usados pelo nosso míssil, o mesmo sofre grande influência do ambiente, então é necessário calibrá-lo em runtime, ou seja, fazer uma função que calcule o "zero" de cada sensor antes de usá-lo, facilitando a comparação entre os valores deles quando em funcionamento. Exemplo: se vc disparar o míssil com o sol posicionado à esquerda deste, o sensor do lado esquerdo dará leituras mais baixas que o do lado direito (já que quanto mais luz menos resistência) sem que tenha necessariamente um alvo a ser seguido desse lado.

Para isso, usa-se uma função de calibração semelhante à escrita abaixo, que foi usada para o projeto em questão:

 int pinL = 0;  // pinos de conexão dos sensores: esquerda, direita, acima abaixo
 int pinR = 1;  
 int pinU = 2;  
 int pinD = 3;  
 
 long calL = 0; // Valores de calibraçao, a serem calculados na função calibracao()
 long calR = 0;  
 long calU = 0;  
 long calD = 0;  
 
 int iterCal = 50; // Número de iterações para calibração  

 void calibracao()  // função de calibração
 {  
  for(int i=0;i<iterCal;i++)  
  {  
   calL += analogRead(pinL);  
   calR += analogRead(pinR);  
   calU += analogRead(pinU);  
   calD += analogRead(pinD);  
   delay(50);  
  }  
  calL /= iterCal;  
  calR /= iterCal;  
  calU /= iterCal;  
  calD /= iterCal;    
 } 
 
 void setup() {  
  calibracao();  
 } 
 
 void loop() {  
 }
  

A rotina calibração acumula iterCal leituras dos sensores e depois tira a média, achando os valores calL etc.

Para usar esses valores é muito fácil. basta descontá-los na hora da leitura dos sensores dentro do projeto:

 long valL = analogRead(pinL) - calL + 1000;   
 long valR = analogRead(pinR) - calR + 1000;   
 long valU = analogRead(pinU) - calU + 1000;   
 long valD = analogRead(pinD) - calD + 1000;   

Quando se faz essa subtração se elimina algum efeito de diferença de fabricação entre os sensores, ou de posicionamento relativo às fontes de luz ambiente etc.

E porque adicionar 1000? É que com isso nos livramos de valores negativos, já que o desconto da calibração leva a números próximos de zero mas não necessariamente positivos. Como as leituras do LDR variam mais ou menos de 40 a 300, somar 1000 faz com que os valores sejam necessariamente positivos. Para o seu sensor pode ser diferente.

Threshold ou Limiar


Quando comparamos valores de sensores temos que imaginar que eles tem imprecisões, e também que muitas vezes são mais sensíveis do que a gente necessita, captando alterações de valores que são muito pequenas para nos interessar.

Nesse caso, devemos usar um valor de threshold, que nada mais é do que um limite mínimo de variação de valores que deve ser observado para que o sistema considere realmente que houve uma variação. Assim, num sistema de aquecimento por exemplo, em vez de escrever:

if (temp< setPoint)  
   // liga o aquecedor
else 
  // desliga o aquecedor

o que poderia fazer com que o sistema ficasse oscilando, ligando e desligando o aquecimento muito rapidamente, o que no caso de um relé poderia levar a superaquecimento e deterioração do dito, podemos escrever:

if ((setPoint - temp) > threshold)  
 // liga o aquecedor.  
 else  
   if ((temp - setPoint) > threshold)  
   // desliga o aquecedor.  

E qual o valor de threshold? Bom, aí cada caso é um caso. Vc deve ajustar o seu de maneira que o circuito não oscile muito mas também não fique "insensível", ou seja, demore a responder ao distúrbio na variável medida.

Abaixo, outras imagens que o Fábio, dono do projeto, me mandou:







É isso! Por fim, a bagaça funcionando. Com uma lanterna, vou incidindo a luz em cada sensor, como dá pra ver do lado esquerdo do vídeo. Observem o detalhe do grampo de cabelo funcionando como "aleta" do foguete... isso, claro, foi feito para facilitar a percepção da posição nos testes.

Abracadabraço,

Mauro


segunda-feira, 11 de julho de 2016

... e a minha geladeira agora roda Python!

Ultimamente tenho me dedicado a um novo hobby, que é cozinhar a minha própria cerveja. A ideia é produzir 20 litros por sábado, que são divididos com os amigos que participam da farra, ops, trabalho.

Em função disso tenho feito projetos legais de automação ligados ao processo cervejeiro, e agora vou passar a publicá-los cá. Sápassado (como dizemos nós de BH) fiz uma palestra no TDC sobre o assunto e surgiu a ideia de criar uma trilha de Tecnologia Cervejeira por lá ano que vem, então vamos já juntando os assuntos por aqui.

Depois eu pretendo fazer um post sobre o processo de produção de cerveja para contextualizar vcs. O fato é que essa é a minha nanocervejaria:

Toda vez que eu construo um equipamento novo, a mangueirinha do chuveiro de hóspedes encolhe...
Os processos cervejeiros são basicamente quatro: brassagem, fermentação, maturação e primming.

Nesse domingão (ontem) eu e o meu Mestre Cervejeiro Tiago, também programador e praticante do Arduinismo, automatizamos a etapa de maturação.

A maturação consiste em deixar a cerveja em um balde tampado em um ambiente climatizado, com temperatura constante e fria. Dependendo do tipo de cerveja pode haver uma rampa de temperatura, ou seja, começa-se na temperatura ambiente e vai resfriando-se o líquido até uma temperatura de uns 3 °C.

Até outro dia eu fazia essa maturação na geladeira do condomínio, em temperatura constante. Aí resolvi aperfeiçoar o processo fazendo uma câmara de maturação em casa, o que nada mais é do que uma geladeira em que eu consiga controlar a temperatura.

Ao começar a "prospectar" a geladeira, o amigo e colega de cerveja Pedro Valle conseguiu com a sogra dele uma geladeira, e ela ainda nos fez a gentileza de emprestar o veículo para transporte.

Acontece que o termostato da geladeira tava quebrado, então ela tava ligando direto. Com esse frio, olhem o que aconteceu com a cerva...


Pois é, virou picolé... isso deve ter feito com que ela se perdesse, pois o fermento deve ter morrido congelado e ele é necessário para o primming. Vou tentar "consertá-la", mas acho que vai rolar não... :(

Bom, o fato é que precisamos controlar a temperatura da máquina, e a melhor forma de fazer isso foi substituir o termostato "zuado" por um outro. E porque não um Raspberry, de maneira a colocar a geladeira na web?

Eis aí o resultado de algumas horas de trabalho no domingão:


Eu tinha um Pi antigão, relés, o Mauríllio, colega cervejeiro com quem fiz um projeto junto e do qual falarei em outros posts me deu um sensor de temperatura, mais um plug wifi que eu já tinha e a geladeira foi parar na intranet da casa!



Vcs podem ver acima o furo que fizemos na bicha para passar:

- O cabo do sensor

- Um par de fios para se conectar no par que substituiu o termostato, agora substituído pelo relé que dá pra ver na foto em detalhe (aquele gadget com o LED vermelhor aceso).

Daí fizemos uma aplicaçãozinha Python que monitora a temperatura, acionando a geladeira quando passa um grau do setpoint e desligando-a quando passa de meio grau abaixo.

Aqui o monitoramento da dita via telnet:



Bom, é isso. Nos próximos posts vamos aos detalhes.

Abracadabraço,

Mauro




domingo, 6 de março de 2016

Detectando pulsos com o Arduino

Dia desses apareceu no Automação no Parque um velho conhecido, o Bruno, um aluno que trouxe o seu TCC tempos atrás e que foi um dos projetos mais legais que a gente já fez. Foi um controle de potência de chuveiro, que deu origem aos posts mais acessados desse blog, a série sobre Controle de Potência por Ângulo de Fase.

Dessa vez ele trouxe um problema, senão tão difícil,  bem interessante. Ele está fazendo estágio num desses vários centros de pesquisa do governo que tem em SJC (me esqueci qual) e por lá rolou o seguinte problema:

- Os caras tem um equipamento que precisa coletar pulsos de um pouco mais de 2V e de 50µs de duração. Existe por lá um equipamento caro que detecta esse pulso, mas eles querem tentar substituir por algo mais em conta.

A pergunta: será que o Arduino "auguenta"???

Como o equipamento não poderia vir até nós, tínhamos que tentar gerar um sinal semelhante para testar. Prá isso, nada melhor que outro Arduino.

























Circuito "simplão", com um Arduino para gerar os pulsos e outro para detectá-los. O Arduino da esquerda gera os pulsos, o da direita detecta. O potenciômetro ajusta a tensão do pulso, para que possamos fazê-la semelhante ao que o Bruno precisa.

Para monitorar os pulsos, usamos um osciloscópio para monitorar o comportamento da bagaça:

Os pulsos vistos aqui foram os que fizemos inicialmente, de 100µs a cada ms. O potenciômetro foi usado para ajustar a tensão, também medida pelo osciloscópio e ajustada para 2V.









Os pulsos foram gerados pelo seguinte código:

#define P_OUT 7

void setup()
{
  pinMode(P_OUT,OUTPUT);
}

void loop()
{
  digitalWrite(P_OUT,LOW);
  delayMicroseconds(1000);
  digitalWrite(P_OUT,HIGH);
  delayMicroseconds(100);
}

Já na detecção foi usado o seguinte código:

#define P_IN 8

void setup()
{
  pinMode(P_IN,INPUT);
  Serial.begin(115200);
}

long t = 0;
int i = 0;

void loop()
{
  t=pulseIn(P_IN,HIGH);
  if(t==0)
    return;
  Serial.print(t-7);
  Serial.print(' ');
  i++;
  if(i > 20)
  {
    Serial.println();
    i=0;
  }
}

O comando pulseIn do Arduino é chave no processo. Ele espera, na porta P_IN, que um pulso HIGH aconteça. Um pulso HIGH significa que o sinal do Arduino saiu de LOW (0V), foi prá HIGH (mais sobre isso abaixo) e prá LOW de novo. A função retorna a duração, em µs, do pulso detectado.

A função possui um terceiro parâmetro, opcional, que recebe o tempo de espera, quer dizer, quanto tempo a função espera pelo pulso. O default é 1s. Mais informações aqui.

E qual é exatamente o valor HIGH, quer dizer, qual o valor mínimo de tensão que o Arduino detectaria? E qual a mínima largura do pulso, ou seja, quanto tempo o pino tem que ficar HIGH para que o Arduino o detecte? Esse foi o objetivo do nosso experimento, a própria documentação do Arduino fala que tem que ser assim, empiricamente.

O programa de detecção imprime a duração de cada pulso detectado. O valor da variável t é subtraído de 7 porque, depois de vários experimentos, determinamos que  chama da função retorna sempre 7µs a mais a cada valor medido. Talvez seja esse o tempo consumido pela própria função, sei lá eu.

A gente conseguiu baixar a largura do pulso até 5µs, e a tensão até 2,1V. Menos do que isso o Arduino Mega (detector) não conseguia perceber o pulso.


Ao lado, pulso de 5µs.

Acho que depois vale a pena fazer um estudo melhor disso, ver se existem outras implementações do pulseIn na internet, ver se o valor da tensão tem alguma correlação com a largura do pulso (quer dizer, se por exemplo o pulso fosse de 5V, será que ele detectaria um pulso de menos de 5µs de duração?) etc.

De toda forma, atingimos com uma certa folga (pelo menos na largura do pulso) o objetivo buscado pelo Bruno. Ele vai seguir com o projeto e depois (espero eu!) nos dará retorno sobre o que aconteceu.

É isso.

Abaixo, filme do troço funcionando. Dá prá ver os dois Arduinos, o circuito com o potenciômetro, a tela do osciloscópio e os resultados no notebook.




E abaixo, funcionando com pulsos de 5µs a cada segundo. Repare que é bem difícil de perceber o pulso na tela do oscilocópio.

É isso.


domingo, 10 de janeiro de 2016

Primeiro Automação no Parque de 2016

Ontem estreamos no Automação no Parque 2016. Começamos bem, um bocado de gente, projetos interessantes, a turma do cosplay cada vez mais presente... aí vão as fotos:
















Um dos projetos legais é um de dar uma turbinada numa espada Jedi. A ideia é fazê-la soar mais alto e intensificar o brilho do sabre. Para isso o trabalho não será fácil, acho, mas é possível chegar a um bom resultado.






















Acima o punho da espada aberto, contendo o circuito de comando.

    Abaixo estrutura que suporta os LEDs da "lâmina de luz".




































A Prefeitura está terminando a reforma do telhado do quiosque, porisso as faixas que teoricamente deveriam impedir o acesso ao espaço. Como a obra está quase pronta e não haveria trabalho ontem, o povo sempre gente fina do Parque autorizou-nos a pular a cerca.
















Acima, o projeto do Michael, segundo ele uma espécie de quadripod capaz de andar na vertical!

Esse promete!

É isso. Automação no Parque strikes back, apareceçam!