#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DHT.h>
#include <WIFI.h>
#include <PubSubClient.h>
#include <WebServer.h>
//Configurazione mqtt e wifi
const char* ssid = "Wokwi-GUEST"; //nome wifi
const char* password = ""; //password wifi
const char* mqtt_server = "broker.hivemq.com"; //server mqtt
//oggetti mqtt e wifi
WiFiClient espClient;
PubSubClient client(espClient);
WebServer server(80);
#define max_valvole 4 //numero di valvole termostatiche
#define DHTtype DHT22 //tipo di sensore utilizzato
#define button_pin_add 13 //pulsante che aggiunge le valvole per arrivare ad un max di 4
#define button_pin_remove 14 //pulsante che rimuove le valvole
//CODICE GESTIONE N VALVOLE TERMOSTATICHE
int dht_pin[max_valvole] = {4,5,18,19};
DHT* dht[max_valvole];
float soglie[max_valvole] = {22.0, 23.0, 21.0, 20.0};
bool stato_valvole[max_valvole] = {false};
int valvole_attive = 2; //valvole attive inizialmente
int pagina_lcd = 0; //variabile per la gestione delle pagine del display
LiquidCrystal_I2C lcd(0x27, 16, 2);
void connessione_wifi(){
//connessione wifi
WiFi.begin(ssid, password);
lcd.clear();
lcd.print("Connessione...");
while(WiFi.status()!=WL_CONNECTED){
delay(500);
lcd.print(".");
}
Serial.println("\nIP: ");
lcd.setCursor(0, 1);
Serial.println(WiFi.localIP());
}
//funzione per inviare lo stato delle valvole tramite mqtt
void valve_status(){
for(int i=0;i<valvole_attive;i++){
String topic = "termostato/valvola/"+ String(i+1);
String mess = "temperatura: "+String(dht[i]->readTemperature())+"C, Stato: "+(stato_valvole[i] ? "ON":"OFF");
client.publish(topic.c_str(), mess.c_str());
Serial.println("Pubblicato: "+topic+" --> "+mess);
}
}
//funzione per ricere i messaggi mqtt
void callback(char* topic, byte* payload, unsigned int length){
Serial.print("Messaggio ricevuto: ");
Serial.print(topic);
String messaggio = "";
for(int i=0;i<length;i++){
messaggio+=(char)payload[i];
}
Serial.println("Messaggio: "+messaggio);
if(String(topic)=="termostato/controllo"){
if(messaggio=="aggiungi"){
if(valvole_attive<max_valvole){
valvole_attive++;
Serial.println("Valvola aggiunta");
}else if(messaggio=="rimuovi"){
if(valvole_attive>0){
valvole_attive--;
Serial.println("Valvola rimossa");
}
}
}
}
}
//funzione per collegarsi al broker mqtt
void connect_broker(){
while(!client.connected()){
Serial.println("Connessione al broker mqtt...");
if(client.connect("ESP32client")){
Serial.println("Connesso al broker mqtt");
client.subscribe("termostato/controllo");
}else{
Serial.println(client.state());
Serial.println("Connessione fallita, riprovo tra 5 secondi");
delay(5000);
}
}
}
void homepage(){
String html = "<html><head><title>Termostato</title></head><body>";
html+="<h1>Monitoraggio valvole termostatiche</h1>";
for(int i=0;i<valvole_attive;i++){
html+="<p>vavlola "+String(i+1) + ": ";
html+=String(dht[i]->readTemperature())+"C ";
html+=(stato_valvole[i] ? "ON":"OFF") +String("</p>");
}
html+="</body></html>";
server.send(200, "text/html", html);
}
void setup(){
pinMode(button_pin_add, INPUT_PULLUP);
pinMode(button_pin_remove, INPUT_PULLUP);
lcd.begin(16, 2);
lcd.init();
lcd.backlight();
for(int i=0;i<max_valvole;i++){
dht[i] = new DHT(dht_pin[i], DHTtype);
dht[i]->begin();
}
Serial.begin(115200); //debug
connessione_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
server.on("/", homepage);
server.begin();
/*
lcd.setCursor(0, 0);
lcd.print("Termostato ON");
delay(2000);
*/
}
void loop(){
if(!client.connected()){
connect_broker();
}
client.loop();
server.handleClient();
lcd.clear();
//lettura temperatura e aggiornamento stato valvola
for(int i=0; i<valvole_attive; i++){
float temperature = dht[i]->readTemperature();
if(temperature >=soglie[i]){
stato_valvole[i] = false; //off
}else{
stato_valvole[i] = true; //on
}
//temperatura e stato valvola mostrata su display
for(int i=0;i<2;i++){
int indice=pagina_lcd*2+i;
if(indice<valvole_attive){
lcd.setCursor(0, i);
lcd.print("T");
lcd.print(indice+1); //indice+1 perchè indice parte da 0
lcd.print(":");
lcd.print(temperature);
lcd.print("C ");
lcd.print(stato_valvole[indice] ? "ON":"OFF");
}
}
}
valve_status();
pagina_lcd++;
if(pagina_lcd*2>valvole_attive){
pagina_lcd=0;
}
delay(3000);
/*
//aggiunta delle valvole
if(digitalRead(button_pin_add)==LOW){
if(valvole_attive<max_valvole){
valvole_attive++;
lcd.clear();
lcd.print("Valvola aggiunta");
}else{
lcd.clear();
lcd.print("Valvole al max");
}
delay(2000);
}
//rimozione delle valvole
if(digitalRead(button_pin_remove)==LOW){
if(valvole_attive>0){
valvole_attive--;
lcd.clear();
lcd.print("Valvola rimossa");
}else{
lcd.clear();
lcd.print("Nessuna valvola");
}
delay(2000);
}
Serial.println("bottone remove: ");
Serial.println(digitalRead(button_pin_remove));
Serial.println("bottone add: ");
Serial.println(digitalRead(button_pin_add));
server.handleClient();
*/
}