#include <RTClib.h>
#include <Wire.h>
#include <DHT.h>
#include <LiquidCrystal_I2C.h>
RTC_DS1307 rtc;
DHT dht(5, DHT22);
LiquidCrystal_I2C lcd(0x27, 20, 4);
float lettura = 0, gradiC = 0;
long trTemp = 0, trOra = 0, trDisp = 0;
int opz = -1, inc_opz = 0, incH = 0, mod_incH = 0, flagH = 0, flagT = 0, t_vecchia = 0, stato = 0, timer = 0;
//boolean vett[24] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //Spento configurazione cavalieri
//boolean vett[24] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; //Acceso configurazione cavalieri
boolean vett[24] = { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0}; //Default configurazione cavalieri
//Orario Programmaz."00-01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20-21-22-23" Default configurazione cavalieri
char daysOfTheWeek[7][12] = {"Domenica", "Lunedi", "Martedi", "Mercoledi", "Giovedi", "Venerdi", "Sabato"};
int t_luce = 60; // tempo luminosità
int soglia = 23; //soglia di temperatura predefinita
//definizione caratteri personalizzati
byte spento[8] =
{
B00000,
B00000,
B00000,
B00000,
B11011,
B11011,
B11011,
B11011,
};
byte on_pari[8] =
{
B11000,
B11000,
B11000,
B11000,
B11011,
B00011,
B00011,
B00011,
};
byte on_dispari[8] =
{
B00011,
B00011,
B00011,
B00011,
B11011,
B11000,
B11000,
B11000,
};
byte on_due[8] =
{
B11011,
B11011,
B11011,
B11011,
B11011,
};
byte segna_pari[8] =
{
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B11000,
B11000,
};
byte segna_dispari[8] =
{
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00011,
B11111,
};
void setup()
{
Serial.begin(9600);
dht.begin(); //
rtc.begin();
Wire.begin();
lcd.clear();
lcd.begin(20, 4);
lcd.setCursor(2, 1);
lcd.print("CRONOTERMOSTATO");
lcd.setCursor(5, 2);
lcd.print("by Gio@on");
lcd.backlight();
lcd.createChar(0, spento);
lcd.createChar(1, on_pari);
lcd.createChar(2, on_dispari);
lcd.createChar(3, on_due);
lcd.createChar(4, segna_pari);
lcd.createChar(5, segna_dispari);
delay(2000);
lcd.clear();
scansione();
lcd.setCursor(13, 2);
temperatura();
pinMode(2, INPUT); //menu
pinMode(3, INPUT); //+
pinMode(4, INPUT); //-
pinMode(7, OUTPUT); //RELE
digitalWrite(7, LOW);
pinMode(A0, INPUT);
}
void loop() {
//casi pressione menu
if (digitalRead(2))
{
opz = inc_opz % 3;
Serial.println(opz);
switch (opz)
{
case -1:
lcd.backlight();
break;
case 0:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Imp. orari");
lcd.backlight();
scansione();
break;
case 1:
flagH = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Imp. temperatura");
lcd.setCursor(0, 1);
lcd.print("soglia? ");
//temperatura();
lcd.setCursor(9, 1);
lcd.print(soglia);
lcd.backlight();
break;
case 2:
lcd.clear();
lcd.backlight();
flagH = 0;
timer = 0;
break;
}
delay(500);
inc_opz++;
timer = 0;
}
if ((opz == 2) || (opz == -1)) //siamo fuori dal menu in visualizzazione normale
{
scansione();
DateTime now = rtc.now();
lcd.setCursor(0, 0);
lcd.print(daysOfTheWeek[now.dayOfTheWeek()]);
lcd.setCursor(9, 0);
lcd.print("-");
lcd.print(now.day(),DEC);
lcd.print("/");
lcd.print(now.month(),DEC);
lcd.print("/");
lcd.print(now.year(),DEC);
lcd.setCursor(0, 2);
//sistemiamo ora
if (millis() - trOra > 1000)
{
DateTime now = rtc.now();
char ora[10];
sprintf(ora, "%2d:%02d" , now.hour(), now.minute());
lcd.setCursor(0, 1);
lcd.print("Ora ");
lcd.print(ora);
trOra = millis();
}
//risparmio energetico spegne la retroilluminazione del display
if (millis() - trDisp > 1000)
{
timer++;
trDisp = millis();
}
if (timer >= t_luce)
{
lcd.noBacklight();
inc_opz = -1;
}
//sistemiamo temperatura
if (millis() - trTemp > 500) // aggiorna ogni x000 la temperatura
{
lcd.setCursor(13, 2);
temperatura();
}
switch (stato)
{
case 0: //se è spenta
if (gradiC < soglia && vett[now.hour()]) //se sono sotto soglia && in orario la accendo
{
lcd.setCursor(11, 1);
lcd.print("Termo ON ");
digitalWrite(7, HIGH);
lcd.backlight();
stato = 1;
//soglia = soglia + 2;
//soglia = soglia;
}
else //altrimenti la tengo spenta
{
lcd.setCursor(11, 1);
lcd.print("Termo OFF");
digitalWrite(7, LOW);
stato = 0;
}
break;
case 1: // se è accesa
if (gradiC > soglia || vett[now.hour()] == 0) //se sono oltre soglia oppure fuori orario la spengo
{
lcd.setCursor(11, 1);
lcd.print("Termo OFF");
digitalWrite(7, LOW);
stato = 0;
//soglia = soglia - 2;
//soglia = soglia;
}
break;
}
if (stato == 0)
{
lcd.setCursor(11, 1);
lcd.print("Termo OFF");
digitalWrite(7, LOW);
}
else
{
lcd.setCursor(11, 1);
lcd.print("Termo ON ");
digitalWrite(7, HIGH);
}
}
if (digitalRead(3) && opz == 1) //decrementa temperatura alla pressione del tasto -
{
soglia--;
lcd.setCursor(9, 1);
lcd.print(soglia);
delay(200);
if (gradiC < soglia) stato = 0;
if (gradiC > soglia) stato = 1;
}
if (digitalRead(4) && opz == 1) //aumenta temperatura alla pressione del tasto +
{
soglia++;
lcd.setCursor(9, 1);
lcd.print(soglia);
delay(200);
if (gradiC < soglia) stato = 0;
if (gradiC > soglia) stato = 1;
}
if (digitalRead(3) && opz == 0) //scorre cavalieri
{ flagH = 1;
mod_incH = incH % 24;
lcd.clear();
lcd.print("Imp. orari");
scansione();
lcd.backlight();
if (incH % 2 == 0)
{
lcd.setCursor(mod_incH / 2 + 4 , 2);
lcd.write(byte(4));
}
if (incH % 2 == 1)
{
lcd.setCursor(mod_incH / 2 + 4 , 2);
lcd.write(byte(5));
}
delay(200);
incH++;
}
if (digitalRead(4) && opz == 0 && flagH == 1) //setta cavalieri
{
vett[mod_incH] = !vett[mod_incH];
scansione();
delay(200);
}
} //fine main
void temperatura()
{
int t = dht.readTemperature();
int h = dht.readHumidity();
gradiC = t;
lcd.setCursor(0,2);
lcd.print("Temp:" + String(t) + char(0xDF) + "C ");
lcd.print(" Umid:" + String(h) + "% ");
trTemp = millis();
}
void scansione() //aggiorna i cavalieri
{
int i = 0;
for (i = 0; i < 12; i++)
{
if (vett[i * 2] == 0 && vett[i * 2 + 1] == 0)
{
lcd.setCursor(i + 4, 3); //offset 2 per centrare i caratteri sul display
lcd.write(byte(0));
}
if (vett[i * 2] == 1 && vett[i * 2 + 1] == 0)
{
lcd.setCursor(i + 4, 3); //offset 2 per centrare i caratteri sul display
lcd.write(byte(1));
}
if (vett[i * 2] == 0 && vett[i * 2 + 1] == 1)
{
lcd.setCursor(i + 4, 3); //offset 2 per centrare i caratteri sul display
lcd.write(byte(2));
}
if (vett[i * 2] == 1 && vett[i * 2 + 1] == 1)
{
lcd.setCursor(i + 4, 3); //offset 2 per centrare i caratteri sul display
lcd.write(byte(3));
}
}
}