Como fazer um Bafômetro com Arduino 47

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? Deixe seu comentário logo abaixo. Em caso de dúvidas, caso queira trocar uma ideia, ou até mesmo dividir seu projeto, acesse nosso Fórum!

Posts Relacionados

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

47 Comentários

  1. Legal, ele detecta outros gases?

    1. Bom dia Eduardo,

      Segundo o datasheet, somente álcool: https://www.pololu.com/file/0J310/MQ3.pdf

      Abraço

      Adilson- Equipe FILIPEFLOP

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

    obs: erro U8GLIB

    1. Olar , gostei bastante deste projeto , mais no momento de copilar ele da um erro na biblioteca ( #include “U8glib.h”) , o que poderia ser este problema , mesma pergunta de nosso amigo salomão zulaia , mostre-nos a solução por favor !!

      1. Boa tarde Arilson,

        Você instalou a biblioteca corretamente ?

        Abraço!

        Adilson – Equipe FILIPEFLOP

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

  4. 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

    1. 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

  5. Olá,

    Parabéns pelo blog.

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

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

    1. Boa tarde Vinicius,

      Estamos aguardando a chegada do display.

      Abraço.

      Adilson – Equipe FILIPEFLOP

  7. 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.

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

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

  10. 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);
    }
    }

    Luis Paulo Gomes da Cunha
  11. 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?

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

      1. qual erro o meu ta aparecendo isso:

        C:UsersDocumentsArduinolibrariesU8glibutilityu8g_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:UsersDocumentsArduinolibrariesU8glibutilityu8g_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.

      2. 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:UsersDocumentsArduinolibrariesU8glibutilityu8g_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:UsersDocumentsArduinolibrariesU8glibutilityu8g_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

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

      1. Ja resolvi alterando a inicializacao do display. para U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);

        1. Fiz a alteração (U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);
          e continua com erro, poderia me ajudar?
          Se possível enviar e-mail para giovani-meirelles@hotmail.com

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

      1. Está faltando importar a biblioteca da maneira correta.

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

    1. 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

      1. 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

    2. Você pode procurar por eeprom eh uma memoria do arduino. Assim o valor fica na eeprom e não eh removido ate que a eeprom seja limpa (isso so eh possível por código)

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

    1. Também quero saber a relação mG/l versus mV.

    2. Boa, também tenho esta dúvida, se puder ajudar.
      Gostaria desta informação para verificar a calibração do mesmo.

  14. 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

    GIOVANNA DE ALMEIDA SOUSA
    1. Bom dia Giovanna,

      Você pode adquirir todos os materiais na nossa loja: http://www.filipeflop.com

      – Placa Uno
      – Jumpers macho-macho
      – Protoboard 400 pontos
      – Sensor de álcool MQ-3
      – Display Oled Azul/Amarelo

      Abraço!

      Adilson – Equipe FILIPEFLOP

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

  16. 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

    1. Bom dia Vitor,

      Nós que agradecemos! 🙂

      Abraço.

      Adilson – Equipe FILIPEFLOP

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

  18. 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

  19. Existe algum sensor com uma precisão maior que esse? Se sim, onde comprar?

  20. Primeiramente gostei muito desse experimento e gostaria de parabenizar todos da equipe FILIPEFLOP!!
    estou com um problema e espero que vocês me ajudassem o meu display não esta ligando a programação esta certa só que o display não esta funcionando o que ha de errado?

  21. Olá ,
    Primeiramente parabéns pelo blog.
    O sensor que estou usando é um MQ-3 da Flying Fish, e o mesmo possui um trimpot na parte de traseira… Gostaria de saber como a regulagem desse resistor ajustável interfere na leitura da concentração.
    Desde já agradeço,
    ATT. Lucas

  22. Boa tarde.
    Gostaria de saber qual é a variação do sinal analógico, se de 0V ~ 5V ou menos ?
    Obrigado.

  23. O display não esta funcionando e não aparece mensagem de erro! Qual versão da biblioteca é a correta? Poderiam me enviar por email?

    lucasfreitas.contatos@gmail.com

  24. Boa tarde, comprei os materiais necessários com vcs, e ao implementar tudo, meu display não funcionou… o arduino está ok, o código compila normal, mas não aparece nada no display. Preciso de ajuda.

  25. é possível usar um oled SSD1306 de 7 pinos no lugar do de 4 pinos?
    Grato!

Trackbacks and Pingbacks

  1. […] informação do índice UV. Esse display é o mesmo que utilizamos recentemente no nosso projeto de Bafômetro com Arduino. A saída do módulo UV (pino OUT) será ligada ao pino analógico A0 do […]