Manual
do
Maker
.
com
Em mais um ou dois artigos vou publicar mais um projeto bacana e um dos recursos envolvidos é o flow meter. Existem outras maneiras de medir o fluxo de água com Arduino, mas não há dúvida de que essa é a mais simplificada, pois esse dispositivo vendido na UsinaInfo está pronto para uso, basta fazer a leitura. Por isso nessa primeira fase do projeto (que ainda não será revelado), vamos ver como utilizá-lo para posteriormente fazer a integração do conjunto.
Como se mede o fluxo de água nesse disposito? Simples, por efeito hall. Ele possui um sensor que gera uma interrupção a cada volta. Como tudo, existe uma taxa de erro e ela pode ser causada por duas razões que me ocorrem no momento; se o posicionamento do sensor estiver ligeiramente além da interrupção, quase uma volta completa será computada como margem de erro. A outra possiblidade é a entrada de ar que, assim como em hidrômetros, é considerada como consumo.
Quando for adquirir esse sensor, tenha em mente que sua capacidade é de 30 litros/min, de modo que você não poderá medir um fluxo torrencial de um hidrante. Mas para muitos projeto cai perfeitamente, como o projeto para o qual ele será designado em breve.
É tão simples quanto se possa imaginar. Não requer circuito adicional, apenas alimente-o com os 5V do Arduino, ligue o ground e use o pino digital 2 para que possamos trabalhar com interrupções.
A ordem deve ser como disposta acima, considerando a saída do sensor. Estou citando isso porque no conector o GND e o SIGNAL estão invertidos, de modo que tive que colocar o jumper para o pino 2 no centro do conector e o ground à esquerda.
É muito comum ver tarefas que poderiam ser tratadas com interrupção serem tratadas no loop e em algumas vezes realmente é funcional, mas não para esse sensor, porque você não ficará lendo ininterruptamente a porta digital, senão não sobra tempo pra MCU fazer outra coisa e ainda assim é capaz de perder leitura. Por isso nesse caso utilizamos o recurso de interrupção. Se quiser maiores detalhes, leia esse outro artigo relacionado a interrupções e timer com Arduino.
Basicamente, você precisará conectar a interrupção a uma função de callback. Por exemplo:
attachInterrupt(digitalPinToInterrupt(2), changeState, FALLING);
Nesse caso, estamos habilitando a interrupção do pino digital 2, chamando a função de callback changeState, que atuará quando o sinal mudar de estado na descida do sinal.
Nesse artigo estou utilizando o Arduino Nano e a base de expansão para ele, é bastante prático e acostumei a utilizá-lo, recomendo. Os pinos de interrupção do Arduino Nano são os mesmos do Arduino UNO, sendo os pinos 2 e 3 digital.
Outra coisa muito importante agora é que, por se tratar de uma interrupção com eventos acontecendo muito rapidamente, nós devemos tirar a otimização da variável de contagem das "mãos" do compilador. A variável volatile informa ao compilador que não pode-se prever o valor da variável com precisão, pois ela pode ser modificada em qualquer parte do programa. Desse modo, reduzimos a margem de erro no incremento do contador. Tentando explicar de maneira mais clara, é como ir até a janela, olhar pra fora, voltar e relatar o que foi visto. Mas enquanto se está contando a alguém o que foi visto pela janela, o evento poderá ter se modificado. Utilizando volatile é como se olhassemos pela janela de longe e relatassemos o que vemos em tempo real. Toda essa explicação apenas para declarar uma variável. Demais, hum?
volatile int pulse;
...
void setup(){
pulse = 0;
...
}
A capacidade de medição é de 30l/m ou, 30 litros por minuto. Se você ligar isso em um hidrante, não vai medir nada direito. Se o fluxo for abaixo do suficiente para encher o interior do dispositivo sensor, também não dará uma boa precisão. Logo, a recomendação é que faça uma calibragem prévia do fluxo do líquido a ser medido. Eu fui ao tanque de lavar roupas e não fiz imagens ou video porque apesar de mostrar um Arduino, mostraria também uma área que não é do interesse de ninguém. Enfim, estando no tanque, medi por diversas vezes o preenchimento de um vasilhame de 1 litro, com um fluxo comum; nem baixo, nem alto. Medindo desse modo, concluí que o melhor caso é de 404 pulsos por litro. Em 1 litro, 2 ou três litros, qualquer diferença não será notada, mas para o projeto que pretendo publicar, a medição precisará de maior acuidade. Por ora está bem assim, já é o suficiente para a prova de conceito.
considerando que 1 litro contém 1000ml e temos 404 pulsos por litro, significa que em média cada pulso mede 2.475ml de líquido não viscoso. O projeto que será apresentado estará sendo aplicado em um caso real onde preciso medir 30 litros de água; não 31 nem 29, nem meio pra mais, nem meio pra menos. E esse fluxo será controlado automaticamente no projeto final (não vou entrar em detalhes agora), por isso já vou considerar a medição com apresentação na serial (nesse momento), a 1 litro ou, 404 pulsos.
#define LITER 403
volatile int pulse;
int liters = 0;
bool oneMore = false;
void setup(){
pulse = 0;
Serial.begin(115200);
attachInterrupt(digitalPinToInterrupt(2),changeState,FALLING);
}
void changeState(){
pulse += 1;
if (pulse >LITER){
pulse = 0;
liters += 1;
oneMore = true;
}
}
void loop(){
if (oneMore){
Serial.print(liters);
Serial.println(" litros");
oneMore = false;
}
delay(10);
}
Perceba que o print na Serial poderia ter sido colocado dentro da interrupção, mas não é uma boa prática porque isso travaria a interrupção na tarefa. Colocando o valor do boolean oneMorepara true ao completar cada litro, o loop se encarregará de exibir o status sem degradar a interrupção.
Entenda também que esse código não é para dar a média de litros por minuto. Isto é pelo fato de que será aplicado em algo específico onde é necessário medir o líquido. No próximo artigo relacionado apresentarei a segunda peça do conjunto, talvez aí você já possa deduzir a aplicação (será?).
Inscreva-se no nosso canal Manual do Maker no YouTube.
Também estamos no Instagram.
Autor do blog "Do bit Ao Byte / Manual do Maker".
Viciado em embarcados desde 2006.
LinuxUser 158.760, desde 1997.