Sensor de Umidade Capacitivo com Arduino

sensor-de-umidade-capacitivo-com-arduino
Font Size

Diversos sistemas de agricultura necessitam de sensores para medir a umidade do solo. Nesse artigo, apresentaremos como criar um sistema de alarme de baixa umidade com Arduino e o sensor capacitivo de umidade. A seguir, apresentamos o circuito do projeto na Figura 1.

Figura 1 – Circuito do sensor de umidade capacitivo na planta.

Por meio desse projeto, apresentaremos várias etapas que te permitirão aprender a utilizar o sensor de umidade capacitivo.

Portanto, por meio desse sistema, apresentaremos como realizar a configuração, calibração e monitoramento da umidade em tempo real.

A seguir, apresentaremos passo a passo como desenvolver este projeto.

Desenvolvimento do Alarme com Sensor de Umidade Capacitivo e Arduino

No sistema a seguir, apresentamos a estrutura do circuito na Figura 2.

Figura 2 – Circuito do Sensor de Umidade Capacitivo

Portanto, por meio do sistema apresentado na Figura 2, o usuário será avisado quando ocorrer alterações no valor de umidade. Desse modo, o usuário será alertado e deverá irrigar a planta para manter o solo em níveis adequados de umidade.

Na Figura 2, o LED será acionado quando ocorrer alterações na umidade. De forma ilustrativa, estamos utilizando um sensor de umidade resistivo.

A seguir, disponibilizamos toda a lista de componentes eletrônicos utilizados nesse projeto.

Lista de Componentes do Projeto

Por fim, você pode adquirir todos os produtos em nossa loja Autocore Robótica e montar o seu projeto.

Lógica de Desenvolvimento do Projeto do Sensor de Umidade Capacitivo com Arduino

A princípio, apresentamos a estrutura completa do código e, a seguir, iniciaremos a discussão da lógica para o projeto.

<code>#include &lt;LiquidCrystal.h&gt;
#include &lt;EEPROM.h&gt;

#define sensor A0
#define botaoOK 11
#define BotaoInc 12
#define BotaoDec 9

bool LCDControl = 0, BaixaUmid = 0, AltaUmid = 0, ConfirmaAnterior = 0, Incremento = 0, IncrementoAnterior = 0;
bool Decremento = 0, DecrementoAnterior = 0;

byte UmidadePercent = 0, umidade = 0, ValorAnterior = 0, VerifCalib = 0, UmidadeAjuste = 0;
byte MaxCalib = 0;

signed char AlarmeUmidade = 0;
 
int ValUmidade = 0, ValorAnalog = 0, UmidadeMap = 0;
long int UmidadeCalib = 0, tempo_atual = 0, ultimo_tempo = 0, ultimo_tempo2 = 0;

#define VALORCALIB 130
#define SINALCALIB 131
#define UMIDADEAJUSTADA 132

const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void CalibraSensor();
void UmidadeAlarme();

void setup()
{
  Serial.begin(9600);
  lcd.begin(16,2);
  
  pinMode(sensor, INPUT);
  pinMode(13, OUTPUT);
  
  lcd.clear();
  
  ValorAnterior = analogRead(sensor);
  
  VerifCalib = EEPROM.read(SINALCALIB);
  UmidadeAjuste = EEPROM.read(UMIDADEAJUSTADA);
  
  if(VerifCalib != 73)
  {
    CalibraSensor();
    lcd.clear();
    UmidadeAlarme();
    
    EEPROM.write(SINALCALIB, 73);
  }

  MaxCalib = EEPROM.read(VALORCALIB);

}
 
bool control = 0;

void loop()
{
  
  tempo_atual = millis();
  
  //Le o valor do pino A0 do sensor
  ValorAnalog = analogRead(sensor);
  
  byte AjustAnalog = map(ValorAnalog, 0, 1023, 0, 255);

  if(AjustAnalog &gt;= MaxCalib)
  {
    AjustAnalog = MaxCalib;  
  }
  
  UmidadePercent = map(AjustAnalog, 0, MaxCalib, 0, 100);
  delay(2000);
    
    lcd.clear();
    lcd.setCursor(3,0);
    lcd.print("Umidade:");
    lcd.setCursor(12,0);
    lcd.print(UmidadePercent);
    lcd.print("%");
  
  if(UmidadePercent &gt;= UmidadeAjuste)
  {
    digitalWrite(13, HIGH);
    
    lcd.setCursor(1,1);
    lcd.print("Baixa Umidade");
  }
  
  if(UmidadePercent &lt; UmidadeAjuste)
  {
    digitalWrite(13, LOW);

    lcd.setCursor(2,1);
    lcd.print("Alta Umidade");
  }

  byte Parametrizar = digitalRead(BotaoDec);

  if(Parametrizar == 0)
  {
    ultimo_tempo = tempo_atual;  
  }
  
  if(Parametrizar == 1 &amp;&amp; (tempo_atual - ultimo_tempo &gt; 4000))
  {
    for(byte endereco = 130; endereco &lt; 133; endereco++)
    {
      EEPROM.write(endereco, 0);
    }

    CalibraSensor();
    EEPROM.write(SINALCALIB, 73);
    UmidadeAlarme();
    
    UmidadeAjuste = EEPROM.read(UMIDADEAJUSTADA);
    MaxCalib = EEPROM.read(VALORCALIB);
  }

    byte ConfigUmidade = digitalRead(BotaoInc);

  if(ConfigUmidade == 0)
  {
    ultimo_tempo2 = tempo_atual;  
  }
  
  if(ConfigUmidade == 1 &amp;&amp; (tempo_atual - ultimo_tempo2 &gt; 3000))
  {
    UmidadeAlarme();
    UmidadeAjuste = EEPROM.read(UMIDADEAJUSTADA);
  }
  
}

void CalibraSensor()
{
    bool confirma = 0;
    byte cont = 0;
    
    lcd.clear();

    lcd.setCursor(0,0);
    lcd.print("Insira o sensor");
    
    lcd.setCursor(0,1);
    lcd.print("e confirme:");

    do
    {
      confirma = digitalRead(botaoOK);    
    }while(confirma == 0);

      do
      {
        long int ValAnalog = analogRead(A0);  
        byte AjustAnalog = map(ValAnalog, 0, 1023, 0, 255);
        
        UmidadeCalib = AjustAnalog + UmidadeCalib;
        cont++;
        
      }while(cont &lt; 10);

      lcd.clear();
      
      lcd.setCursor(5,0);
      lcd.print("Fim da");
      
      lcd.setCursor(3,1);
      lcd.print("Calibracao");

      delay(15000);
      lcd.clear();
      
      byte ValorCalibrado = UmidadeCalib/10;      
      EEPROM.write(VALORCALIB, ValorCalibrado);

}

void UmidadeAlarme()
{
  bool BotaoEnter = 0;
  byte ajuste = 0;
  byte ValorAnt = 0;
  
  lcd.clear();  
  lcd.setCursor(0,0);
  lcd.print("Ajustar Umidade:");
  lcd.setCursor(7,1);
  
  lcd.print(ajuste);
  
  do
  {
      Incremento = digitalRead(BotaoInc);
      Decremento = digitalRead(BotaoDec);
      
      if(Incremento == 1 &amp;&amp; IncrementoAnterior == 0)
      {
        AlarmeUmidade++;
        IncrementoAnterior = 1;
      }
    
      if(Incremento == 0 &amp;&amp; IncrementoAnterior == 1)
      {
        IncrementoAnterior = 0;
      }
    
      if(Decremento == 1 &amp;&amp; DecrementoAnterior == 0)
      {
        AlarmeUmidade--;
        DecrementoAnterior = 1;
      }
    
      if(Decremento == 0 &amp;&amp; DecrementoAnterior == 1)
      {
        DecrementoAnterior = 0;
      }

      if(AlarmeUmidade &gt; 100)
      {
        AlarmeUmidade = 100;  
      }

      if(AlarmeUmidade &lt; 0)
      {
        AlarmeUmidade = 0;  
      }
      delay(100);
      
      if(AlarmeUmidade != ValorAnt)
      {
        lcd.clear();
        
        lcd.setCursor(0,0);
        lcd.print("Ajustar Umidade:");
        lcd.setCursor(7,1);
        lcd.print(AlarmeUmidade);
        
        ValorAnt = AlarmeUmidade;      
      }

      BotaoEnter = digitalRead(botaoOK);
      
  }while(BotaoEnter != 1);

      EEPROM.write(UMIDADEAJUSTADA, AlarmeUmidade);
      
      return;
}</code>

Inicialmente, uma função foi criada para forçar o usuário configurar os parâmetros na inicialização. Portanto, o dispositivo será ligado e o usuário deverá configurá-lo durante a primeira vez que for iniciado. É sempre importante realizar a limpeza(zerar) de toda a memória EEPROM, antes de gravar o código no sistema.

Dessa maneira, o sistema verificará se o valor da posição SINALCALIB na EEPROM é diferente de 73. Caso o valor seja diferente, o sistema chamará as funções CalibraSensor e UmidadeAlarme.

Em resumo, o valor 73 é utilizado para sinalizar que o sistema já foi calibrado. Portanto, como o valor será 0 na primeira execução, o sistema chamará as duas funções.

Desse modo, o sistema irá calibrar o sensor e, em seguida, configurar o nível para alarme de baixa umidade, conforme apresentado na condição abaixo.

 

Após a calibração e configuração da umidade, o sistema escreverá o valor 73 na posição SINALCALIB, para sinalizar que o sistema está com o sensor calibrado.

<code>if(VerifCalib != 73)
  {
    CalibraSensor();
    lcd.clear();
    UmidadeAlarme();
    
    EEPROM.write(SINALCALIB, 73);
  }</code>

A seguir, serão apresentados os códigos implementados nas funções de CalibraSensor e UmidadeAlarme.

Funções CalibraSensor e UmidadeAlarme

A fim de criar um sistema de medição de umidade capaz de se ajustar às necessidades do usuário, foram desenvolvidas duas funções.

Primeiramente, vamos apresentar a implementação da função CalibraSensor.

Implementação da Função CalibraSensor

Por meio desta função, o usuário deverá espetar o sensor na terra seca e realizar o processo de calibração.

Em seguida, o usuário deverá confirmar e o sistema iniciará a calibração. Após isto, uma mensagem será apresentada, a fim de indicar a ocorrência do processo, conforme apresentada na Figura 3.

Figura 3 – Tela de Confirmação de Instalação do Sensor de Umidade Capacitivo.

A seguir, o sistema irá realizar 10 medidas do sensor. Em seguida, calculará a média e utilizará este valor a fim de calibrar o sensor, conforme apresentado na porção de código abaixo.

<code>      do
      {
        long int ValAnalog = analogRead(A0);  
        byte AjustAnalog = map(ValAnalog, 0, 1023, 0, 255);
        
        UmidadeCalib = AjustAnalog + UmidadeCalib;
        cont++;
        
      }while(cont &lt; 10);</code>

Por fim, apresentará a mensagem Fim de Calibração e salvará o valor calibrado na memória EEPROM do Arduino. A porção de código é apresentada abaixo.

<code>lcd.clear();
      
      lcd.setCursor(5,0);
      lcd.print("Fim da");
      
      lcd.setCursor(3,1);
      lcd.print("Calibracao");

      delay(15000);
      lcd.clear();
      
      byte ValorCalibrado = UmidadeCalib/10;      
      EEPROM.write(VALORCALIB, ValorCalibrado);</code>

Finalmente, será chamada a função UmidadeAlarme, a fim de permitir ajustar o valor de umidade para alertar o usuário.

Implementação da Função UmidadeAlarme

Conforme apresentado, o sistema necessita ser parametrizado, para acionar o alerta, quando o valor de umidade ultrapassar um certo limite. Portanto, o usuário deve ajustar esse parâmetro por meio da função UmidadeAlarme.

A seguir, é apresentada a tela de ajuste de umidade na Figura 4. Desse modo, o usuário pode ajustar um valor entre 0% e 100%.

Figura 4 – Tela de Ajuste do nível de umidade do alarme.

Esse processo é realizado através do código a seguir.

<code>void UmidadeAlarme()
{
  bool BotaoEnter = 0;
  byte ajuste = 0;
  byte ValorAnt = 0;
  
  lcd.clear();  
  lcd.setCursor(0,0);
  lcd.print("Ajustar Umidade:");
  lcd.setCursor(7,1);
  
  lcd.print(ajuste);
  
  do
  {
      Incremento = digitalRead(BotaoInc);
      Decremento = digitalRead(BotaoDec);
      
      if(Incremento == 1 &amp;&amp; IncrementoAnterior == 0)
      {
        AlarmeUmidade++;
        IncrementoAnterior = 1;
      }
    
      if(Incremento == 0 &amp;&amp; IncrementoAnterior == 1)
      {
        IncrementoAnterior = 0;
      }
    
      if(Decremento == 1 &amp;&amp; DecrementoAnterior == 0)
      {
        AlarmeUmidade--;
        DecrementoAnterior = 1;
      }
    
      if(Decremento == 0 &amp;&amp; DecrementoAnterior == 1)
      {
        DecrementoAnterior = 0;
      }

      if(AlarmeUmidade &gt; 100)
      {
        AlarmeUmidade = 100;  
      }

      if(AlarmeUmidade &lt; 0)
      {
        AlarmeUmidade = 0;  
      }
      delay(100);
      
      if(AlarmeUmidade != ValorAnt)
      {
        lcd.clear();
        
        lcd.setCursor(0,0);
        lcd.print("Ajustar Umidade:");
        lcd.setCursor(7,1);
        lcd.print(AlarmeUmidade);
        
        ValorAnt = AlarmeUmidade;      
      }

      BotaoEnter = digitalRead(botaoOK);
      
  }while(BotaoEnter != 1);

      EEPROM.write(UMIDADEAJUSTADA, AlarmeUmidade);
      
      return;
}</code>

Dessa forma, o usuário deverá utilizar os botões incremento e decremento, para configurar o valor da umidade no laço do while.

Além disso, o sistema atualizará a tela, apenas quando o valor da contagem é diferente do valor anterior, para evitar efeito indesejado na tela a cada ciclo de loop. Isto é apresentado na porção de código a seguir.

<code>      if(AlarmeUmidade != ValorAnt)
      {
        lcd.clear();
        
        lcd.setCursor(0,0);
        lcd.print("Ajustar Umidade:");
        lcd.setCursor(7,1);
        lcd.print(AlarmeUmidade);
        
        ValorAnt = AlarmeUmidade;      
      }</code>

Por fim, o sistema aguarda o usuário pressionar o botão Ok. Dessa forma, sairá do laço do while e salvará o valor de ajuste na memória EEPROM, conforme apresentado abaixo.

<code>EEPROM.write(UMIDADEAJUSTADA, AlarmeUmidade);</code>

Finalmente, após realizar a calibração e ajuste da umidade para o alarme, o sistema entrará na função loop.

Implementação da Lógica Principal – Função Loop

Primeiramente, o sistema captura o valor de tempo da função millis e salva na variável tempo_atual. Posteriormente, esse valor de tempo será usado para criar outras funções com os botões de incremento e decremento.

<code>tempo_atual = millis();</code>

Após isto, é realizada a leitura do sensor analógico e o valor é mapeado na escala de 0 a 255. Esse processo foi realizado, já que os valores de calibração foram ajustados para 8 bits, pois as posições da memória são de 8 bits.

Por fim, verifica-se o valor ajustado com o valor calibrado no sistema. Se o valor lido e ajustado for maior, atribui-se o próprio valor máximo à variável, conforme apresentado abaixo.

<code>//Le o valor do pino A0 do sensor
  ValorAnalog = analogRead(sensor);
  
  byte AjustAnalog = map(ValorAnalog, 0, 1023, 0, 255);

  if(AjustAnalog &gt;= MaxCalib)
  {
    AjustAnalog = MaxCalib;  
  }</code>

Esse processo força ao sistema apresentar o resultado de solo 100% seco, caso o valor de leitura seja maior que o de calibração.

Em seguida, o valor da umidade será apresentado na tela. Além disso, o sistema informará se a umidade está alta ou baixa, conforme apresentado na Figura 5.

Figura 6 – Tela de apresentação do valor do nível de umidade medido.

Esse processo é representado pela porção de código a seguir.

<code>    lcd.clear();
    lcd.setCursor(3,0);
    lcd.print("Umidade:");
    lcd.setCursor(12,0);
    lcd.print(UmidadePercent);
    lcd.print("%");
  
  if(UmidadePercent &gt;= UmidadeAjuste)
  {
    digitalWrite(13, HIGH);
    
    lcd.setCursor(1,1);
    lcd.print("Baixa Umidade");
  }
  
  if(UmidadePercent &lt; UmidadeAjuste)
  {
    digitalWrite(13, LOW);

    lcd.setCursor(2,1);
    lcd.print("Alta Umidade");
  }</code>

Caso o valor de umidade seja baixo, ou seja, o valor se aproximar de 100% (terra seca), o sistema irá apresentar a mensagem Baixa Umidade e ligar um LED. Na Figura 6 é apresentado o resultado desse processo.

Figura 7 – Tela de apresentação do valor do nível baixo de umidade.

Além desse processo de apresentar o valor de umidade e seu estado, foram necessárias outras funcionalidades.

Implementação de novas funcionalidades de ajuste em tempo real da umidade e calibração

Entre essas funcionalidades, destacamos duas: reconfigurar a calibração e ajustar um novo nível de alarme de umidade para o sistema.

Essas funcionalidades são importantes, pois o usuário pode necessitar inserir o sensor em uma nova planta e, portanto, todo o sistema necessita de um novo ajuste.

Portanto, para realizar esse processo, utilizamos os próprios botões de incremento e decremento. Para realizar novas funcionalidades, utilizamos a função millis para isso.

Ou seja, ao pressionar o botão de decremento por mais de 4 segundos, o sistema inicia o processo de calibração e ajuste de umidade.

A seguir, apresentamos a porção de código, para realizar esse processo.

<code>  bool Parametrizar = digitalRead(BotaoDec);

  if(Parametrizar == 0)
  {
    ultimo_tempo = tempo_atual;  
  }
  
  if(Parametrizar == 1 &amp;&amp; (tempo_atual - ultimo_tempo &gt; 4000))
  {
    for(byte endereco = 130; endereco &lt; 133; endereco++)
    {
      EEPROM.write(endereco, 0);
    }

    CalibraSensor();
    EEPROM.write(SINALCALIB, 73);
    UmidadeAlarme();
    
    UmidadeAjuste = EEPROM.read(UMIDADEAJUSTADA);
    MaxCalib = EEPROM.read(VALORCALIB);
 }</code>

Primeiramente, é realizada a leitura do estado do botão decremento. Em seguida, verifica-se o teste a fim de determinar o seu estado. Caso seja 0, o valor da variável tempo_atual será atribuída à variável ultimo_tempo, para atualizar o último tempo retornado pela função millis.

Em seguida, temos a condição para verificar se o botão está acionado e se o botão está pressionado por mais de 4 segundos.

Botão com Multifunção para Ajuste e Calibração da Umidade

Portanto, quando o botão está pressionado, o valor da variável tempo_anterior não será mais atualizado. Logo, haverá um instante em que a diferença entre a variável tempo_atual e a variável ultimo_tempo será maior que 4000 ms.

Dessa forma, o sistema entrará na condição e limpará as posições da memória EEPROM. Além disso, chamará as funções CalibraSensor e UmidadeAlarme, a fim de iniciar o processo de calibração do sensor e ajuste de um novo valor de alarme para umidade.

Por fim, há a última condição e similar à anterior. Esta condição é utilizada para verificar se o botão de incremento está acionado por 3 segundos ou mais. Caso seja verdade, a função de ajuste do alarme de umidade será chamada.

Desse modo, ela permitirá ao usuário ajustar um novo nível de alarme durante a execução do código.

Portanto, por meio desse sistema você poderá utilizá-lo em qualquer projeto

Depois disso, o sistema retorna ao início do loop e inicia todo o processo de monitoramento do nível de umidade com o sensor de umidade capacitivo pelo arduino.

Conclusão

Por meio desse sensor, finalmente, é possível aplicá-lo em vários projetos que necessitam utilizar sensor de umidade. Além disso, destacamos o principal benefício desse sensor: sua alta resistência à corrosão.

Isto se deve à camada de proteção, que irá garantir uma vida útil maior ao sensor. Portanto, com um baixo custo do sensor é possível obter uma maior durabilidade do mesmo em processos de medição e monitoramento de umidade.

Portanto, com um baixo custo do sensor é possível obter uma maior durabilidade do mesmo em processos de medição e monitoramento de umidade.

Posts relacionados

Como Construir um Robô de Resgate Competitivo – Parte 3: Programação

por autocore
6 anos ago

Gravando no cartão RFID com Arduino

por Danilo Nogueira
5 anos ago

Blink com NodeMCU Lolin V3

por autocore
8 anos ago
Sair da versão mobile