Sei davvero soddisfatto del tuo termostato? No? Allora costruiscilo da solo in pochi passi con Arduino!
La domotica è il futuro delle nostre abitazioni e con Arduino è possibilie creare un termostato fai da te che può essere utilizzato sia d’inverno collegandolo alla caldaia che d’estate collegandolo all’impianto di raffeddamento.
In questo articolo andrò a mostrare i principi fondamentali su cui si basa il progetto del termostato con Arduino, confrontando anche due diversi sensori di temperatura: una termoresistenza e un integrato LM35.
I componenti necessari per realizzare il nostro termostato fai da te sono:
Arduino Uno | Cerca su Amazon |
Sensore temperatura LM35 | Cerca su Amazon |
Relè 5V | Cerca su Amazon |
Display LCD 16×2 I2C | Cerca su Amazon |
Breadboard | Cerca su Amazon |
Cavetti Vari | Cerca su Amazon |
Il circuito da assemblare è quello nell’immagine sottostante:
Per la scrittura di questo articolo ho collegato il relè ad una ventola da PC per constatare rapidamente l’effettiva accensione e spegnimento.
Per quanto riguarda il collegamento del termostato in un caso reale si deve consultare il manuale di istruzioni della propria caldaia o chiedere al proprio elettricista di fiducia. Non mi assumo alcuna responsabilità per danni a cose o persone a causa di vostri errori o a causa di problemi tecnico ad essi annessi. Ricordate inoltre le norme antinfortunistiche atte a proteggere voi e chi vi sta intorno, soprattutto quando si ha a che fare con la corrente.
Il codice sorgente da caricare sull’Arduino è il seguente:
#include <Time.h> #include <TimeLib.h> #include <LiquidCrystal.h> #define LM35pin 0 // connect LM35 Vout pin to arduino analog pin 0 #define LM35ref 1 // connect 2x 1N1418 diodes between LM35 ground pin and ground #define thermistor_pin 3 #define btnPin1 11 #define btnPin2 12 #define relayPin 8 #define LCD_RS 2 #define LCD_EN 3 #define LCD_D4 4 #define LCD_D5 5 #define LCD_D6 6 #define LCD_D7 7 // initialize the library with the numbers of the interface pins LiquidCrystal lcd(LCD_RS, LCD_EN, LCD_D4, LCD_D5, LCD_D6, LCD_D7); String giorni[7] = {"Dom","Lun","Mar","Mer","Gio","Ven","Sab"}; float myTemp = 26.0; int btnState1 = 0; int lastBtnState1 = 0; int btnState2 = 0; int lastBtnState2 = 0; byte iconTermo[8] = { B00100, B01010, B01010, B01110, B01110, B11111, B11111, B01110 }; byte iconDegree[8] = { B01000, B10100, B01000, B00011, B00100, B00100, B00011, B00000 }; byte iconMan[8] = { B00100, B01010, B00100, B01110, B10101, B00100, B01010, B01010 }; void setup() { setTime(23,31,0,10,5,18); lcd.createChar(0, iconTermo); lcd.createChar(1, iconDegree); lcd.createChar(2, iconMan); lcd.begin(16, 4); pinMode(btnPin1, INPUT); pinMode(btnPin2, INPUT); pinMode(relayPin, OUTPUT); } void loop() { digitalClockDisplay(); // LM35 float temp2 = readLM35(true); // true = temp in celsius, false = temp in fahrenheit lcd.setCursor(16, 0); lcd.write((byte) 0); lcd.print(temp2, 1); lcd.write((byte) 1); lcd.print(" "); // thermistor int sensorValue = analogRead(thermistor_pin); float temp3 = Thermistor(sensorValue)/2; float temp4 = round(temp3 * 2.0) / 2.0; lcd.write((byte) 0); lcd.print(temp4, 1); lcd.write((byte) 1); // ***** gestisco i pulsanti per regolare la temperatura ***** // pulsante più btnState1 = digitalRead(btnPin1); if (btnState1 != lastBtnState1) { if (btnState1 == HIGH) { // off => on myTemp++; } } lastBtnState1 = btnState1; // pulsante meno btnState2 = digitalRead(btnPin2); if (btnState2 != lastBtnState2) { if (btnState2 == HIGH) { // off => on myTemp--; } } lastBtnState2 = btnState2; // temperatura utente lcd.setCursor(16,1); lcd.write((byte) 2); lcd.print(myTemp,1); lcd.write((byte) 1); lcd.print(" "); if(myTemp<temp2) { // accendo la ventola lcd.print("ON "); digitalWrite(relayPin, LOW); } else { lcd.print("OFF"); digitalWrite(relayPin, HIGH); } delay(100); } /* Legge la temperatura */ float readLM35(boolean celsius) { int analogVal = 0; for(int j = 0; j < 10; j++) // takes 10 samples to make sure we get a good value { analogVal += (analogRead(LM35pin) - analogRead(LM35ref)); // subtract Vout ADC reading from LM35 ground ADC reading delay(10); } float tempC = (5 * analogVal * 10) / 1023; if (celsius) { return tempC; // return temperature in degrees Celsius } else { return (tempC * 9 / 5) + 32; // return temperature in degrees Fahrenheit } } double Thermistor(int RawADC) { double Temp; Temp = log(((10240000/RawADC) - 10000)); Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp ); Temp = Temp - 273.15; // Convert Kelvin to Celsius return Temp; } void digitalClockDisplay() { lcd.setCursor(0,0); lcd.print( giorni[weekday()] ); lcd.print(" "); lcd.print(day()); lcd.print("/"); lcd.print(month()); lcd.print("/"); lcd.print(year()); lcd.setCursor(0,1); lcd.print(" "); lcd.print(hour()); printDigits(minute()); printDigits(second()); } void printDigits(int digits) { lcd.print(":"); if(digits < 10) lcd.print('0'); lcd.print(digits); }
Nel display vengono mostare le temperature rilevate dai due sensori, come si nota sono leggermente diverse a causa della diversa accuratezza.
Con il pulsante YYY si aumenta la temperatura di soglia per l’accesione della ventola mentre con il pulsante YYY si abbassa.
Il relè ha può operare in modalita NC (normally closed) oppure NO (normally open). In questo caso è collegato alla porta NO.
Futuri sviluppi
Il termostato così configurato necessita di diversi miglioramenti sia hardware che software. Per gestire la pianificazione oraria sarà indispensabile un modulo RTC (Real Time Clock), inoltre il display che ho utilizzato utilizza molte porte dell’Arduino pertando dovrà essere dotato di un modulo I2C e per ultimo ma non meno importante ritengo sia provare il sensore di temperature e umidità DHT22.
Ho tentato di eseguire però lo sketch da errore nel valore setTime() in quanto non lo trova. Inoltre viene dichiarato utilizzo di uno schermo lcd l2c però nel disegno sembra che venga utilizzato un 16×2. Mi può dare una mano perchè il tuo progetto mi sembra molto interessante.
GRazie