Anemômetro caseiro digital com Arduino • Do bit Ao Byte
Djames Suhanko 24 de novembro de 2015 9 min read
Quando criança, os trabalhos de ciência da escola envolviam coisas simples como planetas de bolinhas de isopor, grão de feijão brotando no algodão e afins. Oras, estamos em uma era digital onde escolas de países desenvolvidos estão inserindo programação na grade do curso fundamental; está mais do que na hora de atualizarmos os trabalhos escolares de nossas crianças de hoje não é mesmo?
Para isso, vamos fazer um upgrade em um dos clichês de trabalho de ciências – o anemômetro. Esse é um tutorial realmente para servir de trabalho escolar utilizando uma microcontroladora para coletar os dados reais. Mas não se preocupe, os códigos estarão disponíveis aqui no post para que você possa fazer esse trabalho, ainda que não tenha intimidade com programação. Provavelmente é mais prático um vídeo-tutorial, mas as coisas saem mais rápido apenas escrevendo. Depois coloco o vídeo mostrando o funcionamento.
Existem anemômetros de 3 pontos, o que me parece ideal por reduzir a resistência do vento devido à existência de uma face oposta, ainda que convexa. Claro que é mais fácil fazer um cruzamento sem cálculo nenhum e partir pro próximo passo, então vamos fazer isso, afinal não vamos vender isso para a aeronáutica, certo?
Anemômetro ostentação
Com 2 Kinder Ovo Joy, 3 palitos de sorvete e um canudo já conseguimos fazer a estrutura do anemômetro caseiro gastando menos que o valor de uma BMW!
Eu sei, esse doce é bem caro mesmo. Você pode utilizar caixa de ovo, se tiver à mão, basta que seja leve para reduzir a resistência e atrito do canudo com a base. A construção será basicamente a mesma, então sigamos.
A primeira etapa é marcar uma área do palito; apoie-o sobre uma régua, tire meio centimetro da esquerda e o que exceder a medida, suponhamos, de 10cm, como é o caso que você pode notar na imagem da régua. Depois essas pontas sobressalentes devem ser removidas, preservando assim a simetria dos palitos. É importante que os 2 palitos fiquem do mesmo tamanho por duas razões; achar o centro do palito e balancear o peso adequadamente para que o anemômetro não fique pendendo para lado nenhum.
Feitas as devidas marcações, ache também o centro cruzado do palito, de forma que seja possível ver onde furar. O furo pode ser feito com faca de cozinha, mas vai ser demorado. Se você programa em Python, peça ajuda para o papai e mamãe. Se programa em Java, consulte seu médico primeiro, mas não corram riscos, façam sob a supervisão de um adulto responsável para não se cortar.
Dá pra usar parafusadeira também pra furar e o risco é bem menor. Ou ainda, utilize uma Dremel se tiver. Eu fiz com uma Dremel.
Não coloquei medida nenhuma, apenas o canudo utilizado é desses de tomar milkshake, então o furo foi feito apenas do tamanho suficiente para passar justo pelo canudo. Claro, furei 2 a mais até acertar o diâmetro, mas ficou bacana no final. Os furos ficaram assim:
O óbvio é que você deverá encaixá-lo no canudo e mantê-los cruzados. Cole-os um ao outro. A cola excedente também tocará o canudo e ao fim tudo permanecerá junto. Eu utilizei cola para madeira primeiro, mas queria resultado logo para poder continuar a escrever o post, então utilizei cola de secagem rápida (Super Bonder). Se você for programador PHP, peça ajuda para um adulto porque essa cola pode casar seus dedos e eles ficarão juntos até que a morte os separe.
Você precisará de uma base para apoiar o canudo. Essa base deve ter uma aste que inclusive pode ser um prego. Eu utilizei uma "espiga", daquelas que são coladas em gavetas para unir as partes. Você consegue umas com qualquer marceneiro, ele não te cobrará nada por uma dessas. Para finalizar, ajuste o comprimento de forma que as pás não toquem a base e ainda sobre algum espaço abaixo, então cole um palito furado novamente. Esse palito deverá ser cortado posteriormente para reduzir seu comprimento. Ficará mais ou menos assim:
Antes de darmos sequência ao projeto de ciências, vamos discorrer um pouquinho sobre matemática; mas calma, será divertido, vamos descobrir alguns valores para utilizar no nosso programa.
Como calcular o perímetro de um círculo?
Sei que tem hobistas lendo porque isso também é divertido para adultos, mas realmente acredito que será utilizado em trabalhos escolares e até universitário, dependendo dos conceitos que se deva empregar. Não sabendo exatamente sua idade e o quanto você tem de conceitos, me sinto obrigado a deixar claro alguns desses conceitos. Paciência, ok?
Perímetro é o tamanho linear ocupado por uma forma. Um quadrado com lados de 2 centímetros tem o perímetro de 8 centímetros (porque são 4 lados de 2 centimetros, logo, 2*4 = 8).
Para calcular o perímetro de um círculo, você precisa saber o seguinte:
Quando você faz um círculo com um compasso, a medida do furinho da agulha até a borda do círculo é chamada de raio, ou seja, essa medida representa a metade do diâmetro.
É o tamanho do circulo. Se de um lado a outro ele tem 5 centímetros, ele tem 5 centímetros de diâmetro e 2,5 cm de raio.
Mas como medir o perímetro de um círculo? Com régua não dá. Então o que você precisa fazer é descobrir o raio ou o diâmetro do círculo previamente, então aplicamos um valor chamado "pi" da seguinte maneira.
Supondo r = raio, d = diâmetro e p = perimetro, calculamos o perimetro de um desses modos:
VOCÊ SABE O RAIO. SUPONHAMOS, 2,5cm
[latex]p = (r*2)*\pi[/latex]
[latex]p = (2,5*2)3,14[/latex]
Ou você sabe o diâmetro. Supondo 5cm:
[latex]p = d*\pi[/latex]
[latex]p = 5*3,14[/latex]
Você pode determinar a distância pretendida. No meu caso, para essa ultima foto do palito "interruptor" eu deixei um raio de 3cm:
[latex]p = (3*2)*3,14[/latex]
[latex]p = 18,84cm[/latex]
Isso significa que uma volta completa do interruptor representa 18,84cm percorridos, se fosse em linha reta. Bastante, não? Por isso fiz com que o palito interruptor interagisse 2 vezes, de forma que a medida que utilizaremos no código é o raio, porque se interrompe 2 vezes, significa que interrupção = p/2:
[latex] p = 3*\pi[/latex]
[latex] p = \frac{p}{2}[/latex]
[latex]p = 9,42[/latex]
Se o cara que soprar tiver fôlego de peixe, pelo menos 1 interrupção ele deve conseguir.
Pra que precisamos saber do perimetro afinal? – Bem, para calcularmos a velocidade, precisamos medir deslocamento no tempo. É como um carro andando a 60KM/h; significa que se ele mantiver a velocidade ininterruptamente por 1 hora, ele terá percorrido 60KM. E é o que queremos nesse momento, medir a velocidade, mas do vento. Já encontramos a unidade de medida base, agora precisamos mensurar tempo. Entra então a parte dos programadores. Se você não é programador, pule para a próxima parte, caso contrário é agora que o assunto fica sério.
Teremos 2 tipos de interrupção nesse projeto; um será a interrupção por pino e o outro a interrupção do timer, pois será necessário a utilização de tempo. Se você não está habituado a utilizar timers ou se não leu meus posts a respeito, sugiro a leitura desse post para Arduino e a leitura desse post para PIC.
Precisamos determinar um espaço de tempo para coletar amostras. Fiz uns testes até ficar (mais) tonto, então cheguei à conclusão subliminar de que 2 segundos é um bom espaço de tempo para coletar amostras.
O timer deverá ser configurado para interromper em 2 segundos; a interrupção do palito deverá ser somada em uma variável sempre. Quando o timer estourar, ele lê o valor da variável de interrupção do palito e a limpa. Finaliza calculando a distância em metros/s ou km/h, tanto faz, depois que os valores estão à mão, dá pra calcular o que quiser.
Interrupção no pino
Para quem está habituado com MCUs, mata de cara: estou utilizando uma das piores formas de gerar interrupção. E na verdade, nem é interrupção mesmo porque a leitura é analógica. Estou utilizando um fotodiodo infra-vermelho. É barato, estava à mão e vai quebrar o galho, mas o ideal seria utilizar um imã preso às pontas do palito e um reed switch para gerar interrupção de verdade e assim que chegar os reed switch, dou uma atualizada no post, por enquanto divirtam-se com esse, vale a pena.
Esse circuito foi o teste de sensibilidade, não tinha certeza se a excitação do sensor seria rápida o suficiente para não se perder na contagem. Com um resistor de 10K no receptor foi possível gerar uma ótima sensibilidade, onde em baixa temos algo em torno de 30 e na interrupção rápida passa de 500, havendo uma grande margem para garantir que a variação foi uma interrupção. Bem, não é "aquela" interrupção, mas é um tipo de interrupção também. Esse código pode lhe servir para testes genéricos também, mas logo adiante coloco o código utilizado no anemômetro:
//limite para considerar interrupcao
int photo     = 2; //alimentacao do photodiodo
int LED       = 13;//LED amarelo no pino 13
int photoRead = 0; //leitura do photodiodo
int value     = 0; //leitura do A0
pinMode(photo,OUTPUT);
digitalWrite(photo,HIGH);
value = analogRead(photoRead);
if(value <= THRESHOLD){ digitalWrite(LED,HIGH); delay(30); } else if(value > THRESHOLD){
Serial.println(valu// ]]>e);
Muda pouca coisa no tratamento da interrupção do fotodiodo; invés de acender LED, adicionamos uma variável acumulativa chamada por exemplo, counter. A função dessa interrupção é exclusivamente acumular valores nessa variável. Nesse caso, não teremos mais o 'else if', apenas o 'if' com a seguinte modificação:
Apenas isso. Agora a interrupção do timer; quando houver 1 segundo de interrupção, uma função fará a leitura do valor contido na variável counter e a conta será SUPER-MEGA-HIPER SIMPLES:
velocidade = counter * raio
Porque haverá 2 interrupções por volta, ou seja, a cada 180 graus haverá uma. O resultado dessa conta será cm/s. Se quiser fazer metros por minuto, basta multiplicar por mais 60, e por aí vai. A biblioteca que estou utilizando para fazer a interrupção do timer é a TimerOne desse link, citada nesse post sobre interrupções com Arduino.
O código incluindo a interrupção, função e variável necessária é este:
#define RATIO 9.42
int counter   = 0; //acumulador
float anemometer = 0; //velocidade
//interrupcao a cada 2segs, portanto divide o tempo
//para ter cm/s
anemometer = (counter * RATIO)/2;
go         = true;
Timer1.attachInterrupt(meter);
delay(80); //deixe o palito sair de cima...
Serial.print(" Centimet// ]]>ros por segundo: ");
Serial.println(anemometer);
/*Nao precisa se preocupar em limpar essa var
porque o counter eh zerado em meter() e qualquer
valor vezes 0 eh... bem, voce sabe.*/
Como você pode reparar no código uma péssima decisão foi a utilização de um delay para não repetir a contagem numa passada rápida sobre o sensor. Mas e se estiver lento? E se estiver parado sobre o sensor?
Quando você precisa aguardar por uma mudança de estado, é fundamental a utilização de uma flag, porém haveríamos de considerar um novo threshold para a queda, além da flag e então avaliar a mudança de estado. É código ruim demais pra um objetivo tão simples, vale a pena usar como está. Por fim, utilizando um reed switch tudo se resolverá porque sequer será necessário threshold, uma vez que só teremos 2 estados; 0 ou 1. Desse modo fica fácil utilizar uma flag e uma condicional extra para não gerar falso-positivo e ainda por cima dá pra eliminar o delay, deixando o código bem próximo de bom.
Agora resta transferir o circuito para a base. Para isso, basta fazer as mesmas conexões que na protoboard, comportando os componentes na base, mais ou menos assim:
Base de interrupção
Pra encerrar, fiz brincadeiras com algumas linguagens de programação. Sou programador Python e fiz coisas extremamente importantes nessa linguagem, principalmente robôs de backup de switches e interação com BGP de uma operadora de telecom na Colômbia. Em PHP já fiz um sistema de monitoramento de servidores em 2005 e em Java bem, não fiz nada. Mas foi só uma brincadeira, cada linguagem tem a sua diversão!