Oggi ti racconto il progetto di Stefano: Termostato e sensore di livello con arduino. Tutto ha avuto inizio quando Stefano commentando l’articolo sull’RTC mi ha chiesto una mano per il suo progetto a cui ho risposto ( leggi risposte nei commenti )
Oggi mi ha scritto per informarmi di aver realizzato quello a cui stava lavorando e la volontà di condividere con altri appassionati il suo lavoro.
Non ho saputo resistere e siccome questo blog è nato anche con lo scopo di diffondere tutti i progetti e le idee che riguardano le passioni che ci accomunano ho voluto dedicare a Stefano questo articolo.
Lo schema del Termostato e sensore di livello con arduino
Lo schema realizzato da Stefano è quello che hai visto in copertina e che ti ripropongo per leggerlo insieme:
Il Termostato e sensore di livello con Arduino si basa sui seguenti componenti:
- n.1 arduino UNO
- n.1 sonda temperatura DS18B20
- n.1 sonda di livello
- n.1 Lcd 16×2
- n.1 relay shield
- n. 2 pulsanti n.a.
- n.1 potenziometro da 20Kohm
- n.3 resistenze di pull-up da 10Kohm ciascuna
- n.1 resistenza da 4,7Kohm
I collegamenti nello schema sono chiari:
la sonda è connessa al pin 13 di arduino mediante la resistenza da 4,7Kohm;
il display LCD 16×2 è collegato ai pin 2,3,4,10,11 e 12;
la sonda di livello è connessa al pin A3 ( Analogico 3 ) mediante una delle resistenze di pull-up da 10Kohm;
i pulsanti sono connessi al pin A1 ed A2 mediante le altre due resistenza di pull-up da 10Kohm.
Lo sketch del Termostato e sensore di livello con Arduino
Lo sketch lo puoi prelevare direttamente dal sito di Stefano, lo riporto per completezza dell’articolo:
/* Termostatino antigelo: Lettura sensore termico ds18b20, visualizzazione su display 16x2, modifica soglia con 2 pulsanti + e - su ingressi analogici, visualizzazione soglia durante la modifica, Sensore di livello ad immersione tramite ingresso analogico e comando relais. Pin Analogico 1 = pulsante incremento temperatura soglia Pin Analogico 2 = pulsante riduzione temperatura soglia Pin Analogico 3 = sonda di livello Pin Digitali 2, 3, 4, 10, 11, 12 = lcd DB7, DB6, DB5, DB4, E, RS Pin digitali 5, 6, 7, 8 = modulo relais Pin Digital 13 = linea dati sensore DS18B20 Piedinatura DS18B20: pin 1 = GND, pin 2 = DQ, pin 3 = Vdd (Valida tra 3,3V e 5V) */ #include <OneWire.h> //libreria per ds18b20 #include <DallasTemperature.h> //libreria per conversione valore #include <swRTC.h> //libreria per RTC #include <LiquidCrystal.h> //libreria per lcd #define ONE_WIRE_BUS 13 // Il terminale data del sensore è connesso alla porta 13 di Arduino OneWire oneWire(ONE_WIRE_BUS); // Imposto la comunicazione oneWire per il ds18b20 DallasTemperature sensors(&oneWire); // Passo le info di oneWire alla DallasTemperature LiquidCrystal lcd(12, 11, 10, 4, 3, 2); //stabilisco le uscite digitali per lcd 4 bit swRTC rtc; //creo un'istanza della libreria RTC int rele_out1 = 5; //stabilisco l'uscita digitale per il relè 1 int rele_out2 = 6; //stabilisco l'uscita digitale per il relè 2 int rele_out3 = 7; //stabilisco l'uscita digitale per il relè 3 int rele_out4 = 8; //stabilisco l'uscita digitale per il relè 4 int pulsantepiu; //pulsante incremento temperatura di soglia int pulsantemeno; //pulsante diminuisco temperatura di soglia int tx; //temperatura di soglia int cont; //contatore usato per ottenere un valore medio di temperatura int temperatura; //temperatura rilevata int durata; //conteggio minuti per temporizzazione int livello; //ingresso sonda livello 170 cm byte grado[8] = { //creo i dati per il carattere ° 0b00010, 0b00101, 0b00010, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, }; void setup(){ Serial.begin(9600); //inizializzo la seriale sensors.begin(); //inizializzo la libreria per leggere il sensore lcd.createChar(0, grado); //associo i dati del ° al carattere custom 0 lcd.begin(16, 2); //dichiaro il tipo di lcd pinMode(rele_out1, OUTPUT); //assegno il modo uscita digitale al pin 5 pinMode(rele_out2, OUTPUT); //assegno il modo uscita digitale al pin 6 pinMode(rele_out3, OUTPUT); //assegno il modo uscita digitale al pin 7 pinMode(rele_out4, OUTPUT); //assegno il modo uscita digitale al pin 8 tx = 1; //temperatura di soglia iniziale (valore di sicurezza in caso di interruzioni di alimentazione) pulsantepiu = 0; //assegno valore 0 iniziale al pulsantepiù pulsantemeno = 0; //assegno valore 0 iniziale al pulsantemeno livello = 0; //assegno valore 0 iniziale alla sonda di livello rtc.stopRTC(); //blocco RTC per inserire i valori iniziali rtc.setTime(0, 00, 00); //metto valori a zero perché rtc.setDate(01, 01, 2012); //devo usare RTC solo come timer rtc.startRTC(); //avvio RTC } void loop() { sensors.requestTemperatures(); // Invia il comando di lettura delle temperatura int durata = rtc.getMinutes(); //acquisisco i minuti if (durata > 10){ //se durata è maggiore di 10 minuti rtc.stopRTC(); //blocco RTC rtc.setTime(0, 00, 00); //azzero i valori rtc.setDate(01, 01, 2012); //per poter riconteggiare da zero rtc.startRTC(); //riavvio rtc } int pulsantepiu = analogRead(A1); //lettura ingresso analogico 1 e assegnazione del valore a pulsantepiù int pulsantemeno = analogRead(A2); //lettura ingresso analogico 2 e assegnazione del valore a pulsantemeno if (pulsantepiu == 0){ //se il pulsantepiù vieno premuto verso il negativo tx = tx ++; //la variabile temperatura di soglia tx incrementa di una unita lcd.clear(); //cancello il display lcd.print("Temperatura di"); //scrivo un testo lcd.setCursor(0, 1); //riposiziono il cursore lcd.print("soglia: "); //scrivo di nuovo un testo lcd.print(tx,DEC); //scrivo il valore impostato della temperatura di soglia lcd.write((byte)0); //scrivo il ° lcd.print ("C"); //scrivo il C di Celsius delay(1000); //ritardo di 1 secondi per la lettura } if (pulsantemeno == 0){ //se il pulsantemeno vieno premuto verso il negativo tx = tx --; //la variabile temperatura di soglia tx decrementa di una unità lcd.clear(); //cancello il display lcd.print("Temperatura di"); //scrivo un testo lcd.setCursor(0, 1); //riposiziono il cursore lcd.print("soglia: "); //scrivo di nuovo un testo lcd.setCursor(10, 1); //riposiziono il cursore lcd.print(tx,DEC); //scrivo il valore impostato della temperatura di soglia lcd.write((byte)0); //scrivo il ° lcd.print ("C"); //scrivo il C di Celsius delay(1000); //ritardo di 1 secondi per la lettura } while (analogRead(A3) == 0) { //lettura ingresso analogico A3 e confronto con valore 0 (CONTATTO CHIUSO) lcd.clear(); //con il livello troppo alto avviso su display lcd.print ("! Livello Alto !"); //che il livello è alto e lcd.print(" Valvola Aperta "); //che apro la valvola digitalWrite(rele_out1, HIGH); //comando anche il rele 1 di apertura valvola digitalWrite(rele_out2, HIGH); //comando anche il rele 2 di apertura valvola digitalWrite(rele_out3, HIGH); //comando anche il rele 3 di apertura valvola digitalWrite(rele_out4, HIGH); //comando anche il rele 4 di apertura valvola } /*Lettura temperatura con ds18b20 */ int temperatura = sensors.getTempCByIndex(0); //lettura ingresso digitale 13 e assegnazione del valore alla variabile temperatura if(temperatura <= tx && durata == 10){ //se la temperatura rilevata è minore o uguale rispetto lcd.clear(); //alla temperatura di soglia e il tempo lcd.print("Temperatura "); //trascorso dall'ultimo ciclo è di 10 minutì lcd.print(temperatura,DEC); //scrivo sul display il valore e lcd.write((byte)0); //avviso che il contatto è chiuso lcd.print("C"); lcd.setCursor(0, 1); //con la scritta " Valvola Aperta " lcd.print(" Valvola Aperta "); //per finire digitalWrite(rele_out1, HIGH); //comando anche il rele 1 di apertura valvola digitalWrite(rele_out2, HIGH); //comando anche il rele 2 di apertura valvola digitalWrite(rele_out3, HIGH); //comando anche il rele 3 di apertura valvola digitalWrite(rele_out4, HIGH); //comando anche il rele 4 di apertura valvola delay(60000); // e comando i relè per un minuto }else{ //altrimenti scrivo lcd.clear(); //sempre sul display lcd.print(" Temperatura"); //il valore lcd.setCursor(0, 1); lcd.print("rilevata: "); lcd.print(temperatura,DEC); lcd.write((byte)0); lcd.print("C"); digitalWrite(rele_out1, LOW); //mantengo bassa l'uscita digitale 5 digitalWrite(rele_out2, LOW); //mantengo bassa l'uscita digitale 6 digitalWrite(rele_out3, LOW); //mantengo bassa l'uscita digitale 7 digitalWrite(rele_out4, LOW); //mantengo bassa l'uscita digitale 8 } /*invio le inforamazioni anche al serial monitor della IDE*/ Serial.print ("temperatura di soglia = "); Serial.println (tx, DEC); Serial.println (" "); Serial.print ("Temperatura rilevata = "); Serial.println (temperatura, DEC); Serial.println (" "); Serial.println (" "); Serial.println("durata"); Serial.println(durata,DEC); Serial.println(rtc.getSeconds(),DEC); Serial.println (" "); Serial.println (" "); }
Grazie Stefano !!!
33 commenti
Vai al modulo dei commenti
Ciao Mauro
Intanto grazie per l’articolo e se qualcuno ha idee o suggerimenti io sono sempre disponibile, non si finisce mai di imparare!
Ciao Stefano
Un articolo interessante , davvero molto curato in tutti gli aspetti,sopratutto nei commenti.
Complimenti Stefano
Un ringraziamento anche a Mauro , per lo spazio dedicato a questo articolo
Caricando il programma su arduino mi da questo errore: ‘ swRTC ‘does not name a type.
Potresti mandarmi la libreria swRTC.h per cortesia ? Non riesco a trovarla .
Grazie
Autore
Ciao Idris, non ho quelle libreria, il progetto lo ha realizzato Stefano e la libreria é una sua variante alla libreria originale RTCLib.
Prova a sostituirlo con quella originale che trovi ovunque nel web, e a fare le modifiche necessarie allo sketch, trovi molti miei tutorial sull’RTC nel blog.
Se non ci riesci puoi provare a scrivere a Stefano sul suo forum, trovi il link nella prima linea dell’articolo.
Mauro
Ciao Idris, la libreria puoi trovarla direttamente su arduino.cc ma per semplicità ti posto il link alla discussione sul forum in italiano, dove trovi anche il link per il download:
http://arduino.cc/forum/index.php/topic,73496.msg552421.html#msg552421
Autore
Grazie Stefano per il supporto 🙂
Mauro
Mi sembra il minimo che posso fare!
Ciao a tutti,
avevo intenzione di realizzare anch’io un strumento per misurare la temperatura con arduino, ma utilizzando un sensore a immersione ad esempio:
https://www.adafruit.com/products/381
In piú mi piacerebbe riuscire a calcolare anche il grado alcolico, ad esempio del vino.
Pensavo di acquistare arduino 2. Del punto uno sembra non ci siano problemi, ma del secondo non saprei da dove iniziare.
Se avete qualche consiglio vi sarei gradissimo 🙂
Grazie
mrkrunkle
Ciao, il sensore termico che ho utilizzato io è proprio come quello del link che hai segnalato sopra.
Secondo me la scelta di quale arduino utilizzare è soggettiva, dipende molto da cosa ci devi fare e di che hardware hai bisogno. Per il sensore alcoolico, da quello che so io ci sono dei sensori, ma rilevano dei gas, non so se possono andare bene per il tuo progetto.
Confesso di essere alle prime armi però mi sembra che nel setup manca la dichiarazione degli ingressi, può essere?
Il progetto è stato utilissimo. Per me è stata una fortuna trovare una soluzione con il sensore di temperatura. Il problema della PT100 infatti mi tormentava da un po’
Autore
Ciao Giovanni,
sei di certo un attento osservatore, tuttavia per la struttura dello sketch non devi dichiararli nella setup.
Se avessi dichiarato in alto i pin di input A0,A1 ed A2 sarebbe stato più corretto dichiarare questi pin come pin di INPUT.
In questo caso il codice arduino è buono e quando utilizzi il comando analogRead provvede a leggere l’ingresso anche senza dichiarazione di modalità.
Mauro
Salve, sono alle prime armi con arduino, mi piace smanettare, mi interessa il tuo progetto “Termostato e sensore di livello con Arduino “, ma purtroppo sono ancora all’antica , vorrei usare la vecchia sonda lm35, puoi darmi una dritta per modificare il tuo sketch per sudetta sonda, e c’è il problema della temperatura negativa.
In attesa di una risposta grazie.
Autore
Ciao Luca,
ho acquistato tempo fa la sonda LM35 per fare anche io dei test, tuttavia non l’ho ancora provata.
Se non ricordo male è una sonda analogica ossia varia il potenziale sul piedino di output in funzione della temperatura rilevata.
In tal caso ti basta un semplice sketch in grado di leggere il valore analogico sul pin a cui hai collegato la sonda.
Mauro
Ciao Mauro sono ancora Giovanni, avrei un’altra cosa importante da chiederti.
Ho notato che la variabile “temperatura” è stata dichiarata come INT.
Significa che la libreria restituisce solo valori interi?
Come posso fare se mi servisse un punto decimale?
Sono quasi pronto per iniziare, la sonda dovrebbe arrivarmi la settimana prossima, un saluto e un grazie anticipato 🙂
Autore
Ciao Giovanni,
questo progetto è stato realizzato da un appassionato lettore del blog che ha voluto condividerlo.
Io non ho mai testato la sonda utilizzata in questo sketch anche se ho acquistato una sonda con l’intenzione di provarla.
In ogni caso per aiutarti ho aperto il file DallasTemperature.cpp ed ho trovato la dichiarazione del metodo usato per recuperare la temperatura dalla sonda:
float DallasTemperature::getTempCByIndex(uint8_t deviceIndex)
Siccome è dichiarato float deduco che il valore restituito sua un valore decimale.
Mauro
Ciao
Sto cercando di impostare le soglie ma non capisco perchè non riesco a farla decrescere…
Inoltre mi lampeggianop da una all’altra, mi potresti dare qualche indicazione?
Grazie
Autore
Ciao Michele,
come leggi in fondo ad ogni articolo è richiesto di non incollare codice degli sketch.
In particolare per questo progetto lascio che sia l’autore a darti aiuto.
Mauro
Salve anche io sto cercando di costruire un cronotermoststo per il mio acquario,con un lcd keypad,sensore ds18b20,scheda 8 relè,rtc e arduino mega.
Io volevo impostare una temperatura in modo che se la temperatura si abbassa mi si accende il riscaldatore,e se si alza mi si accendono le 4 ventole da pc a 12 volt.
Potete darmi dei consigli?
Autore
Ciao Alessandro,
il progetto che vuoi realizzare non è complesso.
Ti consiglio di procedere con passi semplici:
– verifichi la lettura del sensore
– verifichi di riuscire ad attivare i relè singolarmente
– controlli la scrittura sul display
dopo ti sarà più semplice scrivere lo sketch totale.
Mauro
Ciao Mauro,
compilando il sorgente messo a disposizione ottengo dal compilatore “Errore durante la compilazione”,
utilizzo l’ultimo IDE Versione 1.0.5-r2
Puoi darmi qualche consiglio?
Autore
Ciao Giovanni,
senza l’errore è impossibile aiutarti.
Ho scritto anche un articolo dedicati agli errori che solitamente capitano in fase di compilazione, prova a leggerlo e verificare se tra quelli c’è un errore simile a quello che ti si verifica.
Bellissimo programma …
Io volevo sapere se è possibilire regolare tarare il sensore di livello dei liquidi con Arduino .. dato che ho costruito una mini centrale idroelettrica con ripompaggio.. l’unico problema è che il sensore di livello mi fa sfasare l’lcd e il relè che attiva la pompa
Autore
Ciao Luciano,
dipende dal sensore che stai utilizzando, se lo conosco posso aiutarti in caso contrario dovrai chiedere a chi ha utilizzato il modello simile al tuo od al produttore.
Salve Mauro e Stefano.
Ho un problema con il codice: premendo i pulsanti non si modifica il valore di tx.
Ho controllato il corretto collegamento dei pulsanti, con un efficace
int sensorValue1 = analogRead(A0);
int sensorValue2 = analogRead(A1);
Serial.println(sensorValue1);
Serial.println(sensorValue2);
che mi danno normalmente il valore di 1021, che diventa 0 con pulsante premuto.
Tx però rimane sempre quella preimpostata.
Avete suggerimenti? grazie
Ho risolto sostituendo il
tx = tx ++;
Con invece
{tx++;}
Autore
Ottimo Gianni !!!
per quale motivo il compilatore preferisce una modalità di scrittura piuttosto che un’altra?
non dovrebbero essere equivalenti?
Autore
Ciao Gianni,
ti riferisci alla differenza tra scrivere
tx = tx ++;
oppure
tx++;
Non ne sono certo al 100% ma la prima penso sia sbagliata, lo spazio tra tx e il segno ++ non è accettato come modo per incrementare una variabile.
Francemente io ho imparato a scrivere tx++; e non saprei dirti cosa accade se distanzi i segni dalla variabile.
No, mi riferisco alla differenza tra
tx = tx++;
oppure
{tx++;}
Autore
Ciao Gianni,
a parte le {}, che io non uso, mi sembra che la differenza sia quella che ti ho indicato nella risposta precedente.
Non essendo un programmatore C lascio a chi è più competente di me chiarirti perché una opzione sia migliore o peggiore dell’altra.
Autore
Ciao Gianni,
lascio a Stefano, autore del progetto, la risposta alla tua osservazione.
Ciao e grazie del progetto. COMPLIMENTI
Vorrei chiederti …come potrei adattare questo progetto ad un sistema di riempimento di una vasca di acquario, governato da un galleggiante e l’acqua prelevata da una cisterna in cui pesca una pompa uso acquario?
Autore
Ciao Rosario,
questo progetto è molto differente da quello che desidera realizzare.
Ti consiglierei di iniziare da un progetto più semplice che usi uno o due sensori di livello ed una pompa per il trasferimento dell’acqua dalla cisterna all’acquario.