Sto "costruendo" un serra non troppo grande con mio padre, sono riuscito bene o male a scrivere tutto il codice ma c'è una parte che non mi è proprio chiara, la parte della gestione delle ventole (premetto che è circa una settimana che cerco ovunque una possibile soluzione cercando su internet, chiedendo ad amici e anche su vari forum ma senza alcun successo);
Il problema che mi porto avanti e che non riesco a risolvere è evitare che le ventole (azionate una volta superata una certa soglia di temperatura rilevata da un DHT11) facciano da "interruttore" ovvero attacca e stacca, in quanto inizialmente le avevo programmate così e in questo modo appena varcata di un grado la soglia partono le ventole e pochi secondi dopo si spengono dato l'abbassamento della temperatura di 1 °C facendo così un attacca e stacca continuo;
Forse mi sono dilungato troppo ma era in modo da rendere il tutto più chiaro,
La cosa che non riesco a fare è quindi scrivere la parte di codice relativa all'accensione delle ventole che permetta ad esse di accendersi superata una certa soglia ( quindi quando t >= valore_massimo_temp che è da me impostato a 40 °C) e rimanere accese fin quando la temperatura non scenda sotto ad un'altra soglia, quella della temperatura ideale (quindi quando t <=valore_ideale_temp che è da me impostato a 35 °C).
Ho provato in mille modi, con mille variabili e con mille cicli ma essendo alle prime armi purtroppo senza successo.
Spero vivamente che qualche saggio di Arduino o della programmazione riesca ad aiutarmi, Grazie mille in anticipo.
Buongiorno e benvenuto nella sezione Italiana del forum,
cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazioneNELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.
Grazie,
Guglielmo
P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto.
Il problema sembra relativo alla mancanza di isteresi, posta il codice.
Se il codice è molto grande conviene creare uno sketch di massima che comprenda il sensore, il comando (relè o altro) e il codice che in relazione alla temperatura esegue il codice.
Qui a seguire un link al primo dei 3 articoli su termostati con arduino:
Questa è la parte di codice relativa alla gestione del relè delle ventole in base alla temperatura:
const int valore_massimo_temp = 40; //Temperatura massima che la serra può raggiungere
const int valore_ideale_temp = 35; //Temperatura ideale della serra alla quale deve essere riportata dalle ventole non appena si è raggiunta la temperatura massima
bool att_ventola = LOW;
int t=0, h=0,
//librerie per DHT11
#include "DHT.h"
#define DHTPIN 12 //sensore collegato al pin 12
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup() {
// PIN 10 al relè - IN2
pinMode(10, OUTPUT);
// Avvio sensore DHT11
dht.begin();
}
void loop() {
// Lettura umidità e temperatura del sensore DHT11
h = dht.readHumidity();
t = dht.readTemperature();
// Misura la temperatura e se maggiore di 39 gradi attiva relè per accendere la ventola
if (t >= valore_massimo_temp){
att_ventola = HIGH;
}
if(att_ventola == HIGH){
digitalWrite (10, HIGH); // Attiva Relè 2
if(t <= valore_ideale_temp){
digitalWrite (10, LOW); // Spegni Relè 2
att_ventola = LOW;
}
}
Nel frattempo cercherò di capire qualcosa di questa isteresi
nel frattempo ne approfitto per ringraziarti e per dei chiarimenti:
dato che la temperatura ideale è 35 gradi e la massima è 40 gradi, nel mio codice l'inizializzazione dell'isteresi dovrà essere così ? ---> const float isteresi = 5.0; // isteresi
Purtroppo non ho ancora avuto modo di verificare la cosa dato il mio non riuscire a trovare un codice adeguato; comunque uso due ventole da 5V che posso tranquillamente sostituire con ventole da 12V, quindi in caso il tempo sia troppo elevato posso provare delle combinazioni e cercare la soluzione più adeguata.
valore ideale_temp = valore_massimo_temp - isteresi
I termostati elettromeccanici hanno 5°C di isteresi, mentre per quelli digitali usati nel frigo di casa in genere isteresi = 2°C.
C'è anche da considerare la temperatura dell'aria prelevata dalla ventola in aspirazione e la posizione della sonda tenendo conto che il calore si stratifica e la massima temperatura si ha nel cielo (tetto).
ora sono impossibilitato a provare il codice sulla serra, quindi mi sono fatto un piccolo impiantino su una breadboard con un termistore ed un led, in modo tale da replicare lo stesso principio e provare ad ultimare il codice,
const float isteresi = 25;
int valore_base = 270;
int valore_massimo = valore_base + isteresi;
int valore_ideale = valore_massimo - isteresi;
void setup() {
Serial.begin(9600);
pinMode(12, OUTPUT);
}
void loop() {
int v = analogRead(A0);
Serial.println(v);
digitalWrite(12, LOW);
if (v >= valore_massimo){
digitalWrite(12,HIGH);
Serial.println("soglia massima varcata");
} else if (v <= valore_ideale){
digitalWrite (10, LOW);
Serial.println("soglia ideale ");
}
delay(500);
}
Sicuramente sbaglio, però il problema che mi si pone è sempre lo stesso finche la temperatura è maggiore della soglia massima allora il led (ventola per la serra) si accende, il problema è che appena la temperatura si abbassa al di sotto della soglia massima allora l'esecuzione del codice non entra più nell'if.
Come posso fare quindi? ho provato ad usare l'isteresi ma non riesco comunque, dove sbaglio?
const float isteresi = 25;
int valore_base = 270;
int valore_massimo = valore_base + isteresi;
int valore_ideale = valore_base - isteresi;
// valore_massimo = 270 + 25 = 295
// valore_ideale = 270 - 25 = 245
// In questo caso isteresi vale 50 perché la differenza tra le due soglie
// Isteresi = 295 - 245 = 50.
// Per usare isteresi = 25
// int valore_massimo = valore_base
void setup() {
Serial.begin(9600);
pinMode(12, OUTPUT);
}
void loop() {
int v = analogRead(A0);
Serial.println(v);
digitalWrite(12, LOW);
if (v >= valore_massimo){
digitalWrite(12,HIGH);
Serial.println("soglia massima varcata");
} else if (v <= valore_ideale){
digitalWrite (10, LOW);
Serial.println("soglia ideale ");
}
}
Meglio uniformarsi con la terminologia standard in cui il setpoint è il punto di intervento in cui deve accadere qualcosa.
# Pseudo codice
// t = 40.01 °C
// setpoint = 40.0 °C
// isteresi = 5.0
if (t >= setpoint) { // soglia OFF->ON
fan(ON);
} else if (t <= setpoint - isteresi) { // soglia ON->OFF
fan(OFF);
}
La soglia ON->OFF vale 40 - 5 = 35 (setpoint - isteresi), quando t <= 35 si spegne la ventola.
Il caso specifico lo equiparo a quello del frigorifero, poiché accendendo la ventola la temperatura tenderà a scendere, allora la funzione del termostato cambia leggermente:
// Il valore di g_setpoint è regolato tramite un potenziometro e
// supponiamo di regolarlo a 35.0°C.
bool checkThermostate(bool state) {
switch (state) {
case LOW: // 40°C >= 35°C + 5°C = 40°C accende ventola
if (g_temperature >= g_setpoint + g_isteresi) {
state = HIGH;
}
break;
case HIGH: // 35°C <= 35°C spegne ventola
if (g_temperature <= g_setpoint) {
state = LOW;
}
break;
} // end switch (thermostateState)
return state;
} // end checkThermostate()
Grazie al vostro aiuto ho risolto la problematica, in questo modo:
#define soglia_on 400
#define soglia_off 370
int stato = LOW;
void setup() {
Serial.begin(9600);
pinMode(12, OUTPUT);
}
void loop() {
int v = analogRead(A0);
Serial.println(v);
if (v >= soglia_on){
stato = HIGH;
Serial.println("ventole accese");
}
if (v < soglia_off){
stato = LOW;
Serial.println("temperatura ideale");
}
digitalWrite(12, stato);
delay(2500);
}
Ora proverò ad adattare questo codice alla serra;
Grazie ancora a tutti. .
Ottimo, hai soglie fisse e isteresi di 400 - 370 = 30.
Però ti sconsiglio di applicarlo paro paro nella serra.
Quanto meno se preferisci fatti un tua funzione da richiamare nel loop. Quando si sposta il codice in una funzione si da per scontato che il codice funziona ed è testato e metterlo in una funzione significa rimuoverlo dal loop dove involontariamente si possono apportare modifiche.