24 setembro 2017

Monitore sua caixa dágua usando Arduino

E não só a caixa dágua, mas também tanques, reservatórios e aquários, usando o sensor de nível de água, um sensor do tipo bóia que é um sensor de funcionamento bem simples, como você vai ver nesse projeto de monitoramento.

Sensor de nível de agua com Arduino

Para entender melhor o funcionamento do sensor de nível de água, recomendo a leitura deste post aqui do Arduino e Cia.

Material necessário para o projeto


Para esse projeto você vai precisar do seguinte material:


O material mostrado acima será usado para a montagem da parte eletrônica do projeto. Se você pretende instalar isso na sua casa, vai precisar de outros materiais para fixar os sensores na caixa dágua, cabos para ligação dos sensores ao Arduino, caixa para proteção do circuito, etc.

O projeto de monitoramento de caixa dágua


Este projeto consiste em um Arduino Uno que vai efetuar a leitura dos sensores de nível de água, que são do tipo "bóia" e ficarão dentro do reservatório. Serão utilizados 3 sensores que, conforme o nível da água, vão enviar sinais para o microcontrolador, que por sua vez vai acionar um display LCD 16x2 I2C e mostrar o nível de água no reservatório.
Sensores posicionados em uma caixa dágua
Coloquei um relé no circuito, mas o uso é opcional, já que ele pode ser usado para ligar uma bomba que vai encher a caixa. O relé permanece desligado até que o nível da água atinja o ponto mais baixo (sensor 3), quando então ele é acionado, e permanece assim até que o nível do reservatório atinja o nível máximo (sensor 1).

Circuito monitoração de caixa dágua


O circuito abaixo mostra a ligação dos 3 sensores no Arduino Uno, conectados às portas 8, 9 e 10, com o relé conectado na porta 7.

O display utiliza interface I2C, e é ligado nas portas analógicas A4 (SDA) e A5 (SCL) do Arduino. Ele está "de lado" justamente para facilitar a visão do nível da água, representado pelos quadrados no lado direito do display.

Arduino Uno - LCD 16x2 e Sensor de nivel de água módulo relé

Os resistores usados nos sensores são de 10K, funcionando como resistores pull-down. Você não precisa usar necessariamente esses valores, ajuste de acordo com os resistores que tiver em mãos.

Programa monitoramento de caixa dágua


O programa usa a biblioteca LiquidCrystal_I2C (download), e você deve descompactar a biblioteca e colocá-la na pasta Libraries da IDE do Arduino. Atenção: Observe que esta biblioteca é diferente de outras LiquidCrystal_I2C que já usei aqui no Arduino e Cia, e foi escolhida por aceitar caracteres customizados, ok?

No código temos a inicialização do display e depois a leitura do estado dos sensores. Se houver alguma mudança, o nível do reservatório é atualizado, passando pelos níveis C (caixa cheia), M (nível médio) e V (caixa vazia).

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//Programa: Monitoracao de Caixa d´agua usando Arduino
//Autor: Arduino e Cia

//Display HD44780 com adaptador I2C
#include <Wire.h>
#include <hd44780.h> // include hd44780 library header file
#include <hd44780ioClass/hd44780_I2Cexp.h> // i/o expander/backpack class
hd44780_I2Cexp lcd; // auto detect backpack and pin mappings

#define pino_rele 7
#define sensor1 8
#define sensor2 9
#define sensor3 10

int valor_s1 = 1, valor_s2 = 1, valor_s3 = 1;

//Simbolos
uint8_t letra_C[8] = {0x0, 0xE, 0x11, 0x11, 0x11, 0x11, 0x0, 0x0};
uint8_t letra_M[8] = {0x0, 0x1F, 0x2, 0x4, 0x2, 0x1F, 0x0, 0x0};
uint8_t letra_v[8] = {0x0, 0x7, 0x8, 0x10, 0x8, 0x7 , 0x0, 0x0};
uint8_t caracter_nivel[8] = {0x0, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0};

int nivel_anterior = 0;

void setup()
{
  Serial.begin(9600);
  //Inicializa o display I2C
  lcd.begin(16, 2);
  //Caracteres customizados
  lcd.createChar(0, letra_C);
  lcd.createChar(1, letra_M);
  lcd.createChar(2, letra_v);
  lcd.createChar(3, caracter_nivel);

  //Define os pinos dos sensores como entrada
  pinMode(sensor1, INPUT);
  pinMode(sensor2, INPUT);
  pinMode(sensor3, INPUT);

  //Mostra a letra C no display
  lcd.setCursor(15, 0);
  lcd.write(uint8_t(0));
  //Mostra a letra M no display
  lcd.setCursor(8, 0);
  lcd.write(uint8_t(1));
  //Mostra a letra V no display
  lcd.setCursor(0, 0);
  lcd.write(uint8_t(2));

  Serial.println("Monitoracao de Caixa Dagua");
  Serial.println();
}

void loop()
{
  //Leitura dos sensores
  int valor_s1 = digitalRead(sensor1);
  int valor_s2 = digitalRead(sensor2);
  int valor_s3 = digitalRead(sensor3);

  //Mostra valor dos sensores no serial monitor
  Serial.print("S1: ");
  Serial.print(valor_s1);
  Serial.print(" S2: ");
  Serial.print(valor_s2);
  Serial.print(" S3: ");
  Serial.println(valor_s3);

  //Checa o nivel e atualiza o display
  if ((valor_s1 == 0) && valor_s2 == 0 && valor_s3 == 0)
  {
    //Atualiza o nivel no display, enviando o numero de
    //"quadrados" que devem ser mostrados para indicar
    //o nivel
    mostra_nivel(15);
    //Desliga o rele
    digitalWrite(pino_rele, HIGH);
  }

  if ((valor_s1 == 1) && valor_s2 == 0 && valor_s3 == 0)
  {
    //Atualiza o nivel no display
    mostra_nivel(11);
  }

  if ((valor_s1 == 1) && valor_s2 == 1 && valor_s3 == 0)
  {
    //Atualiza o nivel no display
    mostra_nivel(4);
  }

  if ((valor_s1 == 1) && valor_s2 == 1 && valor_s3 == 1)
  {
    mostra_nivel(0);
    //Liga o rele
    digitalWrite(pino_rele, LOW);
  }
  delay(100);
}

void mostra_nivel(int nivel)
{
  if (nivel != nivel_anterior)
  {
    //Apaga informacao anterior
    lcd.setCursor(0, 1);
    lcd.print("                ");
    //Atualiza o nivel no display
    for (int i = 0; i <= nivel; i++)
    {
      lcd.setCursor(i, 1);
      lcd.write(uint8_t(3));
    }
    nivel_anterior = nivel;
  }
}

Na imagem abaixo, temos a saída de mensagens no serial monitor, onde você pode acompanhar o estado de cada um dos sensores e também incluir mensagens para o seu próprio controle:

Saída sensores Serial Monitor

Você pode expandir facilmente esse projeto, se precisar utilizar mais sensores, e também pode incrementá-lo adicionando funcionalidades como envio de avisos via Wifi, SMS, MQTT e outros.

23 comentários:

  1. boa tarde, como faco para ter as bioas no telhado do predio e o monitor na portaria>

    ResponderExcluir
  2. Pode me ajudar a subtituir o rele por um BUZZER e um botao para silenciar o buzzer por 5 min (se a caixa encher ele nao toca, se nao, ele toca novamente em 5 min)

    ResponderExcluir
  3. falta

    pinMode(pino_rele, OUTPUT);

    ResponderExcluir
  4. Boa noite, estou com um problema na programação do arduino, agradecia que me pudessem ajudar, obrigado.

    C:\Users\filho leonel\Documents\Arduino\sketch_jan14a\sketch_jan14a.ino:7:60: fatal error: hd44780.h: No such file or directory

    #include // include hd44780 library header file

    ^

    compilation terminated.

    exit status 1
    Erro ao compilar para a placa Arduino/Genuino Uno.

    ResponderExcluir
    Respostas
    1. Oi David,

      Esse arquivo hd44780.h está incluído na biblioteca. Você baixou a biblioteca do link do post?

      Abraço!

      Adilson

      Excluir
    2. Boa noite,sim baixei a biblioteca e coloquei no programa mas continuava a dar erro, mas agora já resolvi o problema, bastou instalar/atualizar uma biblioteca.
      Obrigado na mesma, abraço.

      Excluir
    3. david costa qual foi a biblioteca que vc atualizou

      Excluir
    4. a biblioteca disponilizada aqui neste projeto, LiquidCrystal_I2C

      Excluir
    5. Ola pessoal, Sou Heron, baixei o arquivo acima coloquei no diretório libraries e instalei mas dah esse aviso de erro. pra piorar diz que preciso ir no menu "Arquivo -> Preferências" e no IDE do Arduino no meu mac nao tem assa opção nesse menu e em nenhum outro menu aqui... desde ja agradeço se alguém puder me dar uma dica... valeu!

      Arduino: 1.8.5 (Mac OS X), Placa:"Arduino/Genuino Uno"

      /Users/meunome/Documents/Arduino/Monitoracao_de_Caixa_d_agua/Monitoracao_de_Caixa_d_agua.ino/Monitoracao_de_Caixa_d_agua.ino.ino:6:60: fatal error: hd44780.h: No such file or directory
      #include // include hd44780 library header file
      ^
      compilation terminated.
      exit status 1
      Erro compilando para a placa Arduino/Genuino Uno

      Este relatório teria mais informações com
      "Mostrar a saida detalhada durante a compilação"
      opção pode ser ativada em "Arquivo -> Preferências"

      Excluir
  5. Boa noite, adicionei um led ao circuito, em que acende quando o deposito ta vazio e apaga quando ta cheio, e tudo funciona bem, mas o led da pouca luz, quase nem se vê. Agradecia se me pudesse ajudar.

    ResponderExcluir
    Respostas
    1. Bom dia David,

      Nesse caso, você pode tentar colocar uma resistência menor (se o led permitir), ou então mudar para um led de alto brilho.

      Abraço!

      Adilson

      Excluir
  6. Bom dia, como posso colocar esses sensores no fritzing?

    ResponderExcluir
  7. Arduino: 1.8.4 (Windows 7), Placa:"Arduino/Genuino Uno"

    C:\Users\Novo User\Documents\Arduino\arduino_3_boias_arduino_cia\arduino_3_boias_arduino_cia.ino:6:60: fatal error: hd44780.h: No such file or directory

    #include // include hd44780 library header file

    ^

    compilation terminated.

    exit status 1
    Erro compilando para a placa Arduino/Genuino Uno

    Esta ocorrendo esse erro baixei a biblioteca do link se alguém puder ajudar

    ResponderExcluir
    Respostas
    1. Tem de ir a instalar bibliotecas, no programa arduino e instalar as bibliotecas associadas a este projeto

      Excluir
  8. Ótimo post, estou tentando desenvolver junto com o envio do comando para ligar a bomba por RF 433mhz, o RF estou usando seu exemplo postado no seu site.
    Mas estou com problema para resolver com os sinais do sensor que ficará emitindo 5v e a bomba liga e desliga.

    ResponderExcluir
  9. Consegui pessoal, obrigado por compartilhar o projeto! Abraço a todos.

    ResponderExcluir
    Respostas
    1. Boa tarde,

      Muito obrigado! Aguardo a sua visita no Arduino e Cia sempre que possível e se for do seu interesse, assine a nossa newsletter para receber as novidades em primeira mão. :)

      Abraço!

      Adilson

      Excluir
  10. Olá, boa tarde. Gostaria de saber como foi feita a ligação do display lcd?

    ResponderExcluir
    Respostas
    1. Oi Ariane,

      O display é do tipo que tem uma interface I2C, assim a comunicação com o Arduino usa somente 2 pinos. :)

      Abraço!

      Adilson

      Excluir
  11. O Meu Funcionou Perfeitamente , mais eu gostaria de Colocar mais um sensor que seria o quarto sensor e também gostaria de acrescentar o BUZZER no circuito , mais o rele continua

    ResponderExcluir
  12. Olá, ficaria muito grato se disponibilizasse o arquivo do sensor nível de água no formato fritzing. Estou desenhando o circuito e gostaria de adicionar o sensor nível de água, só que não encontrei na internet.

    ResponderExcluir
    Respostas
    1. Oi Gilvan,

      Infelizmente não tenho. Tive que desenhar o sensor separadamente.

      Abraço!

      Adilson

      Excluir
  13. Boa Noite Estou tentando alterar a programação para 4 sensores mais estou com dificuldades na programação alguém pode ajudar por favor


    //Programa: Monitoracao de Caixa d´agua usando Arduino
    //Autor: Arduino e Cia

    //Display HD44780 com adaptador I2C
    #include
    #include // include hd44780 library header file
    #include // i/o expander/backpack class
    hd44780_I2Cexp lcd; // auto detect backpack and pin mappings

    #define pino_rele 7
    #define sensor1 8
    #define sensor2 9
    #define sensor3 10
    #define sensor4 11
    #define pino_buzzer 12

    int valor_s1 = 1, valor_s2 = 1, valor_s3 = 1, valor_s4 = 1;

    //Simbolos
    uint8_t letra_C[8] = {0x0, 0xE, 0x11, 0x11, 0x11, 0x11, 0x0, 0x0};
    uint8_t letra_M[8] = {0x0, 0x1F, 0x2, 0x4, 0x2, 0x1F, 0x0, 0x0};
    uint8_t letra_v[8] = {0x0, 0x7, 0x8, 0x10, 0x8, 0x7 , 0x0, 0x0};
    uint8_t caracter_nivel[8] = {0x0, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0};

    int nivel_anterior = 0;

    void setup()
    {
    Serial.begin(9600);
    //Inicializa o display I2C
    lcd.begin(16, 2);
    //Caracteres customizados
    lcd.createChar(0, letra_C);
    lcd.createChar(1, letra_M);
    lcd.createChar(2, letra_v);
    lcd.createChar(3, caracter_nivel);

    //Define os pinos dos sensores como entrada
    pinMode(sensor1, INPUT);
    pinMode(sensor2, INPUT);
    pinMode(sensor3, INPUT);
    pinMode(sensor4, INPUT);
    pinMode(pino_rele, OUTPUT);

    //Mostra a letra C no display
    lcd.setCursor(15, 0);
    lcd.write(uint8_t(0));
    //Mostra a letra M no display
    lcd.setCursor(8, 0);
    lcd.write(uint8_t(1));
    //Mostra a letra V no display
    lcd.setCursor(0, 0);
    lcd.write(uint8_t(2));


    Serial.println("Monitoracao de Caixa Dagua");
    Serial.println();
    }

    void loop()
    {
    //Leitura dos sensores
    int valor_s1 = digitalRead(sensor1);
    int valor_s2 = digitalRead(sensor2);
    int valor_s3 = digitalRead(sensor3);
    int valor_s4 = digitalRead(sensor4);

    //Mostra valor dos sensores no serial monitor
    Serial.print("S1: ");
    Serial.print(valor_s1);
    Serial.print(" S2: ");
    Serial.print(valor_s2);
    Serial.print(" S3: ");
    Serial.println(valor_s3);
    Serial.print(" S4: ");
    Serial.println(valor_s4);

    //Checa o nivel e atualiza o display
    if ((valor_s1 == 1) && valor_s2 == 1 && valor_s3 == 1 && valor_s4 == 1)
    {
    //Atualiza o nivel no display, enviando o numero de
    //"quadrados" que devem ser mostrados para indicar
    //o nivel
    mostra_nivel(15);
    //Desliga o rele
    digitalWrite(pino_rele, LOW);
    //lcd.setBacklight(HIGH);
    //delay(10);
    }

    if ((valor_s1 == 0) && valor_s2 == 1 && valor_s3 == 1 && valor_s4 == 1)
    {
    //Atualiza o nivel no display
    mostra_nivel(11);
    }

    if ((valor_s1 == 0) && valor_s2 == 0 && valor_s3 == 1 && valor_s4 == 1)
    {
    //Atualiza o nivel no display
    mostra_nivel(7);
    }

    if ((valor_s1 == 0) && valor_s2 == 0 && valor_s3 == 0 && valor_s4 == 1)
    {
    //Atualiza o nivel no display
    mostra_nivel(4);
    }

    if ((valor_s1 == 0) && valor_s2 == 0 && valor_s3 == 0 && valor_s4 == 0)
    {
    mostra_nivel(0);
    //Liga o rele
    digitalWrite(pino_rele, HIGH);
    // lcd.setBacklight(LOW);
    //delay(10);
    }
    delay(100);
    }

    void mostra_nivel(int nivel)
    {
    if (nivel != nivel_anterior)
    {
    //Apaga informacao anterior
    lcd.setCursor(0, 1);
    lcd.print(" ");
    //Atualiza o nivel no display
    for (int i = 0; i <= nivel; i++)
    {
    lcd.setCursor(i, 1);
    lcd.write(uint8_t(3));
    }
    nivel_anterior = nivel;
    }
    }

    ResponderExcluir