Sensor de Umidade Capacitivo com Arduino
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.
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.
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
- Arduino Nano
- Sensor de Umidade Capacitivo
- Display LCD 16×2 c/ Backlight Azul
- Trimpot 5kR
- Resistor 10kR
- Botão de Toque 6 x 6 x 6 mm
- Kit de Jumpers Rígidos para Protoboard
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 <LiquidCrystal.h> #include <EEPROM.h> #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 >= 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 >= UmidadeAjuste) { digitalWrite(13, HIGH); lcd.setCursor(1,1); lcd.print("Baixa Umidade"); } if(UmidadePercent < 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 && (tempo_atual - ultimo_tempo > 4000)) { for(byte endereco = 130; endereco < 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 && (tempo_atual - ultimo_tempo2 > 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 < 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 && IncrementoAnterior == 0) { AlarmeUmidade++; IncrementoAnterior = 1; } if(Incremento == 0 && IncrementoAnterior == 1) { IncrementoAnterior = 0; } if(Decremento == 1 && DecrementoAnterior == 0) { AlarmeUmidade--; DecrementoAnterior = 1; } if(Decremento == 0 && DecrementoAnterior == 1) { DecrementoAnterior = 0; } if(AlarmeUmidade > 100) { AlarmeUmidade = 100; } if(AlarmeUmidade < 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.
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 < 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%.
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 && IncrementoAnterior == 0) { AlarmeUmidade++; IncrementoAnterior = 1; } if(Incremento == 0 && IncrementoAnterior == 1) { IncrementoAnterior = 0; } if(Decremento == 1 && DecrementoAnterior == 0) { AlarmeUmidade--; DecrementoAnterior = 1; } if(Decremento == 0 && DecrementoAnterior == 1) { DecrementoAnterior = 0; } if(AlarmeUmidade > 100) { AlarmeUmidade = 100; } if(AlarmeUmidade < 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 >= 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.
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 >= UmidadeAjuste) { digitalWrite(13, HIGH); lcd.setCursor(1,1); lcd.print("Baixa Umidade"); } if(UmidadePercent < 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.
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 && (tempo_atual - ultimo_tempo > 4000)) { for(byte endereco = 130; endereco < 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.