Ir ao conteúdo
  • Cadastre-se

Arduino Estouro da função Millis ()


Posts recomendados

Boa Tarde a Todos,

Desculpem resgatar esse topico tão antigo mas fiz varias pesquisas e não encontrei claramente como "dar a volta" na função millis.

Gostaria da ajuda de vocês! Estou em um projeto de estufa de hortaliças estou usando a função millis() para medição de umidade do solo e ao mesmo tempo habilitar uma solenoide para liberara agua.

Sendo assim não consigo usar o delay() pois "travaria" a medição de umidade e não ia desabilitar a solenide ou vice e versa.

A função millis() estoura em ~48 dias com isso pode ser que meu programa trave na solenoide com a agua aberta e cause um desastre, se alguem necessitar do codigo inteiro ou somente a parte do millis é só falar que eu posto aqui.



Obrigado e Agradeço a todos desde já!!!! 

Link para o comentário
Compartilhar em outros sites

6 horas atrás, Bruno R Ruinho disse:

Boa Tarde a Todos,

Desculpem resgatar esse topico tão antigo mas fiz varias pesquisas e não encontrei claramente como "dar a volta" na função millis.

Gostaria da ajuda de vocês! Estou em um projeto de estufa de hortaliças estou usando a função millis() para medição de umidade do solo e ao mesmo tempo habilitar uma solenoide para liberara agua.

Sendo assim não consigo usar o delay() pois "travaria" a medição de umidade e não ia desabilitar a solenide ou vice e versa.

A função millis() estoura em ~48 dias com isso pode ser que meu programa trave na solenoide com a agua aberta e cause um desastre, se alguem necessitar do codigo inteiro ou somente a parte do millis é só falar que eu posto aqui.



Obrigado e Agradeço a todos desde já!!!! 

 

Segue o trecho do codigo:

#define   intervalo 2000   //INTERVALO DE LEITURA DO SENSOR DTH

unsigned long delayIntervalo;           //ARMAZENA O TEMPO DE COMPARAÇÃO COM MILLIS

void loop() 
  {
      leitura_temp();                       //CHAMA FUNÇÃO DE LEITURA DE TEMPERATURA
  }


void leitura_temp()
   {
   if ( (millis() - delayIntervalo) > intervalo ) {        //LEITURA DOS DADOS
        unsigned long start = micros();
        int chk = sensorDHT.read11(pinSensor);             //
        unsigned long stop = micros();
  
      /* VERIFICA SE HOUVE ERRO
      switch (chk)
      {
      case DHTLIB_OK:
          Serial.print("OK,\t");
          break;
      case DHTLIB_ERROR_CHECKSUM:
          Serial.print("Checksum error,\t");			Esta parte esta comentada pois estava dando erro na leitura.
          break;
      case DHTLIB_ERROR_TIMEOUT:
          Serial.print("Time out error,\t");
          break;
      case DHTLIB_ERROR_CONNECT:
          Serial.print("Connect error,\t");
          break;
      case DHTLIB_ERROR_ACK_L:
          Serial.print("Ack Low error,\t");
          break;
      case DHTLIB_ERROR_ACK_H:
          Serial.print("Ack High error,\t");
          break;
      default:
          Serial.print("Unknown error,\t");
          break;
      }*/
      delayIntervalo = millis();          //CARREGA O VALOR DE MILLIS DENTRO DE delayIntervalo
    };
}                                         //FINAL DA FUNÇÃO LEITURA TEMPERATURA

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
18 horas atrás, Bruno R Ruinho disse:

um projeto de estufa de hortaliças

Fale mais sobre o projeto com esquemas, desenhos, fotos, etc. Crie fluxograma ou algoritimos simples. Talvez nem precise desta função. Não analisei seu fonte...

Link para o comentário
Compartilhar em outros sites

Em 31/03/2020 às 14:48, Bruno R Ruinho disse:

Boa Tarde a Todos,

Desculpem resgatar esse topico tão antigo mas fiz varias pesquisas e não encontrei claramente como "dar a volta" na função millis.

Gostaria da ajuda de vocês! Estou em um projeto de estufa de hortaliças estou usando a função millis() para medição de umidade do solo e ao mesmo tempo habilitar uma solenoide para liberara agua.

Sendo assim não consigo usar o delay() pois "travaria" a medição de umidade e não ia desabilitar a solenide ou vice e versa.

A função millis() estoura em ~48 dias com isso pode ser que meu programa trave na solenoide com a agua aberta e cause um desastre, se alguem necessitar do codigo inteiro ou somente a parte do millis é só falar que eu posto aqui.



Obrigado e Agradeço a todos desde já!!!! 


Em vez de um delay gigantesco, faça delays menores, e crie um loop fazendo delay , depois medidas, depois ações corretivas, delay de novo e assim por diante.

Se a precisão do tempo for importante, sugiro usar um módulo DS xxxxx para manter seu tempo preciso.

 

Paulo

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
7 horas atrás, Isadora Ferraz disse:

Não analisei seu fonte...

numa analizinha rápida devido à participação do amigo Paulão...

3 horas atrás, aphawk disse:

um delay gigantesco,

...vi isso...

19 horas atrás, Bruno R Ruinho disse:

#define intervalo 2000 //INTERVALO DE LEITURA DO SENSOR DTH

 

você só quer ler a umidade a cada 2 segundos? Só isso? Que tal se usasse o timer ou uma interrupção por timer de 2 segundos? Se usar cristal até que o tempo fica quase bem preciso. Se houver requisito de baixo consumo, há a opção do modo sleep sendo acordado a cada intervalo.

 

O que você leu acima foi fruto de bola de cristal semi enferrujada e tudo conceitual, portanto não passível de detalhamentos por minha parte ok? Mas é uma oportunidade pra se libertar um pouco das amarras das funções mastigadas da IDE do arduíno e criar próprias...

  • Haha 1
Link para o comentário
Compartilhar em outros sites

Obrigado Isadora e Paulão pela presença!!..rs

 

Gosto da Isadora pois ela da umas "tiradas" de leve não importando a situação🤣

 

Paulão , já vi varios posts seus ajudando o pessoal por ai!!!

 

 

Vamos lá a ideia da Estufa/Plantario:

 

*Controle da iluminação para acelerar o crescimento, simular as épocas do ano, primavera, verão, outono e inverno e 24h ligado

*Temperatura e Umidade do Ar = Somente para comparação interno/externo.

*Umidade do Solo; = Medição (pelo visto posso elevar o tempo) a cada 1 min, caso esteja baixo, aciona uma bomba de aquário / solenoide para irrigação.

*Relógio - Para ter uma precisão de acionar e desligar a lâmpada nos horários pre-definidos.

 

Tela "RESUMO"

001.png.99be48538c64d272897daec347fcdc8a.png

 

Ao pressionar "SELECT"

002.png.2cb9ad9fc13547b037ca93ef2e4ce3b5.png


 

Select novamente, para entrar na "seleção"🙄

003.png.b0833cae913acaba26e9a13a6eec93ed.png


 

Os sub-menus desse menu será o tempo que a iluminação ficará acesa ex: >ILUMINAÇÃO > 24h /

12-12 /

16-8 /

OFF.…

 

 

 

 

Bibliotecas Utilizadas:

DHTlib

NewliquidCrystal_1.3.4

RTClib

 

/* =============================================================================================================


============================================================================================================= */


//*************************************************************************************//
//============================= DECLARAÇÃO DE BIBLIOTECAS =============================

#include <LiquidCrystal_I2C.h>                              //BIBLIOTECA DE LCD POR I2C
#include <Wire.h>                                           //BIBLIOTECA PARA COMUNICAÇÃO COM I2C
#include <RTClib.h>                                         //BIBLIOTECA DO RTC DS1307
#include <dht.h>                                            //BIBLIOTECA DO SENSOR DTH
//*************************************************************************************//
//============================= DECLARAÇÃO DE CONSTANTES ==============================
//*************************************************************************************//
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE);
RTC_DS1307 RTC;
dht sensorDHT;
//*************************************************************************************//
//============================= MAPEAMENTO DE HARDWARE ================================
//*************************************************************************************//
#define   bt_dir    2      //BOTÃO DA DIREITA   
#define   bt_esq    3      //BOTÃO DA ESQUERDA
#define   bt_enter  4      //BOTÃO ENTER
#define   bt_down   5      //BOTÃO DOWN
#define   bt_up     6      //BOTÃO UP
#define   bt_esc    7      //BOTÃO ESC
#define   Relay     10     //RELE LAMPADA
#define   pinSensor 12     //SENSOR DTH
#define   intervalo 2000   //INTERVALO DE LEITURA DO SENSOR DTH
//*************************************************************************************//
//============================= DECLARAÇÃO DE VARIAVEIS ===============================
//*************************************************************************************//
byte menu_num = 1, sub_menu = 1;        //FLAGS PARA OS MENUS PRINCIPAIS
byte submenu1 = 1, submenu2 = 1;        //FLAGS PARA OS SUBMENUS
byte t_bt_down, t_bt_up;                //FLAGS PARA ARMAZENAR OS ESTADOS DOS BOTÕES
byte set_full=1;                        //FLAG PARA MANTER O RELÊ LIGADO
int hourupg=0;                          //ARMAZENA HORA     - INICIA COM 0
int minupg=0;                           //ARMAZENA MINUTOS  - INICIA COM 0
int dayupg=1;                           //ARMAZENA DIA      - INICIA COM 1
int monthupg=1;                         //ARMAZENA MÊS      - INICIA COM 1
int yearupg=0;                          //ARMAZENA ANO      - INICIA COM 0
int menu=0;                             //ARMAZENA O ESTADO DO MENU DENTRO DO SWITCH CASE
int set_on=0;                           //ARMAZENA A HORA DE LIGAR O RELÊ
int set_off=0;                          //ARMAZENA A HORA DE DESLOGAR O RELÊ
String fotoperiodo;                     //ARMAZENA A STRING DO FOTO PERIODO "24h" , "18h" , "12h" , OFF
unsigned long delayIntervalo;           //ARMAZENA O TEMPO DE COMPARAÇÃO COM MILLIS

byte thermometro[8] = {                 //SIMBOLO TERMOMETRO
  B00100,
  B01010,
  B01010,
  B01110,
  B01110,
  B11111,
  B11111,
  B01110};
byte gota[8] = {                       //SIMBOLO GOTA-UMIDADE
  B00100,
  B00100,
  B01010,
  B01010,
  B10001,
  B10001,
  B10001,
  B01110};
byte sol_sym[8] = {                   //SIMBOLO SOL
  B00100,
  B10001,
  B01110,
  B11111,
  B01110,
  B10001,
  B00100,
  B00000
};
//*************************************************************************************//
//============================ CONFIGURAÇÕES DE INICIAIS ==============================
//*************************************************************************************//
void setup() 
{
  pinMode(bt_dir,   INPUT_PULLUP);      //CONFIGURA COMO ENTRADA E SETA RESISTORES DE PULLUP INTERNOS
  pinMode(bt_esq,   INPUT_PULLUP);      //  
  pinMode(bt_enter, INPUT_PULLUP);      //
  pinMode(bt_down,  INPUT_PULLUP);      //
  pinMode(bt_up,    INPUT_PULLUP);      //
  pinMode(bt_esc,   INPUT_PULLUP);      //
  pinMode(Relay,    OUTPUT);            //CONFIGURA COMO SAIDA
  
  lcd.begin(20, 4);                     //INICIA COMUNICAÇÃO COM LCD E SETA LCD20x4
  Wire.begin();                         //INICIA COMUNICAÇÃO WIRE
  RTC.begin();                          //INICIA COMUNICAÇÃO COM MODULO RTC
}                                       //FINAL DO SETUP
//*************************************************************************************//
//============================ CONFIGURAÇÕES DE LOOP ==================================
//*************************************************************************************//
void loop() 
  {
      leitura_temp();                       //CHAMA FUNÇÃO DE LEITURA DE TEMPERATURA
      keyboard();                           //CHAMA FUNÇÃO DE LEITURA DE TECLADO
      switch(menu_num)                      //SWITCH DO MENU
        {
          case 1: resumo(); break;
          case 2: iluminacao(); break;
          case 3: temperatura(); break;
          case 4: umidade(); break;
          case 5: ajuste_relogio(); break;
        }                                   //FINAL DO SWITCH
}                                           //FUNAL DO LOOP
//*************************************************************************************//
//=========================== DESENVOLVIMENTO DAS FUNÇÕES =============================
//*************************************************************************************//
void keyboard()
   {
   if(!digitalRead(bt_up))   t_bt_up   = 0x01;          //BOTÃO UP PRESSIONADO? SETA A FLAG
   if(!digitalRead(bt_down)) t_bt_down = 0x01;          //BOTÃO DOWN PRESSIONADO? SETA A FLAG
      
   if(digitalRead(bt_up) && t_bt_up)                    //BOTÃO UP SOLTO E FLAG SETADA?
     {                                                  //SE SIM...
        t_bt_up = 0x00;                                   //LIMPA FLAG
        lcd.clear();                                      //LIMPA LCD
        menu_num++;                                       //INCREMENTA MENU
        
        if(menu_num > 0x05) menu_num = 0x01;              //SE MENU FOR MAIOR QUE 5, MENU VOLTA A SER 1   
     }                                                  //FINAL BOTÃO UP (bt_up)
   
   if(digitalRead(bt_down) && t_bt_down)                //BOTÃO DOWN SOLTO E FLAG SETADA?
     {                                                  //SE SIM...
        t_bt_down = 0x00;                                 //LIMPA FLAG
        lcd.clear();                                      //LIMPA LCD
        menu_num--;                                       //DECREMENTA MENU
        
        if(menu_num < 0x01) menu_num = 0x05;              //SE MENU FOR MENOR QUE 1, MENU VOLTA A SER 5
     }                                                  //FINAL BOTÃO DOWN (bt_down)   
     
   if(!digitalRead(bt_enter))                           //BOTÃO ENTER PRESSIONADO?
     {                                                    //SE SIM...
        delay(150);                                       //AGUARDA 150ms
        if(sub_menu <= 2) sub_menu ++;                    //SE sub_menu FOR MENOR OU IGUAL A 2, INCREMENTA sub_menu
     }                                                  //FINAL BOTÃO ENTER (bt_enter)

   if(!digitalRead(bt_esc))                             //BOTÃO ESC PRESSIONADO?                
     {                                                    //SE SIM...
        delay(150);                                       //AGUARDA 150ms
        if(sub_menu > 0) sub_menu --;                     //SE sub_menu FOR MAIOR QUE 0, DECREMENTA sub_menu
     }                                                  //FINAL BOTÃO ESC (bt_esc)

}                                        //FINAL DA FUNÇÃO KEYBOARD
void leitura_temp()
   {
   if ( (millis() - delayIntervalo) > intervalo ) {        //LEITURA DOS DADOS
        unsigned long start = micros();
        int chk = sensorDHT.read11(pinSensor);             //
        unsigned long stop = micros();
  
      /* VERIFICA SE HOUVE ERRO
      switch (chk)
      {
      case DHTLIB_OK:
          Serial.print("OK,\t");
          break;
      case DHTLIB_ERROR_CHECKSUM:
          Serial.print("Checksum error,\t");
          break;
      case DHTLIB_ERROR_TIMEOUT:
          Serial.print("Time out error,\t");
          break;
      case DHTLIB_ERROR_CONNECT:
          Serial.print("Connect error,\t");
          break;
      case DHTLIB_ERROR_ACK_L:
          Serial.print("Ack Low error,\t");
          break;
      case DHTLIB_ERROR_ACK_H:
          Serial.print("Ack High error,\t");
          break;
      default:
          Serial.print("Unknown error,\t");
          break;
      }*/
      delayIntervalo = millis();
    };
}                                         //FINAL DA FUNÇÃO LEITURA TEMPERATURA

void resumo()
  {
  DateTime now = RTC.now();
  lcd.setCursor(0,0);
  lcd.print("====== ESTUFA ======");
  lcd.setCursor(0,1);
  if (now.hour()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.hour(), DEC); // GET HORA DO RTC E MOSTRA NO LCD
  hourupg=now.hour();
  lcd.print(":"); // ESPAÇO ENTRE
  if (now.minute()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.minute(), DEC);// GET MINUTOS DO RTC E MOSTRA NO LCD
  minupg=now.minute();

  
  lcd.setCursor(15, 1);
  if (now.day()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.day(), DEC);
  dayupg=now.day();
  lcd.print("/");
  if (now.month()<=9)
  {
    lcd.print("0");
  }
  lcd.print(now.month(), DEC);
  monthupg=now.month();
  
  lcd.createChar(1,thermometro);
  lcd.setCursor(1,2);
  lcd.write(byte(1));
  lcd.setCursor(2,2);
  lcd.print(sensorDHT.temperature,0);
  lcd.setCursor(4,2);
  lcd.write(byte(223));
  
  lcd.createChar(2,gota);
  lcd.setCursor(15,2);
  lcd.write(byte(2));
  lcd.setCursor(16,2);
  lcd.print(sensorDHT.humidity,0);
  lcd.setCursor(18,2);
  lcd.write("%");

  //Função do Relay
    if(set_on == set_off){
   digitalWrite(Relay, LOW);
   if(set_on == set_off && set_on == set_full)
    {
    digitalWrite(Relay, HIGH);
    }
    }
      if(set_on < set_off){
    
               if(now.hour() >= set_on && now.hour() < set_off ){             //Start
               digitalWrite(Relay, HIGH);
               }
               else if(now.hour() >= set_off) {
               digitalWrite(Relay, LOW);
               }
               else{
               digitalWrite(Relay, LOW);
               }
      }
      if (set_on > set_off){
  
              if(now.hour() >= set_on && now.hour() <= 23){                  //Start
              digitalWrite(Relay, HIGH);  
              }
              else if(now.hour() < set_off){
              digitalWrite(Relay, HIGH);
              }
              else if(now.hour() >= set_off && now.hour() < set_on){
              digitalWrite(Relay, LOW);  
              }
      }
  lcd.createChar(3,sol_sym);
  lcd.setCursor(8,2);
  lcd.write(byte(3));
  lcd.setCursor(9,2);
  lcd.print(fotoperiodo);
  
  
  lcd.setCursor(0,3);
  lcd.print("   SOLO:  50 UMIDO  ");
  }
  
void iluminacao()
{
  switch(sub_menu)
  {
     case 1:
      lcd.setCursor(0,0);
      lcd.print(">ILUMINACAO         ");
      lcd.setCursor(0,1);
      lcd.print(" TEMPERATURA        ");
      lcd.setCursor(0,2);
      lcd.print(" UMIDADE            ");
      lcd.setCursor(0,3);
      lcd.print(" AJUSTE RELOGIO     ");
      break;
     case 2:
       //iluminacao_sub();
      lcd.setCursor(0,0);
      lcd.print("                    ");
      lcd.setCursor(0,1);
      lcd.print("     ILUMINACAO     ");
      lcd.setCursor(0,3);
      lcd.print("                    ");
   switch(submenu1)
        {
        case 1:
        lcd.setCursor(0,2);
        lcd.print("        24        >"); 
        if(!digitalRead(bt_dir)) {delay(150); submenu1 ++;}
        
        if(!digitalRead(bt_enter))
        {
         lcd.clear();
         lcd.setCursor(0,0);
         lcd.print("SALVANDO...");
         digitalWrite(Relay, HIGH);
         fotoperiodo = String("24h");
         delay(200);
         set_full=0;
         submenu2=1;
         sub_menu=1;
         menu_num=1; 
        }
        break;
        
        case 2:
        lcd.setCursor(0,2);
        lcd.print("<       12/12     >"); 
        if(!digitalRead(bt_dir)) {delay(150); submenu1 ++;}
        if(!digitalRead(bt_esq)) {delay(150); submenu1 --;}
        
        if(!digitalRead(bt_enter))
        {
         set_on = 10;
         set_off = 11;
         lcd.clear();
         lcd.setCursor(0,0);
         lcd.print("SALVANDO...");
         fotoperiodo = String("12h");
         delay(200);
         submenu2=1;
         sub_menu=1;
         menu_num=1; 
        }
        break;
        case 3:
        lcd.setCursor(0,2);
        lcd.print("<       16/8      >"); 
        if(!digitalRead(bt_dir)) {delay(150); submenu1 ++;}
        if(!digitalRead(bt_esq)) {delay(150); submenu1 --;}

        if(!digitalRead(bt_enter))
        {
         set_on = 6;
         set_off = 0;
         lcd.clear();
         lcd.setCursor(0,0);
         lcd.print("SALVANDO...");
         fotoperiodo = String("18h");
         delay(200);
         submenu2=1;
         sub_menu=1;
         menu_num=1; 
        }
        break;
        case 4:
        lcd.setCursor(0,2);
        lcd.print("<       OFF        "); 
        if(!digitalRead(bt_esq)) {delay(150); submenu1 --;}

        if(!digitalRead(bt_enter))
        {
         set_on = 0;
         set_off = 0;
         set_full = 1;
         lcd.clear();
         lcd.setCursor(0,0);
         lcd.print("SALVANDO...");
         fotoperiodo = String("OFF");
         delay(200);
         submenu2=1;
         sub_menu=1;
         menu_num=1; 
        }
        break;
        }         //Final Switch foto-periodo
        break;
  }
} //Final Switch Iluminação

void temperatura()
{
  switch(sub_menu)
  {
     case 1:
       lcd.setCursor(0,0);
       lcd.print(" ILUMINACAO         ");
       lcd.setCursor(0,1);
       lcd.print(">TEMPERATURA        ");
       lcd.setCursor(0,2);
       lcd.print(" UMIDADE            ");
       lcd.setCursor(0,3);
       lcd.print(" AJUSTE RELOGIO     "); 
       break;
     case 2:
       lcd.setCursor(0,1);
       lcd.print("                    ");
       lcd.setCursor(0,0);
       lcd.print("    Temperatura:    ");
       lcd.setCursor(0,2);
       lcd.print("Ext: 25             ");
       lcd.setCursor(0,3);
       lcd.print("Int: 30             ");
       break;
  }
  
  
} //end temperatura


void umidade()
{
  switch(sub_menu)
  {
     case 1:
       lcd.setCursor(0,0);
       lcd.print(" ILUMINACAO         ");
       lcd.setCursor(0,1);
       lcd.print(" TEMPERATURA        ");
       lcd.setCursor(0,2);
       lcd.print(">UMIDADE            ");
       lcd.setCursor(0,3);
       lcd.print(" AJUSTE RELOGIO     ");
       break;
     case 2:
       lcd.setCursor(0,1);
       lcd.print("                    ");
       lcd.setCursor(0,0);
       lcd.print("      Umidade:      ");
       lcd.setCursor(0,2);
       lcd.print("Ext: 58             ");
       lcd.setCursor(0,3);
       lcd.print("Int: 77             ");
       break;
  }
  
  
} //end umidade


void ajuste_relogio()
{
  switch(sub_menu)
  {
     case 1:
       lcd.setCursor(0,0);
       lcd.print(" ILUMINACAO         ");
       lcd.setCursor(0,1);
       lcd.print(" TEMPERATURA        ");
       lcd.setCursor(0,2);
       lcd.print(" UMIDADE            ");
       lcd.setCursor(0,3);
       lcd.print(">AJUSTE RELOGIO     ");
       break;
     case 2:
  ajuste_sub();
       break;
  }
} //end ajuste_relogio

void ajuste_sub()
  {
  switch(submenu2)
   {
     case 1:        // ============ AJUSTE DA HORA ===================================
     lcd.clear();
     //DateTime now = RTC.now();
     if(digitalRead(bt_dir)==LOW)    // Se P2 estiver em nivel logico baixo
      {
       if(hourupg==23)          // Se "hourupg" for igual a 23
         {
          hourupg=0;            // "hourupg" passa a ser 0
         }
      else
        {
      hourupg=hourupg+1;        // Se não, incrementa +1 a "hourupg"
        }
      }
       if(digitalRead(bt_esq)==LOW)     // Se P3 estiver em nivel logico baixo
        {
      if(hourupg==0)            // Se "hourupg" for igual a 0
        {
         hourupg=23;            // "hourupg" passa a ser 23
        }
      else
        {
        hourupg=hourupg-1;        // Se não, decrementa -1 a "hourupg"
        }
      }
     lcd.setCursor(0,2);
     lcd.print("Ajustar Hora:       ");// Escreve "Ajustar Hora"
     lcd.setCursor(0,3);
     lcd.print(hourupg,DEC);
     delay(200);
     if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;}
     break;
     case 2:      // ============ AJUSTE DOS MINUTOS =================================
        lcd.clear();
        if(digitalRead(bt_dir)==LOW)    // Se P2 estiver em nivel logico baixo
      {
       if (minupg==59)          // Se "minupg" for igual a 59
          {
           minupg=0;            // "minupg" passa a ser 0
          }
    else
      {
       minupg=minupg+1;         // Se não, incrementa +1 a "minupg"
      }
    }
   if(digitalRead(bt_esq)==LOW)     // Se P3 estiver em nivel logico baixo
     {
      if(minupg==0)             // Se "minupg" for igual a 0
        {
        minupg=59;              // "minupg" passa a ser 59
        }
    else
    {
     minupg=minupg-1;           // Se não, decrementa -1 a "minupg"
    }
  }  lcd.setCursor(0,2);
     lcd.print("Ajustar Minutos:");// Escreve "Ajustar Minutos"
     lcd.setCursor(0,3);
     lcd.print(minupg,DEC);
     delay(200);
     if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;}
     break;
     case 3:        // ============ AJUSTE DIA ======================================
     lcd.clear();
    if(digitalRead(bt_dir)==LOW)    // Se P2 estiver em nivel logico baixo
      {
      if(dayupg==31)            // Se "dayupg" for igual a 31
        {
        dayupg=1;               // "dayupg" passa a ser 1
        }
    else
      {
      dayupg=dayupg+1;          // Se não, incrementa +1 a "dayupg"
      }
    }
   if(digitalRead(bt_esq)==LOW)     // Se P3 estiver em nivel logico baixo
     {
     if(dayupg==1)              // Se "dayupg" for igual a 1
        {
        dayupg=31;              // "dayupg" passa a ser 31 
        }
   else
     {
     dayupg=dayupg-1;           // se não, decrementa 11 a "dayupg"
     }
  }
     lcd.setCursor(0,2);
     lcd.print("Ajustar Dia:");// Escreve "Ajustar dia"
     lcd.setCursor(0,3);
     lcd.print(dayupg,DEC);
     delay(200);
     if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;}
     break;
     case 4:    // ============ AJUSTE MÊS ===========================================
     lcd.clear();
    if(digitalRead(bt_dir)==LOW)    // Se P2 estiver em nivel logico baixo
      {
      if(monthupg==12)          // Se "monthupg" for igual a 12
        {
        monthupg=1;             // "monthupg" passa a ser 1
        }
    else
      {
      monthupg=monthupg+1;      // Se não, incrementa +1 a "monthupg"
      }
    }
   if(digitalRead(bt_esq)==LOW)     // Se P3 estiver em nivel logico baixo
      {
      if(monthupg==1)           // Se "monthupg" for igual a 1
        {
        monthupg=12;            // "monthupg" passa a ser 12
        }
    else
      {
      monthupg=monthupg-1;      // Se não, decrementa -1 a "monthupg"
      }
      }
     lcd.setCursor(0,2);
     lcd.print("Ajustar Mes:");    // Escreve "Ajustar Mes"
     lcd.setCursor(0,3);
     lcd.print(monthupg,DEC);
     delay(200);
     if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;}
     break;
     case 5:    // ============ AJUSTAR ANO ===================================
     lcd.clear();
    if(digitalRead(bt_dir)==LOW)    // Se P2 estiver em nivel logico baixo
      {    
      yearupg=yearupg+1;        // Incrementa +1 a "yearupg"
      }
   if(digitalRead(bt_esq)==LOW)     // Se P3 estiver em nivel logico baixo
      {
      yearupg=yearupg-1;        // Decrementa -1 a "yearupg"
      }
  lcd.setCursor(0,0);           // Posiciona o cursor na coluna 0 e linha 0
  lcd.print("Ajustar Ano:");    // Escreve "Ajustar Ano"
  lcd.setCursor(0,1);
  lcd.print(yearupg,DEC);
  delay(200);
    if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;}
     break;
     
     case 6:
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SALVANDO...");
     RTC.adjust(DateTime(yearupg,monthupg,dayupg,hourupg,minupg,0)); // Grava os dados no RTC
     delay(200);
     submenu2=1;
     sub_menu=1;
     menu_num=1;
     break;
  } //end switch
    
} 

 

 

ACREDITO que o codigo esta uma lambança mas incrivelmente funciona, o LCD esta ligado por I2C para economizar pinos, ja que estou usando o Arduino UNO

No caso dos botões, tem um "defeito" , se apertar as teclas de esquerda e direita, elas incrementam / decrementam sem estar dentro dos MENUS, logo quando voce aperta a tecla Menu ele ja esta dentro de outro.... + - isso.

 

 

Com o codigo acima esta completo e funcional, vou desenhar o circuito e postar aqui, para quem quiser ulilizar o mesmo projeto e fazer melhorias serão bem vindos!

 

A tela de "RESUMO" foi modificada para esta abaixo, ficou mais visual porém estou fora de casa então nao deu para pegar do Proteus, com isso os valores da hora / data nao estão aparecendo, somente os separadores

E o valor da leitura de temp , umidade e foto-periodo tambem nao.

 

004.png.c196b85f52137ed2d6471a066f1ad005.png

 

 

 

 

Agora estou travado na leitura de temperatura e umidade com o millis e como habilitar a bomba / solenoide para irrigação.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

@Bruno R Ruinho ,

 

Opa tamos juntos meu amigo !

Pena que não posso te ajudar nessa linguagem, mas vamos lá :

 

- Pelo seu desenho você está usando um sensor de temperatura e umidade feito para uso no ar, e não no solo.

Vai ter de acrescentar um sensor desses que finca no solo e tem uma saída analógica, fácil de usar.


- Creio que para controlar a iluminação você poderia usar um LDR e “bolar” uma calibração para ter uma ideia da luz sobre as plantas, ou usar um sensor de lumens mesmo ( aí já complica um pouco ), e controlar a intensidade de luz por PWM.

 

- Para medir a umidade creio que pode medir de 5 em 5 minutos sem nenhum problema.

 

- Para ter uma boa base de tempo

você pode ficar fazendo polling no RTC e quando passar os intervalos de tempo determinados você executa as funções correspondentes .

 

- Para ganhar um 10 ...  alguns módulos RTC também possuem uma E2prom para você acessar, poderia ir guardando os dados a cada meia hora nela, e implementar uma função que transfere via interface USB ( que no Arduíno é uma simples serial ) para um PC que guardaria tudo em uma planilha Excel. A partir dela poderia fazer gráficos de tudo que é tipo.

 

- E para esnobar .... que tal usar um sensor de fluxo de água , assim poderia medir o consumo de água e verificar por ele se tudo está funcionando direitinho...

 

Projetinho legal esse !

 

 

 

adicionado 7 minutos depois
4 horas atrás, Bruno R Ruinho disse:

Gosto da Isadora pois ela da umas "tiradas" de leve não importando a situação🤣


Tem de ficar esperto, porque ela costuma dar umas “colocadas” também kkkkk , repare que eu já estou super-esperto com ela kkkkk !

 

Mas ela é a melhor pessoa aqui do Fórum quando se trata de introduzir a Eletronica nos novatos , sem falar que é a maior especialista Mundial em fazer piscar Leds !

 

Paulo

  • Haha 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Analizinha é um zip de analisezinha, pequena análise ou algo assim...kk

 

Seu projeto é bacana mas um pouco longe do meu tradicional ponto de vista minimalista. De fato o uso do relógio + ram externos são uma opção curiosa mas dependendo da proposta, desnecessário.

 

14 horas atrás, Bruno R Ruinho disse:

travado na leitura de temperatura e umidade com o millis e como habilitar a bomba / solenoide para irrigação.

Um resumo...de fato o pulo do gato - como em qualquer sistema - são os sensores e atuadores. Entre eles está seu sistema que deve basear em seus conhecimentos prévios da área pra atingir o sucesso. Ainda continuo achando que você pode criar um fluxograma do desafio pra se orientar melhor. Nesta linha acho que até tem ferramentinha semelhante pra isso...

http://easycoding.tn/esp32/demos/code/

o que me leva a...

 

10 horas atrás, aphawk disse:

E para esnobar .... que tal

uma solução wireless com o esp32? Me lembro que já vi um video de um kit hortinha automatizada com irrigadores e etc... bem legal

Link para o comentário
Compartilhar em outros sites

11 horas atrás, aphawk disse:

- Pelo seu desenho você está usando um sensor de temperatura e umidade feito para uso no ar, e não no solo.

Erro meu, este que desenhei é o de umidade do ar e temp, o higrometro eu nao encontrei, estava apanhando do Fritzing

 

11 horas atrás, aphawk disse:

- Creio que para controlar a iluminação você poderia usar um LDR e “bolar” uma calibração para ter uma ideia da luz sobre as plantas, ou usar um sensor de lumens mesmo ( aí já complica um pouco ), e controlar a intensidade de luz por PWM.

Eu me expressei mal, as luzes só vão ter o controle de tempo, ligada 24Horas, / ligada 12horas desligada 12horas / ligado 8h desligados 16h.....para simular as epocas do ano, exemplo que no inverno a irradiação do sol são mais curtos, intensidade estará sempre no 100%

 

 

 

Para o tempo de medição dos sensores, estou pensado em usar os segudos do RTC mas estou travado ainda como transformar isso em função/código.

Penso em escrever parecido com o Millis mas utilizando o now.second, acho que estou na linha certa🤣

 

 

 

1 hora atrás, Isadora Ferraz disse:

que até tem ferramentinha semelhante pra isso...

http://easycoding.tn/esp32/demos/code/

Entrei para ver, vou precisar de um tutorial no Youtube, em primeira vista, nao entendi muito.....🙄

 

1 hora atrás, Isadora Ferraz disse:

uma solução wireless com o esp32? Me lembro que já vi um video de um kit hortinha automatizada com irrigadores e etc... bem legal

kkkk ainda nao, wireless seria na versão da estufa 5.0 ..... estou na versão 0.5....kkkkkkkkkk

 

 

Dei uma melhorada no fonte, ainda baseando no millis, fazendo a leitura da temperatura/umidade e a umidade do solo, desconsidere o diagrama acima, pois tive que alterar algumas portas para fazer a leitura analogica.

 

Fonte alterado nas linhas 167 ate 209, comentei mais linhas para ficar o mais claro do que esta acontecendo.

/* =============================================================================================================


============================================================================================================= */


//*************************************************************************************//
//============================= DECLARAÇÃO DE BIBLIOTECAS =============================
#include <LiquidCrystal_I2C.h>                              //BIBLIOTECA DE LCD POR I2C
#include <Wire.h>                                           //BIBLIOTECA PARA COMUNICAÇÃO COM I2C
#include <RTClib.h>                                         //BIBLIOTECA DO RTC DS1307
#include <dht.h>                                            //BIBLIOTECA DO SENSOR DTH
//*************************************************************************************//
//============================= DECLARAÇÃO DE CONSTANTES ==============================
//*************************************************************************************//
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE);
RTC_DS1307 RTC;
dht DHT;
//*************************************************************************************//
//============================= MAPEAMENTO DE HARDWARE ================================
//*************************************************************************************//
#define   bt_dir        2      //BOTÃO DA DIREITA   
#define   bt_esq        3      //BOTÃO DA ESQUERDA
#define   bt_enter      4      //BOTÃO ENTER
#define   bt_down       5      //BOTÃO DOWN
#define   bt_up         6      //BOTÃO UP
#define   bt_esc        7      //BOTÃO ESC
#define   saida         8      //BOMBA DE IRRIGAÇÃO
#define   Relay         10     //RELE LAMPADA
#define   analog_sens   A1     //SENSOR DE UMIDADE DO SOLO
#define   bomba         9      //BOMBA DE IRRIGAÇÃO
#define   DHT11_PIN     12     //SENSOR DTH
//*************************************************************************************//
//============================= DECLARAÇÃO DE VARIAVEIS ===============================
//*************************************************************************************//
byte menu_num = 1, sub_menu = 1;        //FLAGS PARA OS MENUS PRINCIPAIS
byte submenu1 = 1, submenu2 = 1;        //FLAGS PARA OS SUBMENUS
byte t_bt_down, t_bt_up;                //FLAGS PARA ARMAZENAR OS ESTADOS DOS BOTÕES
byte set_full=1;                        //FLAG PARA MANTER O RELÊ LIGADO
int hourupg=0;                          //ARMAZENA HORA     - INICIA COM 0
int minupg=0;                           //ARMAZENA MINUTOS  - INICIA COM 0
int dayupg=1;                           //ARMAZENA DIA      - INICIA COM 1
int monthupg=1;                         //ARMAZENA MÊS      - INICIA COM 1
int yearupg=0;                          //ARMAZENA ANO      - INICIA COM 0
int menu=0;                             //ARMAZENA O ESTADO DO MENU DENTRO DO SWITCH CASE
int set_on=0;                           //ARMAZENA A HORA DE LIGAR O RELÊ
int set_off=0;                          //ARMAZENA A HORA DE DESLOGAR O RELÊ
int adc_value=0;                        //ARMAZENA VALOR DA UMIDADE DO SOLO - INICIA COM 0
int intervalo=2000;                     //INTERVALO DE LEITURA DO SENSOR DTH
int intervalo2=5000;                    //INTERVALO DE LEITURA DO SENSOR DE SOLO
String fotoperiodo;                     //ARMAZENA A STRING DO FOTO PERIODO "24h" , "18h" , "12h" , OFF
String umidade_solo;
unsigned long delayIntervalo;           //ARMAZENA O TEMPO DE COMPARAÇÃO COM MILLIS
unsigned long tempo=0;                  //ARMAZENA 
int level1=350;
int level2=450;
int level3=880;

byte thermometro[8] = {                 //SIMBOLO TERMOMETRO
  B00100,
  B01010,
  B01010,
  B01110,
  B01110,
  B11111,
  B11111,
  B01110};
byte gota[8] = {                       //SIMBOLO GOTA-UMIDADE
  B00100,
  B00100,
  B01110,
  B01110,
  B11111,
  B11111,
  B11111,
  B01110};
byte sol_sym[8] = {                   //SIMBOLO SOL
  B00100,
  B10001,
  B01110,
  B11111,
  B01110,
  B10001,
  B00100,
  B00000
};
//*************************************************************************************//
//============================ CONFIGURAÇÕES DE INICIAIS ==============================
//*************************************************************************************//
void setup() 
{
  pinMode(bt_dir,   INPUT_PULLUP);      //CONFIGURA COMO ENTRADA E SETA RESISTORES DE PULLUP INTERNOS
  pinMode(bt_esq,   INPUT_PULLUP);      //  
  pinMode(bt_enter, INPUT_PULLUP);      //
  pinMode(bt_down,  INPUT_PULLUP);      //
  pinMode(bt_up,    INPUT_PULLUP);      //
  pinMode(bt_esc,   INPUT_PULLUP);      //
  pinMode(analog_sens, INPUT);          //COMFIGURA COMO ENTRADA ANALOGICA
  pinMode(Relay,    OUTPUT);            //CONFIGURA COMO SAIDA
  pinMode(bomba,    OUTPUT);            //CONFIGURA COMO SAIDA
  pinMode(saida,    OUTPUT);            //CONFIGURA COMO SAIDA
   
  lcd.begin(20, 4);                     //INICIA COMUNICAÇÃO COM LCD E SETA LCD20x4
  Wire.begin();                         //INICIA COMUNICAÇÃO WIRE
  RTC.begin();                          //INICIA COMUNICAÇÃO COM MODULO RTC
}                                       //FINAL DO SETUP
//*************************************************************************************//
//============================ CONFIGURAÇÕES DE LOOP ==================================
//*************************************************************************************//
void loop() 
  {
      leitura_temp();                       //CHAMA FUNÇÃO DE LEITURA DE TEMPERATURA
      keyboard();                           //CHAMA FUNÇÃO DE LEITURA DE TECLADO
      read_humidity();                      //CHAMA FUNÇÃO DE LEITURA DE UMIDADE DO SOLO
      switch(menu_num)                      //SWITCH DO MENU
        {
          case 1: resumo(); break;
          case 2: iluminacao(); break;
          case 3: temperatura(); break;
          case 4: umidade(); break;
          case 5: ajuste_relogio(); break;
        }                                   //FINAL DO SWITCH
        

}                                           //FUNAL DO LOOP
//*************************************************************************************//
//=========================== DESENVOLVIMENTO DAS FUNÇÕES =============================
//*************************************************************************************//
void keyboard()
   {
   if(!digitalRead(bt_up))   t_bt_up   = 0x01;          //BOTÃO UP PRESSIONADO? SETA A FLAG
   if(!digitalRead(bt_down)) t_bt_down = 0x01;          //BOTÃO DOWN PRESSIONADO? SETA A FLAG
      
   if(digitalRead(bt_up) && t_bt_up)                    //BOTÃO UP SOLTO E FLAG SETADA?
     {                                                  //SE SIM...
        t_bt_up = 0x00;                                   //LIMPA FLAG
        lcd.clear();                                      //LIMPA LCD
        menu_num++;                                       //INCREMENTA MENU
        
        if(menu_num > 0x05) menu_num = 0x01;              //SE MENU FOR MAIOR QUE 5, MENU VOLTA A SER 1   
     }                                                  //FINAL BOTÃO UP (bt_up)
   
   if(digitalRead(bt_down) && t_bt_down)                //BOTÃO DOWN SOLTO E FLAG SETADA?
     {                                                  //SE SIM...
        t_bt_down = 0x00;                                 //LIMPA FLAG
        lcd.clear();                                      //LIMPA LCD
        menu_num--;                                       //DECREMENTA MENU
        
        if(menu_num < 0x01) menu_num = 0x05;              //SE MENU FOR MENOR QUE 1, MENU VOLTA A SER 5
     }                                                  //FINAL BOTÃO DOWN (bt_down)   
     
   if(!digitalRead(bt_enter))                           //BOTÃO ENTER PRESSIONADO?
     {                                                    //SE SIM...
        delay(150);                                       //AGUARDA 150ms
        lcd.clear();
        if(sub_menu <= 2) sub_menu ++;                    //SE sub_menu FOR MENOR OU IGUAL A 2, INCREMENTA sub_menu
     }                                                  //FINAL BOTÃO ENTER (bt_enter)

   if(!digitalRead(bt_esc))                             //BOTÃO ESC PRESSIONADO?                
     {                                                    //SE SIM...
        delay(150);                                       //AGUARDA 150ms
        if(sub_menu > 0) sub_menu --;                     //SE sub_menu FOR MAIOR QUE 0, DECREMENTA sub_menu
     }                                                  //FINAL BOTÃO ESC (bt_esc)


}                                        //FINAL DA FUNÇÃO KEYBOARD
void leitura_temp()
   {
   if ( (millis() - delayIntervalo) > intervalo ) {     //LEITURA DOS DADOS
        unsigned long start = micros();
        int chk = DHT.read11(DHT11_PIN);       
        unsigned long stop = micros();
        delayIntervalo = millis();
    };
}                                                         //FINAL DA FUNÇÃO LEITURA TEMPERATURA


void read_humidity()
{
  if((millis()- tempo) >= intervalo2)
  {
   tempo = millis();
   adc_value = analogRead(analog_sens); 
  }
 if (adc_value > 0 && adc_value < level1)             //identifica nível de umidade 5
  {
     umidade_solo = String("Umido     ");
     digitalWrite(bomba,LOW);
  } 
  // ================================================================
  else if (adc_value > level1 && adc_value < level2)   //identifica nível de umidade 3
  {
    umidade_solo = String("Umd. Media ");
    digitalWrite(bomba,LOW);
  }
  // ================================================================
  else if (adc_value > level2 && adc_value < level3)   //identifica nível de umidade 2
  {
    umidade_solo = String("Umd. Minima");
    digitalWrite(bomba,HIGH);
  }
  // ================================================================
  else if (adc_value > level3 && adc_value >= 1000)   //identifica nível de umidade 3
  {
    umidade_solo = String("Seco       ");
    digitalWrite(bomba,HIGH);
  }
}


void resumo()                                             //INICIO DA TELA PRINCIPAL
  {
      DateTime now = RTC.now();
      lcd.setCursor(0,0);
      lcd.print("====== ESTUFA ======");    
      lcd.setCursor(0,1);
      if (now.hour()<=9)                                      //SE A HORA FOR MENOR OU IGUAL A 9
        {
          lcd.print("0");                                     //SIM... MOSTRA "0" NA FRENTE 
        }
      lcd.print(now.hour(), DEC);                             //GET HORA DO RTC E MOSTRA NO LCD
      hourupg=now.hour();
      lcd.print(":");                                         //ADICIONA ":" ENTRE HORA E MINUTO
      if (now.minute()<=9)                                    //SE O MINUTO FOR MAIOR OU IGUAL A 9                                    
        {
          lcd.print("0");                                     //SIM... MOSTRA "0" NA FRENTE
        }
      lcd.print(now.minute(), DEC);                           
      minupg=now.minute();                                    //GET MINUTOS DO RTC E MOSTRA NO LCD
      //=====================segundos
      lcd.print(":"); 
      if (now.second()<=9)                                     //SE O DIA FOR MENOR OU IGUAL A 9
        {
          lcd.print("0");                                     //SIM... MOSTRA "0" NA FRENTE
        }
      lcd.print(now.second(), DEC);
      //=====================segundos  
      lcd.setCursor(15, 1);
        if (now.day()<=9)                                     //SE O DIA FOR MENOR OU IGUAL A 9
        {
          lcd.print("0");                                     //SIM... MOSTRA "0" NA FRENTE
        }
      lcd.print(now.day(), DEC);                              
      dayupg=now.day();                                       //GET DIA DO RTC E MOSTRA NO LCD
      lcd.print("/");                                         //ADICIONA "/" ENTRE DIA E MÊS
      if (now.month()<=9)                                     //SE O MÊS FOR MENOR OU IGUAL A 9
        {
          lcd.print("0");                                     //SIM... MOSTRA "0" NA FRENTE
        }
      lcd.print(now.month(), DEC);
      monthupg=now.month();                                   //GET MÊS DO RTC E MOSTRA NO LCD
  
  lcd.createChar(1,thermometro);                              //CRIA CARACTERE DO TERMOMETRO E GRAVA NA POSIÇÃO 1
  lcd.setCursor(1,2);                                         //POSICIONA CURSOR NA COLUNA 2 E LINHA 3
  lcd.write(byte(1));                                         //ESCREVE CARATERE GRAVDO NA POSIÇÃO 1
  lcd.setCursor(2,2);
  lcd.print(DHT.temperature,0);                         //ESCREVE A TEPERATURA NO LCD, SEM CASAS DECIMAIS (temperature,0)
  lcd.setCursor(4,2);
  lcd.write(byte(223));                                       //ESCREVE CARACTERE DE °GRAU
  
  lcd.createChar(2,gota);                                     //CRIA CARACTERE DE "GOTA" E GRAVA NA POSIÇÃO 2
  lcd.setCursor(15,2);
  lcd.write(byte(2));                                         //ESCREVE CARATERE GRAVDO NA POSIÇÃO 2
  lcd.setCursor(16,2);
  lcd.print(DHT.humidity,0);                            //ESCREVE A UMIDADE NO LCD, SEM CASAS DECIMAIS (humidity,0)
  lcd.setCursor(18,2);
  lcd.write("%");                                             //ESCREVE CARACTERE DE PORCENTAGEM

if(now.second() >= 30 && now.second() < 35 ){       //SE HORA FOR MAIOR OU IGUAL A set_on E HORA FOR MENOR QUE set_off
     digitalWrite(Relay, HIGH);                               //SIM... LIGA RELÊ
     }


  lcd.createChar(3,sol_sym);                                  //CRIA CARACTERE DE "SOL" E GRAVA NA POSIÇÃO 3
  lcd.setCursor(8,2);
  lcd.write(byte(3));                                         //ESCREVE CARATERE GRAVDO NA POSIÇÃO 3
  lcd.setCursor(9,2);
  lcd.print(fotoperiodo);                                     //ESCREVE o que ESTA GRAVADO DENTRO DA STRING O QUAL FOTO-PERIODO ESTA SELECIONADO
  
                                                            //INICO TESTE DE UMINDADE DO SOLO
  lcd.setCursor(2,3);
  lcd.print("Solo:");
  lcd.setCursor(8,3);
  lcd.print(umidade_solo); 
  //lcd.setCursor(7,1);
  //lcd.print(adc_value);   
  }
  
void iluminacao()
   {
   switch(sub_menu)
      {
       case 1:
          lcd.setCursor(0,0);                               //APRESENTA A PRIMEIRA TELA DE MENU
          lcd.print(">ILUMINACAO         ");                //ILUMINAÇÃO  
          lcd.setCursor(0,1);
          lcd.print(" TEMPERATURA        ");
          lcd.setCursor(0,2);
          lcd.print(" UMIDADE            ");
          lcd.setCursor(0,3);
          lcd.print(" AJUSTE RELOGIO     ");
          break;
       case 2:                                              //SUBMENU DE ILUMINAÇÃO
          lcd.setCursor(0,0);
          lcd.print("                    ");
          lcd.setCursor(0,1);
          lcd.print("     ILUMINACAO     ");
          lcd.setCursor(0,3);
          lcd.print("                    ");
       switch(submenu1)
            {
            case 1:
            lcd.setCursor(0,2);
            lcd.print("        24h       >");                     //MOSTRA AS opções DE FOTO-PERIODO
            if(!digitalRead(bt_dir)) {delay(150); submenu1 ++;}   //BOTÃO DIREITO PRESSIONADO? SE SIM.. INCREMENTA submenu1
            
            if(!digitalRead(bt_enter)){                           //BOTÃO ENTER PRESSIONADO?
               lcd.clear();                                       //SE SIM... LIMPA LCD
               lcd.setCursor(0,0);
               lcd.print("SALVANDO...");                          //MOSTRA "SALVANDO..." NO LCD
               digitalWrite(Relay, HIGH);                         //LIGA RELÊ
               fotoperiodo = String("24h");                       //GRAVA "24h" DENTRO DA STRING
               delay(200);                                        //AGUARDA 200ms
               set_full=0;                                        //ZERA A FLAG set_full
               submenu2=1;                                        //GRAVA 1 NA FLAG submenu2 PARA SAIR DO SUBMENU
               sub_menu=1;                                        //GRAVA 1 NA FLAG sub_menu PARA SAIR DO SUB_MENU
               menu_num=1;                                        //GRAVA 1 NA FLAG menu_num PARA IR A TELA PRINCIPAL 
              }
            break;
            case 2:
            lcd.setCursor(0,2);
            lcd.print("<       12/12     >");                     //MOSTRA AS opções DE FOTO-PERIODO
            if(!digitalRead(bt_dir)) {delay(150); submenu1 ++;}   //BOTÃO DIREITO PRESSIONADO? SE SIM.. INCREMENTA submenu1
            if(!digitalRead(bt_esq)) {delay(150); submenu1 --;}   //BOTÃO ESQUERDO PRESSIONADO? SE SIM.. DECEMENTA submenu1
            
            if(!digitalRead(bt_enter))
            {
             set_on = 0;
             set_off = 30;
             lcd.clear();
             lcd.setCursor(0,0);
             lcd.print("SALVANDO...");
             fotoperiodo = String("12h");
             delay(200);
             submenu2=1;
             sub_menu=1;
             menu_num=1; 
            }
            break;
            case 3:
            lcd.setCursor(0,2);
            lcd.print("<       16/8      >"); 
            if(!digitalRead(bt_dir)) {delay(150); submenu1 ++;}
            if(!digitalRead(bt_esq)) {delay(150); submenu1 --;}
    
            if(!digitalRead(bt_enter))
            {
             set_on = 6;
             set_off = 50;
             lcd.clear();
             lcd.setCursor(0,0);
             lcd.print("SALVANDO...");
             fotoperiodo = String("18h");
             delay(200);
             submenu2=1;
             sub_menu=1;
             menu_num=1; 
            }
            break;
            case 4:
            lcd.setCursor(0,2);
            lcd.print("<       OFF        "); 
            if(!digitalRead(bt_esq)) {delay(150); submenu1 --;}
    
            if(!digitalRead(bt_enter))
            {
             set_on = 0;
             set_off = 0;
             set_full = 1;
             lcd.clear();
             lcd.setCursor(0,0);
             lcd.print("SALVANDO...");
             fotoperiodo = String("OFF");
             delay(200);
             submenu2=1;
             sub_menu=1;
             menu_num=1; 
            }
            break;
            }         //Final Switch foto-periodo
            break;
      }
    } //Final Switch Iluminação

void temperatura()
{
  switch(sub_menu)
  {
     case 1:
       lcd.setCursor(0,0);
       lcd.print(" ILUMINACAO         ");
       lcd.setCursor(0,1);
       lcd.print(">TEMPERATURA"        );
       lcd.setCursor(0,2);
       lcd.print(" UMIDADE            ");
       lcd.setCursor(0,3);
       lcd.print(" AJUSTE RELOGIO     "); 
       break;
     case 2:
       lcd.setCursor(0,0);
       lcd.print("    Temperatura     ");
       lcd.setCursor(1,2);
       lcd.print("Interno");
       lcd.setCursor(11,2);
       lcd.print("Externo");
       lcd.createChar(1,thermometro);
       lcd.setCursor(2,3);
       lcd.write(byte(1));
       lcd.print(DHT.temperature,0);
       lcd.write(byte(223));
       lcd.print("C");
       lcd.createChar(1,thermometro);
       lcd.setCursor(12,3);
       lcd.write(byte(1));
       lcd.print(DHT.temperature,0);
       lcd.write(byte(223));
       lcd.print("C");
       break;
    }//FINAL SUB_MENU

} //end temperatura


void umidade()
{
  switch(sub_menu)
  {
     case 1:
       lcd.setCursor(0,0);
       lcd.print(" ILUMINACAO         ");
       lcd.setCursor(0,1);
       lcd.print(" TEMPERATURA        ");
       lcd.setCursor(0,2);
       lcd.print(">UMIDADE            ");
       lcd.setCursor(0,3);
       lcd.print(" AJUSTE RELOGIO     ");
       break;
     case 2:
       lcd.setCursor(0,0);
       lcd.print("      Umidade:      ");
       lcd.setCursor(0,2);
       lcd.print("Leitura ADC:");
       lcd.setCursor(13,2);
       lcd.print(adc_value);
       lcd.setCursor(0,3);
       lcd.print(umidade_solo);
       delay(1000);
       lcd.clear();
       break;
  }
  
  
} //end umidade


void ajuste_relogio()
{
  switch(sub_menu)
  {
     case 1:
       lcd.setCursor(0,0);
       lcd.print(" ILUMINACAO         ");
       lcd.setCursor(0,1);
       lcd.print(" TEMPERATURA        ");
       lcd.setCursor(0,2);
       lcd.print(" UMIDADE            ");
       lcd.setCursor(0,3);
       lcd.print(">AJUSTE RELOGIO     ");
       break;
     case 2:
  ajuste_sub();
       break;
  }
} //end ajuste_relogio

void ajuste_sub()
  {
  switch(submenu2)
   {
     case 1:        // ============ AJUSTE DA HORA ===================================
     lcd.clear();
     //DateTime now = RTC.now();
     if(digitalRead(bt_dir)==LOW)    // Se P2 estiver em nivel logico baixo
      {
       if(hourupg==23)          // Se "hourupg" for igual a 23
         {
          hourupg=0;            // "hourupg" passa a ser 0
         }
      else
        {
      hourupg=hourupg+1;        // Se não, incrementa +1 a "hourupg"
        }
      }
       if(digitalRead(bt_esq)==LOW)     // Se P3 estiver em nivel logico baixo
        {
      if(hourupg==0)            // Se "hourupg" for igual a 0
        {
         hourupg=23;            // "hourupg" passa a ser 23
        }
      else
        {
        hourupg=hourupg-1;        // Se não, decrementa -1 a "hourupg"
        }
      }
     lcd.setCursor(0,2);
     lcd.print("Ajustar Hora:       ");// Escreve "Ajustar Hora"
     lcd.setCursor(0,3);
     lcd.print(hourupg,DEC);
     delay(200);
     if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;}
     break;
     case 2:      // ============ AJUSTE DOS MINUTOS =================================
        lcd.clear();
        if(digitalRead(bt_dir)==LOW)    // Se P2 estiver em nivel logico baixo
      {
       if (minupg==59)          // Se "minupg" for igual a 59
          {
           minupg=0;            // "minupg" passa a ser 0
          }
    else
      {
       minupg=minupg+1;         // Se não, incrementa +1 a "minupg"
      }
    }
   if(digitalRead(bt_esq)==LOW)     // Se P3 estiver em nivel logico baixo
     {
      if(minupg==0)             // Se "minupg" for igual a 0
        {
        minupg=59;              // "minupg" passa a ser 59
        }
    else
    {
     minupg=minupg-1;           // Se não, decrementa -1 a "minupg"
    }
  }  lcd.setCursor(0,2);
     lcd.print("Ajustar Minutos:");// Escreve "Ajustar Minutos"
     lcd.setCursor(0,3);
     lcd.print(minupg,DEC);
     delay(200);
     if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;}
     break;
     case 3:        // ============ AJUSTE DIA ======================================
     lcd.clear();
    if(digitalRead(bt_dir)==LOW)    // Se P2 estiver em nivel logico baixo
      {
      if(dayupg==31)            // Se "dayupg" for igual a 31
        {
        dayupg=1;               // "dayupg" passa a ser 1
        }
    else
      {
      dayupg=dayupg+1;          // Se não, incrementa +1 a "dayupg"
      }
    }
   if(digitalRead(bt_esq)==LOW)     // Se P3 estiver em nivel logico baixo
     {
     if(dayupg==1)              // Se "dayupg" for igual a 1
        {
        dayupg=31;              // "dayupg" passa a ser 31 
        }
   else
     {
     dayupg=dayupg-1;           // se não, decrementa 11 a "dayupg"
     }
  }
     lcd.setCursor(0,2);
     lcd.print("Ajustar Dia:");// Escreve "Ajustar dia"
     lcd.setCursor(0,3);
     lcd.print(dayupg,DEC);
     delay(200);
     if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;}
     break;
     case 4:    // ============ AJUSTE MÊS ===========================================
     lcd.clear();
    if(digitalRead(bt_dir)==LOW)    // Se P2 estiver em nivel logico baixo
      {
      if(monthupg==12)          // Se "monthupg" for igual a 12
        {
        monthupg=1;             // "monthupg" passa a ser 1
        }
    else
      {
      monthupg=monthupg+1;      // Se não, incrementa +1 a "monthupg"
      }
    }
   if(digitalRead(bt_esq)==LOW)     // Se P3 estiver em nivel logico baixo
      {
      if(monthupg==1)           // Se "monthupg" for igual a 1
        {
        monthupg=12;            // "monthupg" passa a ser 12
        }
    else
      {
      monthupg=monthupg-1;      // Se não, decrementa -1 a "monthupg"
      }
      }
     lcd.setCursor(0,2);
     lcd.print("Ajustar Mes:");    // Escreve "Ajustar Mes"
     lcd.setCursor(0,3);
     lcd.print(monthupg,DEC);
     delay(200);
     if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;}
     break;
     case 5:    // ============ AJUSTAR ANO ===================================
     lcd.clear();
    if(digitalRead(bt_dir)==LOW)    // Se P2 estiver em nivel logico baixo
      {    
      yearupg=yearupg+1;        // Incrementa +1 a "yearupg"
      }
   if(digitalRead(bt_esq)==LOW)     // Se P3 estiver em nivel logico baixo
      {
      yearupg=yearupg-1;        // Decrementa -1 a "yearupg"
      }
  lcd.setCursor(0,0);           // Posiciona o cursor na coluna 0 e linha 0
  lcd.print("Ajustar Ano:");    // Escreve "Ajustar Ano"
  lcd.setCursor(0,1);
  lcd.print(yearupg,DEC);
  delay(200);
    if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;}
     break;
     
     case 6:
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("SALVANDO...");
     RTC.adjust(DateTime(yearupg,monthupg,dayupg,hourupg,minupg,0)); // Grava os dados no RTC
     delay(200);
     submenu2=1;
     sub_menu=1;
     menu_num=1;
     break;
  } //end switch
    
} 

Tudo "funcionando" mas com o risco do estouro do Millis:

IMG_20200402_105819644_HDR.thumb.jpg.0e61ede39bbc78b0940941f2f5527bf2.jpgIMG_20200402_105824806_HDR.thumb.jpg.f08d8bcb9c71892f4b9527c034acb2b6.jpg

 

Não sei se o Forum permite eu fazer um video com o funcionamento do menu e do projeto em funcionamento , se posso upar diretamente aqui na pagina ou tenho que carregar no YouTube como "não listado" e postar o link aqui.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
1 hora atrás, Bruno R Ruinho disse:

nao entendi muito

Eu entendi nada kk.

1 hora atrás, Bruno R Ruinho disse:

carregar no YouTube como "não listado" e postar o link aqui.

Me parece ser a melhor opção
Tem lôco pra tudo mas penso que poucos hão de analisar seu código todo.. o que nada impede de compartilhar, claro. Uma opção caminho do meio é você publicar apenas a parte com problema

Não sei se tem botão pra isso mas opte por colocar o tag [ s p o i l e r ] e [ / s p o i l e r ] sem espaços entre texto longo... Algo como

 
1 hora atrás, Bruno R Ruinho disse:

Erro meu, este que desenhei é o de umidade do ar e temp, o higrometro eu nao encontrei, estava apanhando do Fritzing

 

Eu me expressei mal, as luzes só vão ter o controle de tempo, ligada 24Horas, / ligada 12horas desligada 12horas / ligado 8h desligados 16h.....para simular as epocas do ano, exemplo que no inverno a irradiação do sol são mais curtos, intensidade estará sempre no 100%

 

 

 

Para o tempo de medição dos sensores, estou pensado em usar os segudos do RTC mas estou travado ainda como transformar isso em função/código.

Penso em escrever parecido com o Millis mas utilizando o now.second, acho que estou na linha certa🤣

 

 

 

Entrei para ver, vou precisar de um tutorial no Youtube, em primeira vista, nao entendi muito.....🙄

 

kkkk ainda nao, wireless seria na versão da estufa 5.0 ..... estou na versão 0.5....kkkkkkkkkk

 

 

Dei uma melhorada no fonte, ainda baseando no millis, fazendo a leitura da temperatura/umidade e a umidade do solo, desconsidere o diagrama acima, pois tive que alterar algumas portas para fazer a leitura analogica.

 

Fonte alterado nas linhas 167 ate 209, comentei mais linhas para ficar o mais claro do que esta acontecendo.

/* ============================================================================================================= ============================================================================================================= */ //*************************************************************************************// //============================= DECLARAÇÃO DE BIBLIOTECAS ============================= #include <LiquidCrystal_I2C.h> //BIBLIOTECA DE LCD POR I2C #include <Wire.h> //BIBLIOTECA PARA COMUNICAÇÃO COM I2C #include <RTClib.h> //BIBLIOTECA DO RTC DS1307 #include <dht.h> //BIBLIOTECA DO SENSOR DTH //*************************************************************************************// //============================= DECLARAÇÃO DE CONSTANTES ============================== //*************************************************************************************// LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3, POSITIVE); RTC_DS1307 RTC; dht DHT; //*************************************************************************************// //============================= MAPEAMENTO DE HARDWARE ================================ //*************************************************************************************// #define bt_dir 2 //BOTÃO DA DIREITA #define bt_esq 3 //BOTÃO DA ESQUERDA #define bt_enter 4 //BOTÃO ENTER #define bt_down 5 //BOTÃO DOWN #define bt_up 6 //BOTÃO UP #define bt_esc 7 //BOTÃO ESC #define saida 8 //BOMBA DE IRRIGAÇÃO #define Relay 10 //RELE LAMPADA #define analog_sens A1 //SENSOR DE UMIDADE DO SOLO #define bomba 9 //BOMBA DE IRRIGAÇÃO #define DHT11_PIN 12 //SENSOR DTH //*************************************************************************************// //============================= DECLARAÇÃO DE VARIAVEIS =============================== //*************************************************************************************// byte menu_num = 1, sub_menu = 1; //FLAGS PARA OS MENUS PRINCIPAIS byte submenu1 = 1, submenu2 = 1; //FLAGS PARA OS SUBMENUS byte t_bt_down, t_bt_up; //FLAGS PARA ARMAZENAR OS ESTADOS DOS BOTÕES byte set_full=1; //FLAG PARA MANTER O RELÊ LIGADO int hourupg=0; //ARMAZENA HORA - INICIA COM 0 int minupg=0; //ARMAZENA MINUTOS - INICIA COM 0 int dayupg=1; //ARMAZENA DIA - INICIA COM 1 int monthupg=1; //ARMAZENA MÊS - INICIA COM 1 int yearupg=0; //ARMAZENA ANO - INICIA COM 0 int menu=0; //ARMAZENA O ESTADO DO MENU DENTRO DO SWITCH CASE int set_on=0; //ARMAZENA A HORA DE LIGAR O RELÊ int set_off=0; //ARMAZENA A HORA DE DESLOGAR O RELÊ int adc_value=0; //ARMAZENA VALOR DA UMIDADE DO SOLO - INICIA COM 0 int intervalo=2000; //INTERVALO DE LEITURA DO SENSOR DTH int intervalo2=5000; //INTERVALO DE LEITURA DO SENSOR DE SOLO String fotoperiodo; //ARMAZENA A STRING DO FOTO PERIODO "24h" , "18h" , "12h" , OFF String umidade_solo; unsigned long delayIntervalo; //ARMAZENA O TEMPO DE COMPARAÇÃO COM MILLIS unsigned long tempo=0; //ARMAZENA int level1=350; int level2=450; int level3=880; byte thermometro[8] = { //SIMBOLO TERMOMETRO B00100, B01010, B01010, B01110, B01110, B11111, B11111, B01110}; byte gota[8] = { //SIMBOLO GOTA-UMIDADE B00100, B00100, B01110, B01110, B11111, B11111, B11111, B01110}; byte sol_sym[8] = { //SIMBOLO SOL B00100, B10001, B01110, B11111, B01110, B10001, B00100, B00000 }; //*************************************************************************************// //============================ CONFIGURAÇÕES DE INICIAIS ============================== //*************************************************************************************// void setup() { pinMode(bt_dir, INPUT_PULLUP); //CONFIGURA COMO ENTRADA E SETA RESISTORES DE PULLUP INTERNOS pinMode(bt_esq, INPUT_PULLUP); // pinMode(bt_enter, INPUT_PULLUP); // pinMode(bt_down, INPUT_PULLUP); // pinMode(bt_up, INPUT_PULLUP); // pinMode(bt_esc, INPUT_PULLUP); // pinMode(analog_sens, INPUT); //COMFIGURA COMO ENTRADA ANALOGICA pinMode(Relay, OUTPUT); //CONFIGURA COMO SAIDA pinMode(bomba, OUTPUT); //CONFIGURA COMO SAIDA pinMode(saida, OUTPUT); //CONFIGURA COMO SAIDA lcd.begin(20, 4); //INICIA COMUNICAÇÃO COM LCD E SETA LCD20x4 Wire.begin(); //INICIA COMUNICAÇÃO WIRE RTC.begin(); //INICIA COMUNICAÇÃO COM MODULO RTC } //FINAL DO SETUP //*************************************************************************************// //============================ CONFIGURAÇÕES DE LOOP ================================== //*************************************************************************************// void loop() { leitura_temp(); //CHAMA FUNÇÃO DE LEITURA DE TEMPERATURA keyboard(); //CHAMA FUNÇÃO DE LEITURA DE TECLADO read_humidity(); //CHAMA FUNÇÃO DE LEITURA DE UMIDADE DO SOLO switch(menu_num) //SWITCH DO MENU { case 1: resumo(); break; case 2: iluminacao(); break; case 3: temperatura(); break; case 4: umidade(); break; case 5: ajuste_relogio(); break; } //FINAL DO SWITCH } //FUNAL DO LOOP //*************************************************************************************// //=========================== DESENVOLVIMENTO DAS FUNÇÕES ============================= //*************************************************************************************// void keyboard() { if(!digitalRead(bt_up)) t_bt_up = 0x01; //BOTÃO UP PRESSIONADO? SETA A FLAG if(!digitalRead(bt_down)) t_bt_down = 0x01; //BOTÃO DOWN PRESSIONADO? SETA A FLAG if(digitalRead(bt_up) && t_bt_up) //BOTÃO UP SOLTO E FLAG SETADA? { //SE SIM... t_bt_up = 0x00; //LIMPA FLAG lcd.clear(); //LIMPA LCD menu_num++; //INCREMENTA MENU if(menu_num > 0x05) menu_num = 0x01; //SE MENU FOR MAIOR QUE 5, MENU VOLTA A SER 1 } //FINAL BOTÃO UP (bt_up) if(digitalRead(bt_down) && t_bt_down) //BOTÃO DOWN SOLTO E FLAG SETADA? { //SE SIM... t_bt_down = 0x00; //LIMPA FLAG lcd.clear(); //LIMPA LCD menu_num--; //DECREMENTA MENU if(menu_num < 0x01) menu_num = 0x05; //SE MENU FOR MENOR QUE 1, MENU VOLTA A SER 5 } //FINAL BOTÃO DOWN (bt_down) if(!digitalRead(bt_enter)) //BOTÃO ENTER PRESSIONADO? { //SE SIM... delay(150); //AGUARDA 150ms lcd.clear(); if(sub_menu <= 2) sub_menu ++; //SE sub_menu FOR MENOR OU IGUAL A 2, INCREMENTA sub_menu } //FINAL BOTÃO ENTER (bt_enter) if(!digitalRead(bt_esc)) //BOTÃO ESC PRESSIONADO? { //SE SIM... delay(150); //AGUARDA 150ms if(sub_menu > 0) sub_menu --; //SE sub_menu FOR MAIOR QUE 0, DECREMENTA sub_menu } //FINAL BOTÃO ESC (bt_esc) } //FINAL DA FUNÇÃO KEYBOARD void leitura_temp() { if ( (millis() - delayIntervalo) > intervalo ) { //LEITURA DOS DADOS unsigned long start = micros(); int chk = DHT.read11(DHT11_PIN); unsigned long stop = micros(); delayIntervalo = millis(); }; } //FINAL DA FUNÇÃO LEITURA TEMPERATURA void read_humidity() { if((millis()- tempo) >= intervalo2) { tempo = millis(); adc_value = analogRead(analog_sens); } if (adc_value > 0 && adc_value < level1) //identifica nível de umidade 5 { umidade_solo = String("Umido "); digitalWrite(bomba,LOW); } // ================================================================ else if (adc_value > level1 && adc_value < level2) //identifica nível de umidade 3 { umidade_solo = String("Umd. Media "); digitalWrite(bomba,LOW); } // ================================================================ else if (adc_value > level2 && adc_value < level3) //identifica nível de umidade 2 { umidade_solo = String("Umd. Minima"); digitalWrite(bomba,HIGH); } // ================================================================ else if (adc_value > level3 && adc_value >= 1000) //identifica nível de umidade 3 { umidade_solo = String("Seco "); digitalWrite(bomba,HIGH); } } void resumo() //INICIO DA TELA PRINCIPAL { DateTime now = RTC.now(); lcd.setCursor(0,0); lcd.print("====== ESTUFA ======"); lcd.setCursor(0,1); if (now.hour()<=9) //SE A HORA FOR MENOR OU IGUAL A 9 { lcd.print("0"); //SIM... MOSTRA "0" NA FRENTE } lcd.print(now.hour(), DEC); //GET HORA DO RTC E MOSTRA NO LCD hourupg=now.hour(); lcd.print(":"); //ADICIONA ":" ENTRE HORA E MINUTO if (now.minute()<=9) //SE O MINUTO FOR MAIOR OU IGUAL A 9 { lcd.print("0"); //SIM... MOSTRA "0" NA FRENTE } lcd.print(now.minute(), DEC); minupg=now.minute(); //GET MINUTOS DO RTC E MOSTRA NO LCD //=====================segundos lcd.print(":"); if (now.second()<=9) //SE O DIA FOR MENOR OU IGUAL A 9 { lcd.print("0"); //SIM... MOSTRA "0" NA FRENTE } lcd.print(now.second(), DEC); //=====================segundos lcd.setCursor(15, 1); if (now.day()<=9) //SE O DIA FOR MENOR OU IGUAL A 9 { lcd.print("0"); //SIM... MOSTRA "0" NA FRENTE } lcd.print(now.day(), DEC); dayupg=now.day(); //GET DIA DO RTC E MOSTRA NO LCD lcd.print("/"); //ADICIONA "/" ENTRE DIA E MÊS if (now.month()<=9) //SE O MÊS FOR MENOR OU IGUAL A 9 { lcd.print("0"); //SIM... MOSTRA "0" NA FRENTE } lcd.print(now.month(), DEC); monthupg=now.month(); //GET MÊS DO RTC E MOSTRA NO LCD lcd.createChar(1,thermometro); //CRIA CARACTERE DO TERMOMETRO E GRAVA NA POSIÇÃO 1 lcd.setCursor(1,2); //POSICIONA CURSOR NA COLUNA 2 E LINHA 3 lcd.write(byte(1)); //ESCREVE CARATERE GRAVDO NA POSIÇÃO 1 lcd.setCursor(2,2); lcd.print(DHT.temperature,0); //ESCREVE A TEPERATURA NO LCD, SEM CASAS DECIMAIS (temperature,0) lcd.setCursor(4,2); lcd.write(byte(223)); //ESCREVE CARACTERE DE °GRAU lcd.createChar(2,gota); //CRIA CARACTERE DE "GOTA" E GRAVA NA POSIÇÃO 2 lcd.setCursor(15,2); lcd.write(byte(2)); //ESCREVE CARATERE GRAVDO NA POSIÇÃO 2 lcd.setCursor(16,2); lcd.print(DHT.humidity,0); //ESCREVE A UMIDADE NO LCD, SEM CASAS DECIMAIS (humidity,0) lcd.setCursor(18,2); lcd.write("%"); //ESCREVE CARACTERE DE PORCENTAGEM if(now.second() >= 30 && now.second() < 35 ){ //SE HORA FOR MAIOR OU IGUAL A set_on E HORA FOR MENOR QUE set_off digitalWrite(Relay, HIGH); //SIM... LIGA RELÊ } lcd.createChar(3,sol_sym); //CRIA CARACTERE DE "SOL" E GRAVA NA POSIÇÃO 3 lcd.setCursor(8,2); lcd.write(byte(3)); //ESCREVE CARATERE GRAVDO NA POSIÇÃO 3 lcd.setCursor(9,2); lcd.print(fotoperiodo); //ESCREVE o que ESTA GRAVADO DENTRO DA STRING O QUAL FOTO-PERIODO ESTA SELECIONADO //INICO TESTE DE UMINDADE DO SOLO lcd.setCursor(2,3); lcd.print("Solo:"); lcd.setCursor(8,3); lcd.print(umidade_solo); //lcd.setCursor(7,1); //lcd.print(adc_value); } void iluminacao() { switch(sub_menu) { case 1: lcd.setCursor(0,0); //APRESENTA A PRIMEIRA TELA DE MENU lcd.print(">ILUMINACAO "); //ILUMINAÇÃO lcd.setCursor(0,1); lcd.print(" TEMPERATURA "); lcd.setCursor(0,2); lcd.print(" UMIDADE "); lcd.setCursor(0,3); lcd.print(" AJUSTE RELOGIO "); break; case 2: //SUBMENU DE ILUMINAÇÃO lcd.setCursor(0,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" ILUMINACAO "); lcd.setCursor(0,3); lcd.print(" "); switch(submenu1) { case 1: lcd.setCursor(0,2); lcd.print(" 24h >"); //MOSTRA AS opções DE FOTO-PERIODO if(!digitalRead(bt_dir)) {delay(150); submenu1 ++;} //BOTÃO DIREITO PRESSIONADO? SE SIM.. INCREMENTA submenu1 if(!digitalRead(bt_enter)){ //BOTÃO ENTER PRESSIONADO? lcd.clear(); //SE SIM... LIMPA LCD lcd.setCursor(0,0); lcd.print("SALVANDO..."); //MOSTRA "SALVANDO..." NO LCD digitalWrite(Relay, HIGH); //LIGA RELÊ fotoperiodo = String("24h"); //GRAVA "24h" DENTRO DA STRING delay(200); //AGUARDA 200ms set_full=0; //ZERA A FLAG set_full submenu2=1; //GRAVA 1 NA FLAG submenu2 PARA SAIR DO SUBMENU sub_menu=1; //GRAVA 1 NA FLAG sub_menu PARA SAIR DO SUB_MENU menu_num=1; //GRAVA 1 NA FLAG menu_num PARA IR A TELA PRINCIPAL } break; case 2: lcd.setCursor(0,2); lcd.print("< 12/12 >"); //MOSTRA AS opções DE FOTO-PERIODO if(!digitalRead(bt_dir)) {delay(150); submenu1 ++;} //BOTÃO DIREITO PRESSIONADO? SE SIM.. INCREMENTA submenu1 if(!digitalRead(bt_esq)) {delay(150); submenu1 --;} //BOTÃO ESQUERDO PRESSIONADO? SE SIM.. DECEMENTA submenu1 if(!digitalRead(bt_enter)) { set_on = 0; set_off = 30; lcd.clear(); lcd.setCursor(0,0); lcd.print("SALVANDO..."); fotoperiodo = String("12h"); delay(200); submenu2=1; sub_menu=1; menu_num=1; } break; case 3: lcd.setCursor(0,2); lcd.print("< 16/8 >"); if(!digitalRead(bt_dir)) {delay(150); submenu1 ++;} if(!digitalRead(bt_esq)) {delay(150); submenu1 --;} if(!digitalRead(bt_enter)) { set_on = 6; set_off = 50; lcd.clear(); lcd.setCursor(0,0); lcd.print("SALVANDO..."); fotoperiodo = String("18h"); delay(200); submenu2=1; sub_menu=1; menu_num=1; } break; case 4: lcd.setCursor(0,2); lcd.print("< OFF "); if(!digitalRead(bt_esq)) {delay(150); submenu1 --;} if(!digitalRead(bt_enter)) { set_on = 0; set_off = 0; set_full = 1; lcd.clear(); lcd.setCursor(0,0); lcd.print("SALVANDO..."); fotoperiodo = String("OFF"); delay(200); submenu2=1; sub_menu=1; menu_num=1; } break; } //Final Switch foto-periodo break; } } //Final Switch Iluminação void temperatura() { switch(sub_menu) { case 1: lcd.setCursor(0,0); lcd.print(" ILUMINACAO "); lcd.setCursor(0,1); lcd.print(">TEMPERATURA" ); lcd.setCursor(0,2); lcd.print(" UMIDADE "); lcd.setCursor(0,3); lcd.print(" AJUSTE RELOGIO "); break; case 2: lcd.setCursor(0,0); lcd.print(" Temperatura "); lcd.setCursor(1,2); lcd.print("Interno"); lcd.setCursor(11,2); lcd.print("Externo"); lcd.createChar(1,thermometro); lcd.setCursor(2,3); lcd.write(byte(1)); lcd.print(DHT.temperature,0); lcd.write(byte(223)); lcd.print("C"); lcd.createChar(1,thermometro); lcd.setCursor(12,3); lcd.write(byte(1)); lcd.print(DHT.temperature,0); lcd.write(byte(223)); lcd.print("C"); break; }//FINAL SUB_MENU } //end temperatura void umidade() { switch(sub_menu) { case 1: lcd.setCursor(0,0); lcd.print(" ILUMINACAO "); lcd.setCursor(0,1); lcd.print(" TEMPERATURA "); lcd.setCursor(0,2); lcd.print(">UMIDADE "); lcd.setCursor(0,3); lcd.print(" AJUSTE RELOGIO "); break; case 2: lcd.setCursor(0,0); lcd.print(" Umidade: "); lcd.setCursor(0,2); lcd.print("Leitura ADC:"); lcd.setCursor(13,2); lcd.print(adc_value); lcd.setCursor(0,3); lcd.print(umidade_solo); delay(1000); lcd.clear(); break; } } //end umidade void ajuste_relogio() { switch(sub_menu) { case 1: lcd.setCursor(0,0); lcd.print(" ILUMINACAO "); lcd.setCursor(0,1); lcd.print(" TEMPERATURA "); lcd.setCursor(0,2); lcd.print(" UMIDADE "); lcd.setCursor(0,3); lcd.print(">AJUSTE RELOGIO "); break; case 2: ajuste_sub(); break; } } //end ajuste_relogio void ajuste_sub() { switch(submenu2) { case 1: // ============ AJUSTE DA HORA =================================== lcd.clear(); //DateTime now = RTC.now(); if(digitalRead(bt_dir)==LOW) // Se P2 estiver em nivel logico baixo { if(hourupg==23) // Se "hourupg" for igual a 23 { hourupg=0; // "hourupg" passa a ser 0 } else { hourupg=hourupg+1; // Se não, incrementa +1 a "hourupg" } } if(digitalRead(bt_esq)==LOW) // Se P3 estiver em nivel logico baixo { if(hourupg==0) // Se "hourupg" for igual a 0 { hourupg=23; // "hourupg" passa a ser 23 } else { hourupg=hourupg-1; // Se não, decrementa -1 a "hourupg" } } lcd.setCursor(0,2); lcd.print("Ajustar Hora: ");// Escreve "Ajustar Hora" lcd.setCursor(0,3); lcd.print(hourupg,DEC); delay(200); if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;} break; case 2: // ============ AJUSTE DOS MINUTOS ================================= lcd.clear(); if(digitalRead(bt_dir)==LOW) // Se P2 estiver em nivel logico baixo { if (minupg==59) // Se "minupg" for igual a 59 { minupg=0; // "minupg" passa a ser 0 } else { minupg=minupg+1; // Se não, incrementa +1 a "minupg" } } if(digitalRead(bt_esq)==LOW) // Se P3 estiver em nivel logico baixo { if(minupg==0) // Se "minupg" for igual a 0 { minupg=59; // "minupg" passa a ser 59 } else { minupg=minupg-1; // Se não, decrementa -1 a "minupg" } } lcd.setCursor(0,2); lcd.print("Ajustar Minutos:");// Escreve "Ajustar Minutos" lcd.setCursor(0,3); lcd.print(minupg,DEC); delay(200); if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;} break; case 3: // ============ AJUSTE DIA ====================================== lcd.clear(); if(digitalRead(bt_dir)==LOW) // Se P2 estiver em nivel logico baixo { if(dayupg==31) // Se "dayupg" for igual a 31 { dayupg=1; // "dayupg" passa a ser 1 } else { dayupg=dayupg+1; // Se não, incrementa +1 a "dayupg" } } if(digitalRead(bt_esq)==LOW) // Se P3 estiver em nivel logico baixo { if(dayupg==1) // Se "dayupg" for igual a 1 { dayupg=31; // "dayupg" passa a ser 31 } else { dayupg=dayupg-1; // se não, decrementa 11 a "dayupg" } } lcd.setCursor(0,2); lcd.print("Ajustar Dia:");// Escreve "Ajustar dia" lcd.setCursor(0,3); lcd.print(dayupg,DEC); delay(200); if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;} break; case 4: // ============ AJUSTE MÊS =========================================== lcd.clear(); if(digitalRead(bt_dir)==LOW) // Se P2 estiver em nivel logico baixo { if(monthupg==12) // Se "monthupg" for igual a 12 { monthupg=1; // "monthupg" passa a ser 1 } else { monthupg=monthupg+1; // Se não, incrementa +1 a "monthupg" } } if(digitalRead(bt_esq)==LOW) // Se P3 estiver em nivel logico baixo { if(monthupg==1) // Se "monthupg" for igual a 1 { monthupg=12; // "monthupg" passa a ser 12 } else { monthupg=monthupg-1; // Se não, decrementa -1 a "monthupg" } } lcd.setCursor(0,2); lcd.print("Ajustar Mes:"); // Escreve "Ajustar Mes" lcd.setCursor(0,3); lcd.print(monthupg,DEC); delay(200); if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;} break; case 5: // ============ AJUSTAR ANO =================================== lcd.clear(); if(digitalRead(bt_dir)==LOW) // Se P2 estiver em nivel logico baixo { yearupg=yearupg+1; // Incrementa +1 a "yearupg" } if(digitalRead(bt_esq)==LOW) // Se P3 estiver em nivel logico baixo { yearupg=yearupg-1; // Decrementa -1 a "yearupg" } lcd.setCursor(0,0); // Posiciona o cursor na coluna 0 e linha 0 lcd.print("Ajustar Ano:"); // Escreve "Ajustar Ano" lcd.setCursor(0,1); lcd.print(yearupg,DEC); delay(200); if(!digitalRead(bt_enter)) {delay(150); submenu2 ++;} break; case 6: lcd.clear(); lcd.setCursor(0,0); lcd.print("SALVANDO..."); RTC.adjust(DateTime(yearupg,monthupg,dayupg,hourupg,minupg,0)); // Grava os dados no RTC delay(200); submenu2=1; sub_menu=1; menu_num=1; break; } //end switch }

Tudo "funcionando" mas com o risco do estouro do Millis:

IMG_20200402_105819644_HDR.thumb.jpg.0e61ede39bbc78b0940941f2f5527bf2.jpgIMG_20200402_105824806_HDR.thumb.jpg.f08d8bcb9c71892f4b9527c034acb2b6.jpg

 

Não sei se o Forum permite eu fazer um video com o funcionamento do menu e do projeto em funcionamento , se posso upar diretamente aqui na pagina ou tenho que carregar no YouTube como "não listado" e postar o link aqui.

 

Ou melhor.. o texto longo entre os tags.. O problema é que desfigura o que estiver no tag < c o d e >.  Me lembro de ter conseguido contornar mas é meio tramposo

Link para o comentário
Compartilhar em outros sites

Vou fazer o video e posto aqui, mas ainda segue a minha duvida, o trecho do codigo>>>

void leitura_temp()
   {
   if ((millis() - delayIntervalo) > intervalo) {       //delayIntervalo => ARMAZENA O TEMPO DE COMPARAÇÃO COM MILLIS 
        unsigned long start = micros();                 //intervalo=> INTERVALO DE LEITURA DO SENSOR DTH - esta setado para 2000ms
        int chk = DHT.read11(DHT11_PIN);       
        unsigned long stop = micros();
        delayIntervalo = millis();
    };
}                                                         //FINAL DA FUNÇÃO LEITURA TEMPERATURA

porém ao final de ~48 dias vai acontecer o ovewflow e será zerada, mas a minha variavel delayIntervalo estará carregada com o ultimo valor de millis, sendo assim a leitura ficará travada, assim como todo o resto que esta usando o millis.

 

Já vi exemplos que usam o Timer1 com interrupção por overflow. Mas nao faço ideia.....

 

Tem o RTC no circuito mas não faço ideia de como utilizar o tempo dele (imagino que dos segundos) para fazer a leitura do sensor.

 

E dar um reset no Arduino antes do Millis estourar?

 

Link para o comentário
Compartilhar em outros sites

@Bruno R Ruinho ,

 

45 minutos atrás, Bruno R Ruinho disse:

 

Já vi exemplos que usam o Timer1 com interrupção por overflow. Mas nao faço ideia.....

 

Tem o RTC no circuito mas não faço ideia de como utilizar o tempo dele (imagino que dos segundos) para fazer a leitura do sensor.

 

Como você tem o RTC, voce pode usar a saida dele de 1 Hz e ligar no seu Arduino na INT0 , assim a cada segundo do RTC gera uma interrupção, e com ela você faz a sua base de tempo, simplesmente incrementando um contador a cada interrupção.

Ai você compara o valor desse contador com o tempo desejado, e pronto.

 

Paulo

 

 

  • Haha 1
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
10 horas atrás, Bruno R Ruinho disse:

Timer1 com interrupção por overflow. Mas nao faço ideia.....

 

10 horas atrás, Bruno R Ruinho disse:

Tem o RTC no circuito mas não faço ideia

Seu problema está resumido acima. Passe a fazer ideia primeiro pow! Esquece esta pohhha de milis.

  • Curtir 1
  • Haha 1
Link para o comentário
Compartilhar em outros sites

Obrigado pelos esclarecimentos!!

 

Consegui fazer o RTC me retornar 1Hz:🤩

 RTC.writeSqwPinMode(DS1307_SquareWave1HZ);

mas ainda tenho um problema, a interrupção acontece pois o led no pino 10 fica mudando de estado, mas a leitura do sensor DHT não atualiza....

attachInterrupt(0,leitura_temp,RISING); 

void leitura_temp()
   {
       DHT1.read11(DHT11_PIN);
     
      digitalWrite(10, !digitalRead(10));      
    }

 

  • Confuso 1
Link para o comentário
Compartilhar em outros sites

não estava dando certo pois estava colocando ações muito longa dentro da interrupção. 

 

então modifiquei para ficar parecido com a função do millis>

//============================= declaração de variaveis ===============================
//*************************************************************************************//
unsigned int sensor_dht=0;          //armazena o contador de tempetarura/umidade
unsigned int temp_dht=2;            //armazena o tempo de leiura da temperatura

//============================ configurações de iniciais ==============================
//*************************************************************************************//
  pinmode(2,input);                     //entrada do sinal de interrupção do rtc
  rtc.writesqwpinmode(ds1307_squarewave1hz);  // seta o pino sqw do rtc para frequencia de 1hz
  attachinterrupt(0,leitura_sensor,rising);   // interrupção do rtc no pino 2

//============================ configurações de loop ==================================
//*************************************************************************************//
void loop(){
         if(sensor_dht >= temp_dht){         //se "sensor" é maior ou igual a "temp_dht"
           dht1.read11(dht11_pin);           //se sim, le o sensor dht
           sensor_dht = 0;                   //zera a variavel
           }
  
     lcd.createchar(1,thermometro);                        //cria caractere do termometro e grava na posição 1
     lcd.setcursor(1,2);                                   //posiciona cursor na coluna 2 e linha 3
     lcd.write(byte(1));                                   //escreve caratere gravdo na posição 1
     lcd.setcursor(2,2);
     lcd.print(dht1.temperature,0);                        //escreve a teperatura no lcd, sem casas decimais (temperature,0)
     lcd.setcursor(4,2);
     lcd.write(byte(223));                                 //escreve caractere de °grau
  
     lcd.createchar(2,gota);                               //cria caractere de "gota" e grava na posição 2
     lcd.setcursor(15,2);
     lcd.write(byte(2));                                   //escreve caratere gravdo na posição 2
     lcd.setcursor(16,2);
     lcd.print(dht1.humidity,0);                           //escreve a umidade no lcd, sem casas decimais (humidity,0)
     lcd.setcursor(18,2);
     lcd.write("%");                                       //escreve caractere de porcentagem
}

void leitura_sensor(){                      //FUNÇÃO DA INTERRUPÇÃO
       sensor_dht++;                        //INCREMENTA +1 A VARIAVEL
   }                            //FINAL DA FUNÇÃO DE INTERRUPÇÃO

 

funcionando perfeitamente, faz a leitura a cada 2 segundos!

 

obrigado a todos!

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...

@Bruno R Ruinho eu fiz uma aplicação uma vez que usava o micros() que o overflow acontece em 70 minutos e poderia explodir o equipamento... quando se usa o micros() ou millis() voce deve ter em mente que são uma variavel long que sempre sera positivo o resultado, ou seja, quando resetar o contador e você subtrair o valor do intervalo anterior o resultado sera gigantesco, basta voce fazer uma simples protecao antes do seu if:

 

voce verifica se millis()-delay_intervalo é maior que o intervalo+10 (coloquei 10 para ter uma margem de segurança e processar, mas no seu caso essa diferença passara de 1 milhao) se for maior, o delay_intervalo passara a ser = millis() entao você reseta ele, e após 2 segundos no seu caso o processamento ocorrerá normalmente!

 

sempre que trabalhar com contadores que resetam voce precisa disso, e outra coisa vamos aprofundar no assunto: vamos supor que voce precise de precisão extrema e a partir dos millis() você tenha que realizar uma matemática complexa. Quando o valor millis() for pequeno voce processa rápido, a medida que ele sobe as coisas complicam, imagina se ele nao estourasse, seu programa iria estourar o tamanho das variaveis tentando salvar digitos cada vez maiores e ficaria lerdo.

 

Nesse caso assim que millis atingisse um valor grande  para seu processamento e velocidade voce poderia resetar ele e usar a mesma logica acima que passei.

 

Caso tenha duvidas de uma olhada nisso: https://www.norwegiancreations.com/2018/10/arduino-tutorial-avoiding-the-overflow-issue-when-using-millis-and-micros/

 

@Isadora Ferraz analise zip kkkkkkkk eu dou risada de verdade lendo seus comentarios otimo senso de humor 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Em 26/04/2020 às 05:24, mlegnari disse:

@Bruno R Ruinho eu fiz uma aplicação uma vez que usava o micros() que o overflow acontece em 70 minutos e poderia explodir o equipamento... quando se usa o micros() ou millis() voce deve ter em mente que são uma variavel long que sempre sera positivo o resultado, ou seja, quando resetar o contador e você subtrair o valor do intervalo anterior o resultado sera gigantesco, basta voce fazer uma simples protecao antes do seu if:

 

voce verifica se millis()-delay_intervalo é maior que o intervalo+10 (coloquei 10 para ter uma margem de segurança e processar, mas no seu caso essa diferença passara de 1 milhao) se for maior, o delay_intervalo passara a ser = millis() entao você reseta ele, e após 2 segundos no seu caso o processamento ocorrerá normalmente!

 

sempre que trabalhar com contadores que resetam voce precisa disso, e outra coisa vamos aprofundar no assunto: vamos supor que voce precise de precisão extrema e a partir dos millis() você tenha que realizar uma matemática complexa. Quando o valor millis() for pequeno voce processa rápido, a medida que ele sobe as coisas complicam, imagina se ele nao estourasse, seu programa iria estourar o tamanho das variaveis tentando salvar digitos cada vez maiores e ficaria lerdo.

 

Nesse caso assim que millis atingisse um valor grande  para seu processamento e velocidade voce poderia resetar ele e usar a mesma logica acima que passei.

 

Caso tenha duvidas de uma olhada nisso: https://www.norwegiancreations.com/2018/10/arduino-tutorial-avoiding-the-overflow-issue-when-using-millis-and-micros/

 

@Isadora Ferraz analise zip kkkkkkkk eu dou risada de verdade lendo seus comentarios otimo senso de humor 

 

Obrigado, já me foi muito útil sua resposta.

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!