#include <Wire.h> // richiama la libreria Wire che riconosce la seriale I2C
#include <RTClib.h> // richiama la libreria dell'orologio RTC
#include <LiquidCrystal.h> // richiama la libreria del display lcd
//#define BACKLIGHT 30 // Pin per il controllo della retroilluminazione del display LCD
//#define CONTRAST 32 // Pin per il controllo del contrasto del display LCD
#define SET 8 // Pin per il pulsante "SET"
#define PIU 9 // Pin per il pulsante "PIU"
#define MENO 10 // Pin per il pulsante "MENO"
char buffer[10]; // Buffer per la formattazione delle stringhe
unsigned long time=0; // Variabile per memorizzare il tempo
unsigned long timeSet=0; // Variabile per memorizzare il tempo per l'impostazione
int setModeTime=2000; // tempo occorrente per entrare in modalità "Impostazione" prmendo "SET" e uscire dal menù impostazione
const int numReadings = 10; // variabile in cui è impostato il numero di letture (campioni) su cui fare la media delle temperature
float BETA = 3950; // Variabile utile a convertire il valore sei sensori
RTC_DS1307 RTC;
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // inizializzazione pin dedicati al display lcd
int stato = 0; // variabile il cui valore permette di commutare il relativo case , parte da 0.
unsigned long cambioCase = 3000; // variabile che stabilisce l'intevallo di tempo per ogni case
unsigned long tempoTrascorso; // variabile che calcola la differenza tempo
const int limiteMassimo = 3; // variabile che determina quanti case in sequenza deve cambiare
unsigned long ultimoTempo = 0; // Memorizza il tempo dell'ultimo incremento
void setup() {
Wire.begin(); // Inizializza la comunicazione I2C
RTC.begin(); // Inizializza il timer RTC
lcd.begin(16, 2); // INIZIALIZZO IL DISPLAY
Serial.begin(9600); // Inizializza la stampa su schermo a 9600 baud rate
if (!RTC.isrunning()) { // Se il RTC non sta funzionando o non è collegato,
Serial.println("RTC is NOT running!"); // scrive su stampa a schermo la scritta "RTC is NOT running!
RTC.adjust(DateTime(__DATE__, __TIME__)); //imposta la data/ora con quella dello sketch
}
}
void loop(){
unsigned long tempoAttuale = millis();
// Verificare se è trascorso l'intervallo di tempo
if (tempoAttuale - ultimoTempo >= cambioCase) {
// Se il pulsante SET è premuto, vai direttamente alla modalità di impostazione
if (digitalRead(SET) == HIGH) {stato = 4;}
// Incrementa la variabile e assicura che non superi il limite massimo 3
else {stato = (stato + 1) % (limiteMassimo + 1);}
// Stampare il valore attuale della variabile
Serial.print("stato:");
Serial.println(stato);
delay(300);
ultimoTempo = tempoAttuale; // Aggiornare l'ultimo tempo di incremento
}
switch(stato){
case 0:
tempPiano0();
// **************************^^***** temperatura interna Piano terra***********************************
break;
case 1:
tempPiano1();
// ************************************ temperatura Primo piano*************************************
break;
case 2:
tempEsterna();
// ************************************ Temperatura esterna *************************************
break;
case 3:
dataOra();
// ************************************ data e ora *********************************************
break;
case 4:
setDataora();
// ****************************** impostazione data e ora **************************************
break;
}
}
void tempPiano0(){
int analogValue1 = analogRead(A0); // variabile di acquisizione dell'ingresso analogico A0
// Variabile su cui viene calcolato il valore di lettura analogico A0 in gradi celsius
float celsius1 = 1/(log(1/(1023./analogValue1-1))/BETA+1.0/298.15)-273.15;
//lcd.clear(); // Pulisce il display LCD
lcd.setCursor(0,0); // Imposta il cursore all'inizio della prima riga
lcd.print("Temp.piano terra"); // Stampa su LCD la parola "temperatura"
lcd.setCursor(0,1); // Imposta il cursore all'inizio della seconda riga
lcd.print(celsius1); // Stampa su lCD la temperatura media
delay( 100 ); // tempo in cui resta visualizzata la temperatura
}
void tempPiano1(){
int analogValue2 = analogRead(A1); // variabile di acquisizione dell'ingresso analogico A1
// Variabile su cui viene calcolato il valore di lettura analogico A1 in gradi celsius
float celsius2 = 1 / (log(1 / (1023. / analogValue2 - 1)) / BETA + 1.0 / 298.15) - 273.15;
//lcd.clear(); // Pulisce il display LCD
lcd.setCursor(0,0); // Imposta il cursore all'inizio della prima riga
lcd.print("Temp.primo piano"); // Stampa su LCD la parola "temperatura"
lcd.setCursor(0,1); // Imposta il cursore all'inizio della seconda riga
lcd.print(celsius2); // Stampa su lCD la temperatura media
delay( 100 ); // tempo in cui resta visualizzata la temperatura
}
void tempEsterna(){
int analogValue3 = analogRead(A2); // variabile di acquisizione dell'ingresso analogico A2
// Variabile su cui viene calcolato il valore di lettura analogico A2 in gradi celsius
float celsius3 = 1 / (log(1 / (1023. / analogValue3 - 1)) / BETA + 1.0 / 298.15) - 273.15;
//lcd.clear(); // Pulisce il display LCD
lcd.setCursor(0,0); // Imposta il cursore all'inizio della prima riga
lcd.print("Temp.esterna "); // Stampa su LCD la parola "temperatura"
lcd.setCursor(0,1); // Imposta il cursore all'inizio della seconda riga
lcd.print(celsius3); // Stampa su lCD la temperatura media
delay( 100 ); // tempo in cui resta visualizzata la temperatura
}
//*************************** modalità visualizza Data/Ora e gestione pulsante SET **********************************
void dataOra(){
// Se il pulsante "SET" è premuto, memorizza il tempo
if (digitalRead( SET ) == LOW) { time = millis(); }
DateTime now = RTC.now(); // Variabile su cui viene copiata la data/ora attuale dall' RTC
//lcd.clear(); // Pulisce il display LCD
// Formatta la data nel formato "Giorno/Mese/Anno"
sprintf(buffer, "%02d/%02d/%d", now.day(), now.month(), now.year());
lcd.setCursor(0,0); // Imposta il cursore all'inizio della prima riga
lcd.print( buffer ); // Stampa la data
//char buffer[10] = ""; // Buffer temporaneo per la formattazione dell'ora
// Formatta l'ora nel formato "Ore: Minuti: Secondi"
sprintf(buffer, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
lcd.setCursor(0,1); // Imposta il cursore all'inizio della seconda rig
lcd.print( buffer ); // Stampa l'ora'
// Se è trascorso un certo periodo di tempo e il tempo di attivazione della modalità
// "Impostazione" è stato superato, attiva la modalità "Impostazione"
if (time > 0 && setModeTime < (millis()-time)){setDataora();}
delay(200);
lcd.clear(); // Pulisce il display LCD alla fine
}
//***************************^^^^***** modalità impostazione Data/Ora *********************************************
void setDataora() {
DateTime now = RTC.now();
boolean setMode = true; // Variabile booleana per indicare se la modalità "Impostazione" è attiva
int setModeLevel = 0; // Variabile per indicare il livello di impostazione
int _day = now.day(); // Ottiene il giorno attuale
int _month = now.month(); // Ottiene il mese attuale
int _year = now.year(); // Ottiene l'anno attuale
int _hour = now.hour(); // Ottiene l'ora attuale
int _min = now.minute(); // Ottiene il minuto attuale
int _sec = now.second(); // Ottiene il secondo attuale
lcd.clear(); // Pulisce il display LCD
lcd.setCursor(0,0); // Imposta il cursore all'inizio della prima riga
sprintf(buffer, "%s: %02d", "Giorno", _day); // Formatta il messaggio con il giorno
delay( 1000 ); // Delay per una breve pausa
timeSet = millis(); // Memorizza il tempo corrente
while ( setMode ) { // Finche si è in modalità "impostazione data/ora"
if (digitalRead(SET) == HIGH || digitalRead(PIU) == HIGH || digitalRead(MENO) == HIGH ) { timeSet = millis(); }
lcd.setCursor(0,0); // Imposta il cursore all'inizio della prima riga
// Imposta il giorno
if ( setModeLevel == 0 ) {
if (digitalRead(PIU) == HIGH && _day < 31) { _day++; } // premendo "PIU" il giornoaumenta fino a 31
if (digitalRead(MENO) == HIGH && _day > 1) { _day--; } // premendo "MENO" il giorno diminuisce fino a 1
sprintf(buffer, "%s: %02d", "Giorno", _day); // Formatta il messaggio con il giorno e la scritta "Giorno"
}
// Imposta il mese
if ( setModeLevel == 1 ) {
if (digitalRead(PIU) == HIGH && _month < 12) { _month++; } // premendo "PIU" il mese aumenta fino a 12
if (digitalRead(MENO) == HIGH && _month > 1) { _month--; } // premendo "MENO" il mese diminuisce fino a 1
sprintf(buffer, "%s: %02d", "Mese", _month); // Formatta il messaggio con il mese e la scritta "Mese"
}
// Imposta l'anno
if ( setModeLevel == 2 ) {
if (digitalRead(PIU) == HIGH && _year < 9999) { _year++; } // premendo "PIU" l'anno aumenta fino a 9999
if (digitalRead(MENO) == HIGH && _year > 1900) { _year--; }// premendo "MENO" l'anno diminuisce fino 1900
sprintf(buffer, "%s: %02d", "Anno", _year); // Formatta il messaggio con l'anno e la scritta "Anno"
}
// Imposta l'ora
if ( setModeLevel == 3 ) {
if (digitalRead(PIU) == HIGH && _hour < 24) { _hour++; } // premendo "PIU" l'ora aumenta fino a 24
if (digitalRead(MENO) == HIGH && _hour > 1) { _hour--; } // premendo "MENO" l'ora diminuisce fino 1
sprintf(buffer, "%s: %02d", "Ora", _hour); // Formatta il messaggio con l'ora e la scritta "ora"
}
// Imposta i minuti
if ( setModeLevel == 4 ) {
if (digitalRead(PIU) == HIGH && _min < 60) { _min++; } // premendo "PIU" i minuti aumentano fino a 60
if (digitalRead(MENO) == HIGH && _min > 1) { _min--; } // premendo "MENO" i minuti diminuisce fino 1
sprintf(buffer, "%s: %02d", "Minuti", _min); // Formatta il messaggio con i minuti e la scritta "Minuti"
}
// Imposta i secondi
if ( setModeLevel == 5 ) {
if (digitalRead(PIU) == HIGH && _sec < 60) { _sec++; } // premendo "PIU" i secondi aumentano fino a 60
if (digitalRead(MENO) == HIGH && _sec > 0) { _sec--; } // premendo "MENO" i secondi diminuisce fino 1
sprintf(buffer, "%s: %02d", "Secondi", _sec); // Formatta il messaggio con i secondi e la scritta "<secondi"
}
lcd.print( buffer ); // Stampa il messaggio
if (digitalRead(SET) == HIGH) { lcd.clear(); setModeLevel++; }// Se il pulsante "SET" è premuto, passa al livello successivo
if (setModeLevel > 5 ) { setModeLevel=0; } // Se il livello è maggiore di 5, reimposta a 0
// Se è trascorso un certo periodo di tempo, imposta la data/ora e esci dalla modalità "Impostazione"
if (timeSet > 0 && (setModeTime*2) < (millis() - timeSet)) {
RTC.adjust(DateTime(_year, _month, _day, _hour, _min, _sec));
setMode = false;
}
delay(200);
stato = 0; // Delay per evitare letture troppo rapide dai pulsanti
}
}