#include <Arduino.h>
#include <LiquidCrystal_I2C.h> // Per il Display LCD
#include <Wire.h> // Gestione I2C
#include <RTClib.h> // Per mantenere l'orologio
#include <EEPROM.h> // Per mantenere i dati anche dopo lo spegnimento
#include <Bounce2.h> // gestione tasti
#include <TimeLib.h>
//#include <Time.h>
// Definizione variabili GLOBALI
#define temp_mandata_su A0 // Sonda di temperatura acqua Riscaldamento mandata piano terra;
#define temp_mandata_giu A1 // Sonda di temperatura acqua Riscaldamento mandata piano primo;
#define temp_mandata_caldaia A2 // Sonda di temperatura acqua Caldaia per riscaldamento;
#define temp_mandata_sanitari A3 // Sonda di temperatura acqua Caldaia per uso sanitario;
#define temp_ambiente_su A4 // Attualmente non installata;
#define temp_ambiente_giu A5 // Attualmente non installata;
#define temp_esterna A6 // Attualmente non installata;
#define puls_su 40 // Pulsante di selezione;
#define puls_giu 42 // Pulsante di selezione;
#define puls_dx 44 // Pulsante di selezione;
#define puls_sx 46 // Pulsante di selezione;
#define puls_ok 48 // Pulsante di selezione;
#define r_caldaia_on 22 // Assegnazione pin per Relè e Spie - Rele low = chiuso - hight = aperto
#define r_pompasu 24 // Relè accensione pompa
#define r_pompagiu 26 // Relè accensione pompa
#define r_pompacaldaia 25 // Relè pompa interna - non in uso da verificare
#define r_pompapuffer 27 // Relè pompa interna - non in uso da verificare
#define r_valvolasu_on 28 // controllo valvola motorizzata in apertura
#define r_valvolasu_off 30 // controllo valvola motorizzata in chiusura
#define r_valvolagiu_on 32 // controllo valvola motorizzata in apertura
#define r_valvolagiu_off 34 // controllo valvola motorizzata in chiusura
#define sw_on_su 27 // switch fine corsa apertura valvola su
#define sw_off_su 29 // switch fine corsa chiusura valvola su
#define sw_on_giu 31 // switch fine corsa apertura valvola giu
#define sw_off_giu 33 // switch fine corsa chiusura valvola giu
//Millisecondi per il debounce dei pulsanti
const int debounce_ms = 5;
Bounce tasto_su = Bounce();
Bounce tasto_giu = Bounce();
Bounce tasto_dx = Bounce();
Bounce tasto_sx = Bounce();
Bounce tasto_ok = Bounce();
int pulsanteStato = LOW;
int attesaDebounce = 50;
byte tasto_premuto;
byte tasto_scelta;
// Si "Istanzia" il componente RealTimeClock
RTC_DS1307 rtc;
const uint8_t buttonPins[] = {40, 42, 44, 46, 48};
String giorni[7] = {"Dom","Lun","Mar","Mer","Gio","Ven","Sab"};
// Si "Istanzia" il componente Cristalli_Liquidi
LiquidCrystal_I2C lcd(0x27,20,4); // Imposta LCD indirizzo 0x27 per 20 caratteri su 4 linee
static unsigned long tempoApertura = 0; // Variabile globale
static unsigned long tempoChiusura = 0; // Variabile globale
// Definizione routin di programmazione
void read_display_temperatura();
void lettura_applicazione_impostazioni();
void regolo_mandata_su();
void stabilizzo_mandata_su();
void regolo_mandata_giu();
void stabilizzo_mandata_giu();
void cambiaMenu();
void imposta_funzioni_manuali();
void TestRele();
void TestRele_1();
void scelta_menu();
float leggo_sensore(int sensore);
byte get_input();
int impostazioni_menu();
int t_max_caldaia = 80; // Definizione tempratura massima Caldaia
int t_min_caldaia = 60; // Definizione tempratura minima Caldaia
int t_max_puffer = 75; // Definizione tempratura massima Acqua Sanitaria
int t_min_puffer = 65; // Definizione tempratura minima Acqua Sanitaria
int T_max_riscaldamento_giu = 39; // Definizione temparatura massima di mandata impianto primo terra
int T_min_riscaldamento_giu = 25; // Definizione temparatura minima di mandata impianto primo terra
int T_max_riscaldamento_su = 39; // Definizione temparatura massima di mandata impianto primo piano
int T_min_riscaldamento_su = 25; // Definizione temparatura minima di mandata impianto primo primo
int T_ambiente_giu = 20; // Definizione temperatura ambiente piano Terra
int T_ambiente_su = 19; // Definizione Temperatura ambiente piano primo
int T_esterna = 10; // Definizione temperatura esterna media stagionale per autunno
int T_mantenimento = 25; // Definizione della temperatura di mantenimento per una T ambiente di 18°
int t_caldaia; // definizione variabili di uso globale
int mandata_su;
int mandata_giu;
int mandata_caldaia;
int mandata_sanitari;
int ambiente_su;
int ambiente_giu;
int esterna;
int counter_rele = 1; // per il test rele
bool ultimo_tasto = false;
bool selezione = false;
bool selezione_1 = false;
int tempo_attesa = 1000;
uint64_t tempo;
void setup() {
Serial.begin(9600);
rtc.begin();
DateTime now = rtc.now();
lcd.init(); // initialize the lcd;
lcd.backlight(); // open the backlight;
lcd.begin(20,4); // Definizione tipo LCD;
lcd.clear(); // cancella LCD;
lcd.setCursor(0, 0);
lcd.print("Gestione");
lcd.setCursor(0, 1);
lcd.print("Riscaldamento");
lcd.setCursor(0, 2);
lcd.print("Ver. 1.0 01/02/2023");
lcd.setCursor(0, 3);
lcd.print("Inizializzazione....");
delay(3000);
setTime(10,31,30,05,02,2023);
pinMode(temp_mandata_su, INPUT); // Associazione pin - Sensori di temperatura LM 35
pinMode(temp_mandata_giu, INPUT);
pinMode(temp_mandata_caldaia, INPUT);
pinMode(temp_mandata_sanitari,INPUT);
pinMode(temp_ambiente_su, INPUT);
pinMode(temp_ambiente_giu, INPUT);
pinMode(temp_esterna,INPUT);
tasto_su.attach( puls_su, INPUT );
tasto_su.interval(debounce_ms);
tasto_giu.attach( puls_giu, INPUT );
tasto_giu.interval(debounce_ms);
tasto_dx.attach( puls_dx, INPUT );
tasto_dx.interval(debounce_ms);
tasto_sx.attach( puls_sx, INPUT );
tasto_sx.interval(debounce_ms);
tasto_ok.attach( puls_ok, INPUT );
tasto_ok.interval(debounce_ms);
/* pinMode(puls_su, INPUT ); // Associazione pin - Tasti di selezione
pinMode(puls_giu, INPUT );
pinMode(puls_dx, INPUT );
pinMode(puls_sx, INPUT );
pinMode(puls_ok, INPUT ); */
pinMode(r_caldaia_on, OUTPUT); // Associazione pin - Rele di attuazione apparati
pinMode(r_pompacaldaia, OUTPUT);
pinMode(r_pompapuffer, OUTPUT);
pinMode(r_pompasu, OUTPUT);
pinMode(r_pompagiu, OUTPUT);
pinMode(r_valvolasu_on, OUTPUT);
pinMode(r_valvolasu_off, OUTPUT);
pinMode(r_valvolagiu_on, OUTPUT);
pinMode(r_valvolagiu_off,OUTPUT);
digitalWrite (r_caldaia_on, HIGH); // Impostazione a off di tutte le uscite relè
digitalWrite (r_pompacaldaia, HIGH);
digitalWrite (r_pompapuffer, HIGH);
digitalWrite (r_pompasu, HIGH);
digitalWrite (r_pompagiu, HIGH);
digitalWrite (r_valvolasu_on, HIGH);
digitalWrite (r_valvolasu_off,HIGH);
digitalWrite (r_valvolagiu_on,HIGH);
digitalWrite (r_valvolagiu_off,HIGH);
lcd.setCursor(0, 3);
lcd.print("Imposto valori base.");
delay(1000);
}
void loop() {
byte scelta_si = 0;
byte scelta_no = 0;
byte scelta_ok = 0;
lcd.clear();
// digitalClockDisplay();
// read_display_temperatura();
// lettura_applicazione_impostazioni();
Serial.print("Inizio attesa = ");
Serial.println(selezione);
tasto_sx.update();
tasto_dx.update();
tasto_su.update();
tasto_giu.update();
tasto_ok.update();
tempo = millis();
while (selezione == true ) {
Serial.print("Isono nel ciclo while");
if (tasto_sx.read() == LOW || tasto_dx.read() == LOW || tasto_su.read() == LOW || tasto_giu.read() == LOW || tasto_ok.read() == LOW) {
Serial.print("Tasto Premuto = xxxxxx");
Serial.println(tasto_premuto);
lcd.clear(); // Se premo un tasto entro nei menu test o configurazione
lcd.setCursor(0, 0);
lcd.print("Tasto su - TEST Menu");
lcd.setCursor(0, 3);
lcd.print("Tasto giu - Menu SET");
if (millis() <= tempo + tempo_attesa){
selezione == true;
}
tasto_sx.update();
tasto_dx.update();
tasto_su.update();
tasto_giu.update();
tasto_ok.update();
if (tasto_su.read() == LOW){
lcd.clear(); // Se premo un tasto entro nei menu test o configurazione
lcd.setCursor(0, 0);
lcd.print("Menu TEST - ");
}
else
if (tasto_giu.read() ){
lcd.clear(); // Se premo un tasto entro nei menu test o configurazione
lcd.setCursor(0, 0);
lcd.print("Menu SET - ");
}
tempo = tempo - 1000; // decremento il contatore
selezione = get_input();
if (selezione == 1) {
lcd.setCursor(13, 0);
lcd.print("SI");
scelta_si = 1;
}
if (selezione == 0) {
lcd.setCursor(13, 0);
lcd.print("No");
scelta_no = 1;
}
tempo = tempo - 1000; // decremento il contatore
if (tasto_su.read() == LOW || tasto_giu.read() == LOW || tasto_ok.read() == LOW) {
lcd.setCursor(13, 0);
lcd.print("exit");
scelta_no = 0;
scelta_no = 0;
}
} // fine ciclo while
}
}
void read_display_temperatura(){
mandata_su = analogRead(temp_mandata_su);
mandata_giu = analogRead(temp_mandata_giu);
mandata_caldaia = analogRead(temp_mandata_caldaia);
mandata_sanitari = analogRead(temp_mandata_sanitari);
ambiente_su = analogRead(temp_ambiente_su);
ambiente_giu = analogRead(temp_ambiente_giu);
esterna = analogRead(temp_esterna);
int celsius1 = mandata_su/2;
int celsius2 = mandata_giu/2;
int celsius3 = mandata_caldaia/2;
int celsius4 = mandata_sanitari/2;
int celsius5 = ambiente_su/2;
int celsius6 = ambiente_giu/2;
int celsius7 = esterna/2;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Caldaia=");
lcd.print(celsius1, DEC);
lcd.print((char)223);
lcd.setCursor(11, 0);
lcd.print("Sanit=");
lcd.print(celsius2, DEC);
lcd.print((char)223);
lcd.setCursor(0, 1);
lcd.print("Risc-PT=");
lcd.print(celsius3, DEC);
lcd.print((char)223);
lcd.setCursor(11, 1);
lcd.print("Amb-PT=");
lcd.print(celsius4, DEC);
lcd.print((char)223);
lcd.setCursor(0, 2);
lcd.print("Risc-P1=");
lcd.print(celsius5, DEC);
lcd.print((char)223);
lcd.setCursor(11, 2 );
lcd.print("Amb-P1=");
lcd.print(celsius6, DEC);
lcd.print((char)223);
lcd.setCursor(0, 3);
lcd.print("Ext=");
lcd.print(celsius7, DEC);
lcd.print((char)223);
delay(500);
lcd.setCursor(0, 3);
lcd.print(hour(), DEC);
lcd.print(" ");
lcd.print(minute(), DEC);
lcd.print(" ");
lcd.print(second(), DEC);
lcd.print(" ");
lcd.print(day(), DEC);
lcd.print(" ");
lcd.print(month(), DEC);
lcd.print(" ");
lcd.print(year(), DEC);
delay(500);
}
void lettura_applicazione_impostazioni()
{
if (t_caldaia < t_max_caldaia)
{
digitalWrite (r_caldaia_on,LOW); // Se temperatuta sotto soglia MAX accendo Caldaia
}
else
{
digitalWrite (r_caldaia_on, HIGH); // Se temperatuta sopra soglia Max Spengo la Caldaia
}
if (t_caldaia < t_min_caldaia) // Se temperatuta sotto soglia minima Spengo tutte le pompe
{
digitalWrite(r_pompacaldaia, HIGH);
digitalWrite(r_pompapuffer, HIGH);
digitalWrite(r_pompasu, HIGH);
digitalWrite(r_pompagiu, HIGH);
}
if (t_caldaia > t_min_caldaia) // Se temperatuta OK verifico richiesta calore dai piani
{
if (ambiente_su < T_ambiente_su) { // se la temperatura ambiente è inferore al SET std di 18°
regolo_mandata_su(); } // richiamo la routin di regolazione per riscaldare
else {
stabilizzo_mandata_su(); } // altrimenti attivo la routin di - mantenimento Circolazione acqua a 18°
if (ambiente_giu < T_ambiente_giu) { // se la temperatura ambiente è inferore al SET std di 18°
regolo_mandata_giu(); } // richiamo la routin di regolazione per riscaldare
else {
stabilizzo_mandata_giu(); } // altrimenti attivo la routin di - mantenimento Circolazione acqua a 18°
}
}
byte get_input()
{
// Creo un loop per assegnare un valore da 1 a 5 alla variabile premuto che contiene il numero
// del tasto premuto SX=1, DX=2, SU=3, GIU=4, OK=5
// SX=0, DX=1, SU=2, GIU=3, OK=4
Serial.println("Inizio routin get_input");
tasto_sx.update();
tasto_dx.update();
tasto_su.update();
tasto_giu.update();
tasto_ok.update();
Serial.println("routin get_input");
byte i;
byte scelta;
bool selezione = false;
while (selezione == false) {
for ( i = 0; i < 5; i++) {
byte buttonPin = buttonPins[i];
if (digitalRead(buttonPin) == LOW) {
selezione = true;
Serial.println(i);
scelta = i;
Serial.println(scelta);
}
}
}
Serial.println("Fine routin get_input");
Serial.print("Pulsante Premuto = ");
Serial.println(i);
return (scelta);
}
void scelta_menu()
{
byte scelta_si = 0;
byte scelta_no = 0;
tasto_premuto = get_input();
switch (tasto_premuto) {
case 2: // Premuto tasto SU - entro nel menu TEST
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Menu TEST - ");
ultimo_tasto = true;
while ( ultimo_tasto == true){
Serial.println("Passo di qua ---");
tasto_scelta = get_input();
Serial.println("Passo di qua --1");
Serial.println(tasto_scelta);
ultimo_tasto = false;
}
if (tasto_scelta == 1) {
Serial.println("sono nell'IF");
lcd.setCursor(13, 0);
lcd.print("SI");
scelta_si = 1;
}
if ((tasto_scelta) == 0) {
lcd.setCursor(13, 0);
lcd.print("NO");
scelta_no = 1;
}
ultimo_tasto = true;
while ( ultimo_tasto == true){
tasto_scelta = get_input();
ultimo_tasto = false;
}
if (tasto_scelta == 4 && scelta_si == 1) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Test rele in corso..");
// TestRele();
delay(700);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Test rele terminato");
lcd.print("premi un tasto fine");
ultimo_tasto = true;
while ( ultimo_tasto == true){
tasto_scelta = get_input();
ultimo_tasto = false;
}
}
if (tasto_scelta == 4 && scelta_no == 1){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Test rele annullato..");
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Test rele terminato");
lcd.print("premi un tasto fine");
while ( ultimo_tasto == true){
tasto_scelta = get_input();
ultimo_tasto = false;
}
}
if (tasto_scelta != 4) {
break;
}
return;
ultimo_tasto = false;
break;
case 3: // Premuto tasto GIU
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Menu SET - ");
lcd.setCursor(1, 0);
lcd.print("Stato attuale - ");
break;
default: // nel caso siano premuti altri tasti esce dal switch case
break;
}
}
void TestRele(){
lcd.setCursor(0,0);
lcd.print("Accendo i RELE: ");
lcd.setCursor(0,1);
}