Como fazer um Bafômetro com Arduino

Como fazer um Bafômetro com Arduino

Neste post vamos ver como montar um Bafômetro com Arduino e um sensor de gás MQ-3 álcool, um dispositivo de fácil conexão e capaz de detectar entre 10 e 10.000 ppm (partes por milhão) de álcool.

Bafômetro com Arduino e Sensor de Gás MQ-3

Esse sensor funciona por meio de uma reação química, necessitando de um tempo de aquecimento (5 minutos) para entrar em operação e começar a detectar o vapor de álcool. Quando a concentração de álcool fica acima do nível ajustado pelo potenciômetro, a saída digital DOUT fica em estado alto, acionando também o led do módulo.

Módulo MQ-3 - Detalhes pinos

Para acompanhar com um pouco mais de precisão os dados do sensor, pode ser utilizada a saída AOUT, ligada em uma entrada analógica do microcontrolador. No nosso projeto de bafômetro, vamos utilizar o pino AOUT para mostrar os diferentes níveis de álcool detectados pelo sensor MQ-3.

Observe que este é um projeto que deve ser utilizado somente para fins experimentais e educacionais.

Ligação do módulo MQ-3 ao Arduino

Os dados do nosso bafômetro serão mostrados em um display gráfico OLED 128×64, utilizando a mesma ligação via interface I2C e biblioteca que usamos no post Como conectar o display OLED ao Arduino. Já o pino AOUT do sensor MQ-3 será ligado à porta analógica A1 do Arduino.

Circuito Arduino Oled e MQ3

Programa e biblioteca u8glib

No display será mostrado o valor lido da porta analógica A1, e no rodapé da tela uma mensagem correspondente ao nível de álcool detectado pelo sensor. A biblioteca gráfica do display é a u8glib, disponível neste link. É com essa biblioteca que alteramos o tamanho e tipo da fonte, desenhamos linhas, retângulos, curvas, etc.

Como mencionamos anteriormente, esse sensor precisa de um tempo para aquecimento, por volta de 5 minutos, e definimos esse valor na linha 9 do programa utilizando a variável tempo_aquecimento, com o valor em segundos (300 segundos = 5 minutos).

Entre as linhas 108 e 128 você pode alterar os valores de teste da variável valor_sensor, que é utilizado para mostrar as mensagens no display.

// Programa: Bafometro com Arduino
// Autor: FILIPEFLOP

#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);

// Tempo de aquecimento
int tempo_aquecimento = 300;
int valor_sensor = 0;
unsigned long time;
int status = 1;
String estado;
int posicao1;

void draw()
{
  // Comandos graficos para o display devem ser colocados aqui
  // Seleciona a fonte de texto
  u8g.setFont(u8g_font_8x13B);
  // Mensagens iniciais
  u8g.drawRFrame(0, 18, 128, 46, 4);
  u8g.drawStr( 30, 15, "BAFOMETRO");
  u8g.drawStr( 10, 37, "Aguarde");

  // Animacao caneca
  if (status == 1)
  {
    u8g.drawBox(80, 25, 20, 30);
    u8g.drawHLine(77, 24, 26);
    u8g.drawRFrame(78, 25 , 24, 32, 0);
    u8g.drawRFrame(77, 25 , 26, 32, 0);
    u8g.drawHLine(76, 57, 28);
    u8g.drawHLine(76, 58, 28);
    u8g.drawRFrame(102, 30 , 7, 20, 2);
    u8g.drawRFrame(102, 28 , 9, 24, 2);
    u8g.setColorIndex(0);
    if (time == 0)
    {
      time = 1;
    }
    u8g.drawBox(79, 25, 22, time);
    u8g.setColorIndex(1);
  }

  // Apos o aquecimento, exibe dados do sensor
  if (status == 0)
  {
    u8g.setFont(u8g_font_fub20);
    u8g.setColorIndex(0);
    u8g.drawBox(10, 25, 110, 33);
    u8g.setColorIndex(1);
    // Centraliza o valor na tela
    if (valor_sensor <= 99)
    {
      posicao1 = 50;
    }
    else
    {
      posicao1 = 43;
    }
    // Mostra valor do sensor
    u8g.setPrintPos(posicao1, 45);
    u8g.print(valor_sensor);
    u8g.setFont(u8g_font_ncenB08);
    // Imprime mensagem no rodape
    int tamanho = estado.length();
    int posicao = (128 / 2 - 3) - ((tamanho * 5) / 2);
    u8g.setPrintPos(posicao, 60);
    u8g.print(estado);
  }
}

void setup(void)
{
  Serial.begin(9600);
  pinMode(A1, INPUT);
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255, 255, 255);
  }
}

void loop(void)
{
  // Leitura do valor do sensor
  valor_sensor = analogRead(A1);
  time = millis() / 1000;
  u8g.firstPage();
  // Tempo de aquecimento
  if (time <= tempo_aquecimento)
  {
    time = map(time, 0, tempo_aquecimento, 0, 30);
    status = 1;
  }
  else
  {
    status = 0;
  }
  // Mensagem rodape
  if (valor_sensor >= 0 and valor_sensor <= 50)
  {
    estado = "Voce nao bebeu...";
  }
  else if (valor_sensor >= 51 and valor_sensor <= 200)
  {
    estado = "Bebeu 1 cerveja ?";
  }
  else if (valor_sensor >= 201 and valor_sensor <= 400)
  {
    estado = "Bebeu 2 cervejas ?";
  }
  else if (valor_sensor >= 401 and valor_sensor <= 600)
  {
    estado = "Voce cheira a 51 !";
  }
  else if (valor_sensor >= 601)
  {
    estado = "Voce esta bebado !!";
  }

  // Chama a rotina de desenho na tela
  do
  {
    draw();
  }
  while ( u8g.nextPage() );

  delay(50);
}

O programa inicialmente mostra uma pequena animação enquanto aguarda o tempo de aquecimento. Depois disso, passa a mostrar os valores lidos da porta analógica. A leitura do nível de álcool é geralmente feita de forma rápida, mas é normal que o sensor demore um tempo para voltar aos valores iniciais.

Gostou? Ajude-nos a melhorar o blog atribuindo uma nota a este tutorial (estrelas no final do artigo) e visite nossa loja FILIPEFLOP!

3
Como fazer um Bafômetro com Arduino
34 votos, 4.74 classificação média (94% pontuação)

Formado em Ciência da Computação pela Universidade de Mogi das Cruzes, atualmente responsável pelo departamento técnico da FILIPEFLOP.

Compartilhe este Post

38 Comentários

  1. Raimundo delogo - 29 de janeiro de 2017

    boa tarde
    Teria com estabilizar para zero?
    E colocar uma porta como saída analógica no Arduíno quando o valor for mair que zero 5vcc?
    pode me ajudar

  2. bruno - 12 de dezembro de 2016

    gostaria de saber com inserir a biblioteca U8GLIB no programa sou relativamente novo e não sei como se faz

  3. Vitor F. Thomé - 7 de dezembro de 2016

    Implementei o projeto de vocês para a matéria de transdutores com a professora Daniela Suziki da UFSC!
    Sou graduando de engenharia eletrônica e agradeço pelos posts precisos e úteis do blog.
    Vídeo do projeto: https://www.youtube.com/watch?v=oTZowT13zJQ&t=4s

  4. alisson - 22 de novembro de 2016

    o que acontece caso pouco ar seja expelido? tem como colocar algum tipo de aviso ou algo do tipo??

  5. GIOVANNA DE ALMEIDA SOUSA - 14 de setembro de 2016

    Bom Dia,
    Gostaria de que me enviasse um orçamento total do projeto de Bafômetro com Arduíno, incluindo o nome dos materiais necessários.
    ATT
    Giovanna

  6. hugo - 4 de junho de 2016

    Poderiam me informar qual a relação de Volts para mg/L desse sensor?

  7. Neudivan - 17 de maio de 2016

    Como deixar o medidor já marcando zero, e fixar o número mais alto depois de assoprar?

    • Adilson Thomsen - 17 de maio de 2016

      Boa tarde Neudivan,

      O sensor de álcool precisa de pelo menos 15 minutos de “aquecimento”, e o número que ele mostra depois desse tempo costuma variar um pouco, mas nada impede que você espere esses 15 minutos e depois zere a variável para ficar do jeito que você precisa.

      Abraço!

      Adilson – Equipe FILIPEFLOP

      • Adilson Thomsen - 25 de maio de 2016

        Boa tarde,

        Não consegui reproduzir o erro aqui. Usei um Arduino Mega + Oled + IDE versão 1.6.8, rodando o exemplo do post. Funcionou normalmente.

        Sua biblioteca está completa ?

        Abraço!

        Adilson – Equipe FILIPEFLOP

  8. leonardo - 19 de abril de 2016

    Estou iniciando no arduino, e apenas copiei e colei o programa, e esta aparecendo que a linha que determina o tipo de display ( adquirido com voces) U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);does not match.
    Poderia me ajudar?

    • leonardo - 19 de abril de 2016

      Pode deixar amigo, ja achei um erro que cometi com a biblioteca. Valeu.

      • Estudante - 25 de maio de 2016

        qual erro o meu ta aparecendo isso:

        C:\Users\Documents\Arduino\libraries\U8glib\utility\u8g_rot.c:48:1: warning: initialization from incompatible pointer type [enabled by default]

        u8g_dev_t u8g_dev_rot = { u8g_dev_rot_dummy_fn, NULL, NULL };

        ^

        C:\Users\Documents\Arduino\libraries\U8glib\utility\u8g_rot.c:48:1: warning: (near initialization for ‘u8g_dev_rot.dev_fn’) [enabled by default]

        O sketch usa 24.090 bytes (9%) de espaço de armazenamento para programas. O máximo são 253.952 bytes.
        Variáveis globais usam 551 bytes (6%) de memória dinâmica, deixando 7.641 bytes para variáveis locais. O máximo são 8.192 bytes.

      • Estudante - 25 de maio de 2016

        Caro amigo parabéns pelo blog preciso de uma ajuda tenho que fazer um projeto identico a este, mas não estou conseguindo falta alguma coisa pode me ajudar?
        estou com arduino mega 2560
        display OLED 0.96″12C Azul Amarelo
        sensor MQ-3 alcool

        me ajude!!!

        copiei e colei sua programação e quando faço upload aparece a seguinte mensagem:

        C:\Users\Documents\Arduino\libraries\U8glib\utility\u8g_rot.c:48:1: warning: initialization from incompatible pointer type [enabled by default]

        u8g_dev_t u8g_dev_rot = { u8g_dev_rot_dummy_fn, NULL, NULL };

        ^

        C:\Users\Documents\Arduino\libraries\U8glib\utility\u8g_rot.c:48:1: warning: (near initialization for ‘u8g_dev_rot.dev_fn’) [enabled by default]

        O sketch usa 24.090 bytes (9%) de espaço de armazenamento para programas. O máximo são 253.952 bytes.
        Variáveis globais usam 551 bytes (6%) de memória dinâmica, deixando 7.641 bytes para variáveis locais. O máximo são 8.192 bytes.

        daí não roda nada, o arduino acende os leds de alimentação e mais nada

    • Rafael Nunes - 9 de maio de 2016

      Qual era o erro amigo? estou com o mesmo problema..

    • Leticia Sugayama - 11 de junho de 2016

      O meu tbm esta dando esse erro. Vc pode me ajudar?

  9. Luis Paulo Gomes da Cunha - 18 de abril de 2016

    Poderia explicar o que cada uma dessas linhas estão fazendo, não está muito claro. Grato
    void setup(void)
    {
    Serial.begin(9600);
    pinMode(A1, INPUT);
    if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255); // white
    }
    else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3); // max intensity
    }
    else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1); // pixel on
    }
    else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255, 255, 255);
    }
    }

  10. juan pablo - 13 de abril de 2016

    Bacana, voce saberia como fazer pra mostrar fazer isso com o display 16×2

  11. Guilherme - 22 de dezembro de 2015

    Olá, obrigado pelo tutorial,
    como modifico o código pra fazer funcionar com um display OLED 1,3″?
    Obrigado

  12. Rodolpho - 1 de dezembro de 2015

    Comprei o display com voces , porem os pinos vcc e gnd estão invertidos, com relaçao ao do exemplo no video, e está ocorrendo de nao aparecer nada no display, estou usando o arduino mega . Ajudas urgente por favor.

  13. Vinicius - 21 de novembro de 2015

    muito legal, mas e o display oled? nao achei vendendo.

  14. Diego Sousa - 8 de outubro de 2015

    Olá,

    Parabéns pelo blog.

    Como consigo o componente MQ-3 para usar no Fritzing? Não encontrei-o na paleta de componentes.
    Valeu!

  15. Mauricio - 30 de setembro de 2015

    Olá.

    Antes de mais nada, parabéns pelo blog.

    Uma dúvida: esse e outros sensores “MQ”, segundo o datasheet, tem 2 características que fazem com que usá-los não seja tão “plug and play”:

    1. eles precisam de um pré-aquecimento demorado antes de serem usados (no datasheet aparece como “Preheat time: over 48 hours”);

    2. em quase todos eles existe uma tensão para mantê-los aquecido e uma tensão para fazer a leitura (vide o MQ-7, que é o que estou trabalhando no momento, e que pede 5V para aquecimento e 1,4V para leitura).

    Minha questão é sobre esses módulos onde os sensores MQ já vem grudados em uma plaquinha com 4 pinos:

    1. eles precisam desse “preheat time” antes de serem usados?

    2. parece que, devido ao número de pinos, não é possível fazer com que trabalhem com essas 2 tensões indicadas no datasheet. Será que isso pode trazer algum problema com relação a precisão na leitura?

    Abraços,
    Mauricio de O. Pena

    • FILIPEFLOP - 1 de outubro de 2015

      Boa tarde Maurício,

      Sim, eles precisam desse tempo de aquecimento. No caso do bafômetro, o programa aguarda alguns minutos antes de realizar a leitura justamente por causa disso.

      Quanto à precisão na leitura, não temos informações sobre isso, já que o fabricante não fornece nenhuma indicação de que o moódulo aumenta ou diminui a tensão automaticamente depois de um certo tempo (de aquecimento).

      Abraço e obrigado!

      Adilson – Equipe FILIPEFLOP

  16. Fabrício - 30 de setembro de 2015

    Muito legal! Gostaria de saber se vocês conhecem algum simulador que possua essa OLED 128X64, valeu!

  17. salomão zulaia - 21 de agosto de 2015

    felipe muito bom seu projeto, mas estou com duvida no codigo fonte, pois não conseguir copilar no programa.

    obs: erro U8GLIB

  18. Eduardo - 17 de agosto de 2015

    Legal, ele detecta outros gases?

Deixe uma resposta