Gardenino (Irrigação Automatizada)

O projeto Gardenino permite a automação da irrigação de plantações de pequeno porte, tais como hortas domésticas. Baseado em horários pré-definidos e na presença de água em um reservatório, realiza-se o acionamento do relé, que por sua vez liga a bomba para a irrigação da horta. Uma mensagem pelo twitter é enviada automaticamente com uma mensagem programada para informar ao produtor que a irrigação está ocorrendo.

O sistema consiste na utilização de uma bomba de aquário para irrigar, um relé para o seu acionamento periódico, um sensor ultra-sônico para verificação do nível da água para evitar o mau funcionamento da bomba e a utilização da placa NodeMCU para o processamento dos dados da periodicidade, verificação do nível da água, acionamento do relé da bomba e envio de mensagem acerca do estado da planta.

Projeto pelos alunos José Pereira e Diego Queiroz

Componentes

  • Protoboard 

É uma placa com furos e conexões condutoras para montagem de circuitos elétricos experimentais. A grande vantagem da placa de ensaio na montagem de circuitos eletrônicos é a facilidade de inserção de componentes, uma vez que não necessita soldagem. As placas variam de 800 furos até 6000 furos, tendo conexões verticais e horizontais.

protoboard

  • Fios

fios

  • NodeMCU

O NodeMCU é um kit de desenvolvimento que permite a programação de protótipos para a Internet das Coisas (IoT). Ele integra interfaces GPIO, 1-Wire, I2C, SPI, PWM, ADC, entre outros.node

  • Relé( srd-05vdc-sl-c )

O funcionamento do relé consiste quando uma corrente circula pela bobina, esta cria um campo magnético que atrai um ou uma série de contatos fechando ou abrindo circuitos. Ao cessar a corrente da bobina o campo magnético também cessa, fazendo com que os contatos voltem para a posição original.

rele

  • Sensor ultra-sônico HC-SR04

O sensor é capaz de medir distâncias de 2cm a 4m com ótima precisão. Este módulo possui um circuito pronto com emissor e receptor acoplados e 4 pinos (VCC, Trigger, ECHO, GND) para medição. Para realizar a medição é necessário alimentar o módulo e colocar o pino Trigger em nível alto por mais de 10us. Assim o sensor emitirá uma onda sonora que ao encontrar um obstáculo rebaterá de volta em direção ao módulo, sendo que o neste tempo de emissão e recebimento do sinal o pino ECHO ficará em nível alto. Logo o cálculo da distância pode ser feito de acordo com o tempo em que o pino ECHO permaneceu em nível alto após o pino Trigger ter sido colocado em nível alto.

ultrasonico

  • Bomba Submersa A-100 Vigo Ar

Bomba essencial para se obter um ambiente propício aos peixes dentro de tanques ou aquários, tendo como fatores preponderantes a economia de energia e o alto rendimento de vazão e oxigenação, sendo este fator importante na vida aquática. Melhora a qualidade da água de seu aquário. Bomba com vazão para até 100 litros por hora, recomendada para aquários até 30 litros. Pode ser usada dentro ou fora do aquário.bomba

Montagem 

Passo 1: Fixar a placa NodeMCU na protoboard.

nodemcu

Passo 2: Conectar o sensor ultra-sônico ao NodeMCU  com a pinagem do Trigger no D1, do ECHO no D2, do GND no GND da placa e o VCC do ultra-sônico no VIN da placa, tudo de acordo com a imagem a baixo

node+ultra

Passo 3: Conectar o relé ao NodeMCU de acordo com a imagem a baixo.

node+rele

Passo 4: Conectar a bomba ao relé (para simular usaremos um motor que tem o mesmo tipo de montagem para o seu funcionamento).circuitocompleto

Imagem Real:

circuito real

Máquina de Estados

A máquina de estado descreve a implementação do projeto Gardenino.Gardenino2O projeto Gardenino inicia pelo estado S0, onde ele se mantém quando se encontra fora da hora de irrigar e o nível do reservatório estiver bom (T0, S1). Se estiver fora da hora de irrigar e o nível do reservatório estiver baixo (T0,S0)  ele irá para o estado S1 onde o sistema postará a seguinte mensagem no twitter: “Reservatório vazio!”.

Se der a hora de irrigar e o nível do reservatório estiver baixo (T1,S0) ele irá para o estado S2 onde enviará a seguinte mensagem no twitter: “Estou com sede e não tem água =(“, e se der a hora de irrigar e o nível do reservatório estiver bom (T1,S1) ele irá para o S3 onde o sistema postará uma outra mensagem ao twitter: “Oba! Água! *–*”,  acionará a bomba de água pelo tempo delimitado em S3 e retornará para S0.

Estando no estado S1 ele poderá manter-se lá caso a situação (T0,S0) continue ou ir para o estado S2, caso der a hora de irrigar e continue o reservatório com nível de água baixo (T1,S0) onde o sistema postará uma mensagem no twitter: “Reservatório vazio!”, ou irá para o estado S3. Se der à hora de irrigar e já o reservatório estiver cheio deixando em um nível bom (T1,S1)  o sistema irá postar uma mensagem no twitter: “Oba! Água! *–*”,  acionará a bomba de água pelo tempo delimitado em S3 e retornará para S0.

Estando no estado S2 ele poderá manter-se lá caso a situação (T1,S0) continue ou ir para o estado S3. Se der a hora de irrigar e já tiverem enchido o reservatório deixando num nível bom (T1,S1), o sistema irá postar a seguinte mensagem no twitter: “Oba! Água! *–*”,  acionará a bomba de água pelo tempo delimitado em S3 e retornará para S0.

Código

//Inclusão de bibliotecas utilizadas no projeto

#include
#include 

//definição das entradas e saídas utilizadas
#define TRIGGER 5
#define ECHO 4
#define RELAY 15

//declaração das variáveis
unsigned long tempocontrole=0;
int s=1; // indica a situacao do sensor
int t=0;
int count=0;
typedef enum{
S0,
S1,
S2,
S3,
DELAY
} STATES;
STATES estado = S0;
char ssid[] = "JuniorBrowser"; // SSID da rede
char pass[] = "junior29"; // Senha da rede

// Variáveis usadas no recebimento e manipulação de pacotes NTP
unsigned int localPort = 2390;
IPAddress timeServerIP;
const char* ntpServerName = "a.st1.ntp.br";
const int NTP_PACKET_SIZE = 48;
byte packetBuffer[ NTP_PACKET_SIZE];
WiFiUDP udp;

void setup()
{
//iniciando o Serial e as entradas/saidas
Serial.begin(9600);
pinMode(TRIGGER, OUTPUT);
pinMode(ECHO, INPUT);
pinMode(RELAY, OUTPUT);

//Metodo de conexão a uma rede Wifi
Serial.println("Conectando a ");
Serial.println(ssid);
WiFi.begin(ssid, pass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi conectado");
Serial.println("IP: ");
Serial.println(WiFi.localIP());
udp.begin(localPort);
}

//Metodo que recebe e trata os pacotes NTP
unsigned long sendNTPpacket(IPAddress& address)
{
memset(packetBuffer, 0, NTP_PACKET_SIZE);
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
udp.beginPacket(address, 123); //NTP requests are to port 123
udp.write(packetBuffer, NTP_PACKET_SIZE);
udp.endPacket();
}

//Função que consulta o tempo atual
unsigned long gettempo(){
WiFi.hostByName(ntpServerName, timeServerIP);
sendNTPpacket(timeServerIP);
delay(1000);
int cb = udp.parsePacket();
while (!cb) {
Serial.println("no packet yet");
}
udp.read(packetBuffer, NTP_PACKET_SIZE);
unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
unsigned long secsSince1900 = highWord <=tempocontrole){
tempocontrole = gettempo()+14400;// Aqui é definido o intervalo de tempo entre regagens em segundos(14400s = 4h)
return 1;
}
else{
return 0;
}
}

//Função que calcula a distancia captada pelo sensor
long sensor(){
long duration, distance;
digitalWrite(TRIGGER, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER, LOW);
duration = pulseIn(ECHO, HIGH);
distance = (duration/2) / 29.1;
Serial.print("Centimeter: ");
Serial.println(distance);
return distance;
}

void loop()
{
//Definição do estado inicial do automato e do tempo controle
// importante observar que a maquina irá começar a contar o tempo do intervalo a partir do momento em que for ativada
Serial.print("Estado: S");
Serial.println(estado);
unsigned long secsSince1900 = gettempo();
if (tempocontrole==0){
tempocontrole= gettempo();
}
t =comparatempo(secsSince1900, tempocontrole);
if(t==1){
tempocontrole=tempocontrole+14400; //define o tempo de intervalo em segundos
}
long distance = sensor();
if(distance < 10) { //distancia em centimetros que indica o limite do reservatório.
count++;
if(count==2){// validação que evita leituras erradas do sensor
digitalWrite(RELAY, HIGH);
delay(4000); //Tempo em ms que a bomba deve bombear a agua.
count=0;
s=1;
}
}
else{
count=0;
digitalWrite(RELAY, LOW);
s=0;
}

// Definição da maquina de estados e de sua função de transição

Serial.print("T: ");
Serial.println(t);
Serial.print("S: ");
Serial.println(s);
switch(estado){
case S0:
if((t==0)&&(s==1)){
estado=S0;
break;
}
else if((t==0)&&(s==0)){

estado=S2;
break;
}
else if((t==1)&&(s==0)){

estado=S1;
break;
}
else if((t==1)&&(s==1)){

estado=S3;
break;
}
else{estado=S0;
}
break;
case S1:
Serial.println("Reservatorio vazio! ");
if(s==1){
estado=S3;
break;
}
else{
estado=S1;
}
break;
case S2:

Serial.println("Estou com sede e nao tem agua =( ");
if((t==0)&&(s==1)){
estado=S0;
break;
}
else if((t==0)&&(s==0)){
break;
}
else if((t==1)&&(s==0)){
estado=S1;
break;
}
else if((t==1)&&(s==1)){
estado=S3;
break;
}
else{estado=S0;
}
break;
case S3:
Serial.println("Oba! Agua! *--* ");
//regar
//resetar
estado=S0;
break;
case DELAY:
//delay(3000);
estado=S0;
break;
default:
break;
delay(30);
}
Serial.println("Estado final: ");
Serial.println(estado);
}

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s