Aprendendo Arduino — Parte 3B — construindo algo útil

sensuranuncamais

Previously, on Battlestar Galactica…

Nós vimos os princípios básicos de funcionamento dos semicondutores, e como algumas de suas características se revelaram úteis na fabricação de sensores de gases muito mais baratos e sensíveis que os tradicionais. Agora vamos ver como isso pode ser utilizado, em conjunto com o Arduino para construir algo… útil.

Eu tenho fobia e bujão de gás, acho incrível não termos explosões o tempo todo nas cidades. Cada vez que tenho que trocar o bujão é um parto, aquelas frações de segundo entre a válvula lacrar, enquanto o butano espirra pra fora, eu já começo a pensar Oh a Humanidade…

Descobrir se a válvula está bem conectada é outro parto. Tenho que depender da técnica neandertal de espuma de sabão. Na cozinha então… só fica a dica: se você tem gente com Alzheimer em casa, não se resfrie, vai precisar do nariz para detectar se eles abrem o gás, esquecem que vão fazer café e deixam pra lá.

Quem poderá me salvar disso? Arduino, claro, com ajuda de um módulo Sensor MQ-4.

mq-4

Como expliquei por alto no outro artigo, o uso é extremamente simples. Você tem um pino de saída digital que ninguém usa, positivo, negativo e saída analógica.

Essa saída analógica varia entre 0 volt e 5 volts, e representa concentrações de gases entre o mínimo detectável e o suficiente para saturar o detector (eu linkei a datasheet do sensor no texto anterior).

Os valores são convertidos pelo Arduino, que retorna um número entre 0 e 1.023. Se você se lembrar do primeiro artigo, vai converter 1.023 para binário e descobrir que é 1111111111. Isso significa que a conversão analógico pra digital do Arduino tem uma resolução de 10 bits.

Se você está entendendo resolução como resolução gráfica de imagens, a analogia é perfeita. A resolução de um sinal analógica significa em quantos pedaços discretos aquele sinal é representado. Usemos o bom e velho papel quadriculado. A resolução dele é de 10 quadrados por cm. Digamos que temos uma curva em uma área de 5 cm de altura por 6 cm de largura.

50bits

Se eu marcar com uma caneta cada quadradinho de 1 mm conseguirei uma aproximação muito boa da curva original:

resol01

Essa é uma amostragem com 50 bits de resolução. Para a nossa realidade isso é irreal. Trabalhamos com 10 bits, então o resultado é mais ou menos assim:

10bits

10 bits parece pouco, mas se usados como informação de cor dão 1.024 tons de cinza por pixel. Aquela fanfiqueira ficou rica com 50 tons de cinza e a sonda soviética Venera 9 transmitiu as primeira imagens da superfície de Vênus com apenas 6 bits, ou 63 tons de cinza.

c_venera09_processed

Vamos ver então nosso circuito inicial: usando só os componentes do kit de Arduino que comprei. Em um experimento inicial criaremos um circuito para transformar as informações do sensor em áudio.

Inicialmente pensei em fazer algo como um contador Geiger, mas pro áudio funcionar direito teria que usar interrupções e não é hora de falar disso ainda. A alternativa é tom contínuo, igual detectores de metal.

O resultado saiu melhor do que eu imaginava:


Carlos Cardoso — Exemplo de sensor MQ-2

Como funciona o circuito:

circuito1

A saída analógica do Sensor é ligada no pino A0 do Arduino.

Um LED verde é ligado em série com um resistor de 1 kΩ ao pino 9.

Um LED vermelho é ligado em série com um resistor de 1 kΩ ao pino 10.

O pólo positivo do buzzer é ligado ao pino 9 do Arduino.

Os negativos são ligados ao barramento negativo da protoboard, que é conectada ao negativo do Arduino.

Pino V+ do sensor é ligado ao pino 5 V do Arduino, pino negativo do sensor, ao negativo do Arduino.

Simples assim.

Agora, o programa

AVISO: o objetivo aqui é didática, não performance. Se você tem sugestões de como otimizar o código, rotinas em assembler e comandos esotéricos, mande mande um email e explicarei o que deve fazer com sua sugestão, mas pra adiantar, consiga bastante vaselina.

O programa é quase tão simples quanto o circuito:

//pinos básicos, autoexplicativo, espero.

const int buzz =8;
const int LEDSinal = 9;
const int LEDRed = 10;
uint16_t jorge;
int som = 0;
uint16_t sensor = 0;

void setup() {
pinMode(buzz,OUTPUT);
pinMode(LEDSinal,OUTPUT);
pinMode(LEDRed,OUTPUT);

//resetando botões
digitalWrite(LEDSinal,LOW);
digitalWrite(LEDRed,HIGH);

//delay de 30 segundos até o sensor aquecer.
//na fase de testes recomendo diminuir o delay.
delay(30000);
digitalWrite(LEDRed,LOW);

for (jorge = 0; jorge <3; jorge +=1) {
digitalWrite(LEDSinal, HIGH);
delay(10);
digitalWrite(LEDSinal, LOW);
delay(10);
}

}

void pisca() {
delay(20);
digitalWrite(LEDSinal,HIGH);
delay(20);
digitalWrite(LEDSinal,LOW);
}

void loop() {
delay(10);
sensor = analogRead(A0);

som = map(sensor ,10,50, 50,400);
tone(buzz,som,(1/(sensor * 10)));
pisca();
delay(50);

}

Vamos entender por partes:

const int buzz =8;
const int LEDSinal = 9;
const int LEDRed = 10;
uint16_t jorge;
int som = 0;
uint16_t sensor = 0;

Aqui nós definimos nossas variáveis principais e nossas constantes. Sempre que possível use constantes, elas são movidas pra memória FLASH e não comem sua preciosa RAM.

As três constantes buzz, LEDSinal e LEDRed funcionam como mnemônicos para facilitar a associação dos pinos com suas funções. Assim em vez de escrever um comando digitalWrite(9,HIGH) e depois ter que lembrar que diabos faz o pino 9, você escreve digitalWrite(LEDSignal,HIGH).

A variável jorge é um inteiro de 16 bits, unsigned, ou seja, sem sinal. Ele é sempre positivo. Como tem 16 bits, seu valor máximo é 1111111111111111 ou em binário 65.535. São só dois bytes, é mais seguro que usar um inteiro simples que se restringe a valores entre 0 e 255.

A variável som é um inteiro simples. Ele será a frequência gerada pelo Arduino. A função de áudio aceita valores entre 0 e 65.535 mas vamos trabalhar com com 256 variações, isso gera um resultado mais artificial e “robótico”.

sensor é uma variável de 16 bits, mas que só usaremos 10. Ela armazenará o resultado da leitura do pino A0, que recebe o sinal analógico do sensor MQ-4.

void setup() {
 pinMode(buzz,OUTPUT);
 pinMode(LEDSinal,OUTPUT);
 pinMode(LEDRed,OUTPUT);

Aqui nós definimos o que cada pino vai fazer. Todos os três são definidos como saída de dados. O pino A0 não é definido, pois por padrão ele é um pino analógico de entrada. Ele pode ser usado como um pino digital de Entrada/Saída, mas não é o caso.

//resetando botões
digitalWrite(LEDSinal,LOW);
digitalWrite(LEDRed,HIGH);

Aqui nosso circuito começa a funcionar. A primeira coisa visível que o Arduino faz é apagar o LED verde e acender o LED vermelho.

//delay de 30 segundos até o sensor aquecer.
//na fase de testes recomendo diminuir o delay.
delay(30000);
digitalWrite(LEDRed,LOW);

Uma característica dos sensores semicondutores de gases é que eles precisam de um período de aquecimento. Isso é feito para que a superfície leitora atinja uma temperatura controlada, pois a temperatura afeta o resultado da leitura. Um fio de tungstênio aquele mesmo o sensor, cuidado ao encostar na parte gradeada.

Nosso programa gera uma pausa de 30.000 milissegundos, ou 30 segundos. Após isso ele apaga o LED vermelho.

for (jorge = 0; jorge <3; jorge +=1) {
 digitalWrite(LEDSinal, HIGH);
 delay(10);
 digitalWrite(LEDSinal, LOW);
 delay(10);
 }
}

Neste ponto indicamos ao usuário que a calibragem foi feita e o sensor já está pronto para fazer leituras. Um loop de 3 iterações repete código que aciona o LED verde, pausa 10 milissegundos, apaga o LED, pausa outros 10 e o ciclo se repete até a 3ª vez.

void pisca() {
 delay(20);
 digitalWrite(LEDSinal,HIGH);
 delay(20);
 digitalWrite(LEDSinal,LOW);
}

Uma função para piscar o LED verde a cada 20 milissegundos. ao invés de repetir esse código sempre que precisar piscar o LED, é só chamar por pisca(); no código.

void loop() {
 delay(10);
 sensor = analogRead(A0);

Começa o loop principal do programa. E já começa com uma pausa. Necessária? Não, mas o sim ficou melhor com ela. Em seguida a linha

 sensor = analogRead(A0);

O que ela faz é atribuir à variável sensor o valor, entre 0 e 1023 correspondendo ao sinal no pino analógico A0.

som = map(sensor ,10,50, 50,400);
 tone(8,som,(1/(sensor * 10)));
 pisca();
 delay(50);

}

Essa linha aqui é o pulo do gato:

som = map(sensor ,10,50, 50,400);

O comando map do C do Arduino é uma espécie de regra de três. Digamos que você tenha um mapa com distância em km, e uma régua com centímetros. Você sabe que a distância entre Rio e São Paulo é de 357,65 km. No seu mapa isso dá, digamos, 11 cm. Qual a distância entre Rio e Belo Horizonte?

Usando a régua você achou 12,4 cm. E isso em km?

A função map te retornaria isso. Você usaria o comando:

distancia = map (12.4, 0,11,0, 357.65)

Essa função recebe dois conjuntos lineares de números e escala um valor no primeiro conjunto retornando o equivalente no segundo.

No nosso caso eu digo que o conjunto de valores do sensor vai de 10 a 50, é uma forma de concentrar as leituras nas baixas concentrações de gás, mas o map aceita valores fora da faixa e isso zoneou um pouco o programa. Os parâmetros seguintes dizem para retornar um valor entre 50 e 400, a faixa de frequência do som que eu quero. Baixa.

O próximo comando é o que faz barulho:

 tone(buzz,som,(1/(sensor * 10)));

Aqui eu mando ele emitir na porta buzz um tom de frequência som, com duração de 1/10 vezes o valor original do sinal analógico convertido.

O processamento então cessa por 50 milissegundos, e o loop se reinicia. É feio mas funciona.

Só tem um problema: é irritante. Esqueça tudo que fizemos, vamos pensar em outra interface.

Eu lembrei dos detectores de radiação eletromagnética que os caçadores usam em Supernatural. Será que dá pra traduzir os valores do sensor MQ-4 para um sequencial de LEDs?
Spoiler: dá.

vlcsnap-00006

Mas isso é assunto para o próximo artigo.

DISCLAIMER: parte dos componentes deste projeto foram fornecidos pelos Baú da Eletrônica, como o Sensor de Gás MQ-4. Outros eu comprei, como o Kit Arduíno Start.

Leia também:

Relacionados: , , , , ,

Autor: Carlos Cardoso

Entusiasta de tecnologia, tiete de Sagan e Clarke, micreiro, hobbysta de eletrônica pré-pic, analista de sistemas e contínuo high-tech. Cardoso escreve sobre informática desde antes da Internet, tendo publicado mais de 10 livros cobrindo de PDAs e Flash até Linux. Divide seu tempo entre escrever para o MeioBIt e promover seus últimos best-sellers O Buraco da Beatriz e Calcinhas no Espaço.

Compartilhar

Aproveite nossos cupons de desconto:

Cupom de desconto Locaweb, Cupom de desconto HP, Cupom de desconto Descomplica, Cupom de desconto Nuuvem, Cupom de desconto CVC, Cupom de desconto Asus, Cupom de desconto World Tennis