RTC e funzioni legate all'ora

Salve a tutti, sto realizzando una serra che fa funzionare luce, riscaldamento e irrigazione a tempi prestabiliti.
Ora sto utilizzando la libreria RTClib di ladyada è mi chiedevo, richiamo le funzioni nel modo corretto?
faccio bene a leggere l'ora utilizzando l'IF ? questo è il codice:

if(now.hour()==9) innaffia();

inoltre quando richiamo la funzione innaffia() ho un delay di 10 s in cui il display rimane in "freeze" e non viene aggiornato, come bypasso questo problema? questo il codice:

if(now.hour()==9) innaffia();
void innaffia(){
  digitalWrite(pompa,HIGH);
  delay(10000);
  digitalWrite(pompa,LOW);
  }

Infine posto tutto lo sketch e allego uno schema

/* Serra Riscaldata 
By Simone
http://myweb96.altervista.org
Iniziato il /02/2014
Date and time functions using a DS1307 RTC connected via I2C and Wire lib
*/
 
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
RTC_DS1307 RTC;
#define cavo 13          //assegna il pin 13 al cavo riscaldante
#define ventola 12      //assegna il pin 12 alla ventola
#define lampada 11      //assegna il pin 11 alla lampada
#define pompa 10        //assegna il pin 10 alla pompa irrigazione
#define button1 9
#define button2 8
int sens1 = A0;       //assegna il pin A0 al primo sensore di temperatura
int stato1;
int stato2;
int tempset=20;
float temp1;
void setup () {
    Serial.begin(57600);
    Wire.begin();
    RTC.begin();
    lcd.begin(16, 2); 
    lcd.clear();
     //RTC.adjust(DateTime(__DATE__, __TIME__));
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
   pinMode(cavo,OUTPUT);
  pinMode(ventola,OUTPUT);
  pinMode(lampada,OUTPUT);
  pinMode(pompa,OUTPUT);
  pinMode(button1,INPUT);
  pinMode(button2,INPUT);
 
}

float temperature(byte _pin) {
  float T = (analogRead(_pin) * 5.0) / 1024.0;
  T *= 100;
  return T;
}
  
void innaffia(){
  digitalWrite(pompa,HIGH);
  delay(10000);
  digitalWrite(pompa,LOW);
  
}
void loop () {
    DateTime now = RTC.now();
 
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    lcd.setCursor(0,0);
    lcd.print(now.day(),DEC);
    lcd.print('/');
    lcd.print(now.month(), DEC);
    lcd.print('/');
    lcd.print(now.year(), DEC);
    lcd.print(' ');
    lcd.setCursor(0,1);
    lcd.print(now.hour(),DEC);
    lcd.print(':');
    lcd.print(now.minute(), DEC);
    lcd.print(':');
    lcd.print(now.second(), DEC);
    lcd.print(' ');
    
    stato1= digitalRead(button1);
    stato2= digitalRead(button2);
    if (stato1==1) tempset++;
    if (stato2==1) tempset--;    
    
    temp1 = temperature(sens1);
    lcd.print("T=");
    lcd.print(temp1);
    delay(200);
    if (temp1<tempset) digitalWrite(cavo,HIGH);             //termostato
    else digitalWrite(cavo,LOW);
   
    if (now.hour()>=8 && now.hour()<=20)  digitalWrite(lampada,HIGH);    //illuminazione on
    else digitalWrite(lampada,LOW);                 //illuminazione off
           
    if(now.hour()==9) innaffia();
    if(now.hour()==16) innaffia();
        
    delay(1000);
}

EDIT: modificato primo codice.

schema.fzz (24.5 KB)

Serra_sketch_con_controllo_temp.ino (2.77 KB)

simo96:
faccio bene a leggere l'ora utilizzando l'IF ? questo è il codice:

if (temp1<tempset) digitalWrite(cavo,HIGH);             //  termostato

else digitalWrite(cavo,LOW);                            // temp impostata

Qui veramente confronti 2 temperature, non 2 orari.

inoltre quando richiamo la funzione innaffia() ho un delay di 10 s in cui il display rimane in "freeze" e non viene aggiornato, come bypasso questo problema? questo il codice:

if(now.hour()==9) innaffia();

void innaffia(){
  digitalWrite(pompa,HIGH);
  delay(10000);
  digitalWrite(pompa,LOW);
  }

E' normale visto che delay non permette di eseguire nessun altro compito.
Devi usare millis in un ciclo all'interno del quale, mentre passa il tempo prestabilito, fare altre cose tra cui gestire il refresh dello schermo. Qui alcune dritte su come farlo, da un mio articoletto.

simo96:
faccio bene a leggere l'ora utilizzando l'IF ? questo è il codice:

if(now.hour()==9) innaffia();

Ecco il codice che dicevo

No, perché in questo caso daresti l'impulso per accendere la pompa per 1 ora intera.
Il controllo lo devi fare sulle ore, i minuti ed i secondi.

SE (ore == 9 AND minuti == 0 AND secondi == 0) ALLORA ....

Ricordati però che in questo caso l'impulso lo daresti per tutto il tempo in cui secondi è pari a 0, quindi devi anche usare una variabile di stato per vedere se hai dato già l'impulso.

Quindi, in pseudocodice:

stato = 0
...
CICLO
se orario è giusto
  stato è 0?
  sì: attiva pompa + metti stato ad 1
  no: ho già fatto, salto
fine se

OK, ho capito.
Un'ultima cosa, tengo questo tipo di richiamo:

if(now.hour()==9)

o devo dichiarare delle variabili e usare questo tipo di richiamo??

ore == 9 AND minuti == 0 AND secondi == 0

Inoltre alla fine devo riportare lo stato a 0 vero? altrimenti funzionerebbe solo la prima volta?

  1. ore == 9 era per abbreviare :wink:
    Non sei costretto ad assegnare a delle variabili il valore delle funzioni temporali, fai il confronto direttamente con le funzioni stesse.

  2. ovviamente sì, quando andrai a spengere la pompa, farai l'inverso: controlli se l'orario è quello di stop, poi controlli se la pompa è già spenta (hai "stato" che te lo dice), e la spengi solo se stato=1, ossia se la pompa è accesa.

Ecco il codice modificato ed ultimato. Può andare o c'è qualche errore?

/* Serra Riscaldata 
By Simone
http://myweb96.altervista.org
Iniziato il /02/2014
Date and time functions using a DS1307 RTC connected via I2C and Wire lib
*/
 
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
RTC_DS1307 RTC;
#define cavo 13          //assegna il pin 13 al cavo riscaldante
#define ventola 12      //assegna il pin 12 alla ventola
#define lampada 11      //assegna il pin 11 alla lampada
#define pompa 10        //assegna il pin 10 alla pompa irrigazione
#define button1 9
#define button2 8
int sens1 = A0;       //assegna il pin A0 al primo sensore di temperatura
int stato1;
int stato2;
int tempset=25;
float temp1;
void setup () {
    Serial.begin(57600);
    Wire.begin();
    RTC.begin();
    lcd.begin(16, 2); 
    lcd.clear();
     //RTC.adjust(DateTime(__DATE__, __TIME__));
  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
   pinMode(cavo,OUTPUT);
  pinMode(ventola,OUTPUT);
  pinMode(lampada,OUTPUT);
  pinMode(pompa,OUTPUT);
  pinMode(button1,INPUT);
  pinMode(button2,INPUT);
 
}

float temperature(byte _pin) {
  float T = (analogRead(_pin) * 5.0) / 1024.0;
  T *= 100;
  return T;
}
void startinnaffia(){
  digitalWrite(pompa,HIGH);
}
void stopinnaffia(){
  digitalWrite(pompa,LOW);
}
  
void loop () {
    DateTime now = RTC.now();
 
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    lcd.setCursor(0,0);
    lcd.print(now.day(),DEC);
    lcd.print('/');
    lcd.print(now.month(), DEC);
    lcd.print('/');
    lcd.print(now.year(), DEC);
    lcd.print(' ');
    lcd.setCursor(0,1);
    lcd.print(now.hour(),DEC);
    lcd.print(':');
    lcd.print(now.minute(), DEC);
    lcd.print(':');
    lcd.print(now.second(), DEC);
    lcd.print(' ');
    
    stato1= digitalRead(button1);
    stato2= digitalRead(button2);
    if (stato1==0) tempset++;
    if (stato2==0) tempset--;    
    if(now.hour()==8 && now.minute()==0 && now.second()==0)   tempset=25;
    if(now.hour()==20 && now.minute()==30 && now.second()==0) tempset=20;
    
    temp1 = temperature(sens1);
    lcd.setCursor(9,1);
    lcd.print("T=");
    lcd.print(temp1);
    delay(200);
    if (temp1<tempset) digitalWrite(cavo,HIGH);             //  termostato
    else digitalWrite(cavo,LOW);      // temp impostata
    lcd.setCursor(10,0);
    lcd.print("Ts=");
    lcd.print(tempset);
   Serial.println(temp1);
   Serial.println(tempset);
   
    if (now.hour()>=8 && now.hour()<=20)  digitalWrite(lampada,HIGH);    //illuminazione on
    else digitalWrite(lampada,LOW);                 //illuminazione off
           
    if(now.hour()==9 && now.minute()==0 && now.second()==0) startinnaffia();
    if(now.hour()==9 && now.minute()==5 && now.second()==0) stopinnaffia();
    if(now.hour()==16 && now.minute()==0 && now.second()==0) startinnaffia();
    if(now.hour()==16 && now.minute()==5 && now.second()==0) stopinnaffia();
        
    delay(1000);
}