problema temperatura con LM35

Ciao! sto facendo un controllo di temperatura per un acquario. uso un LM35 con filtro RC e i valori sono stabili. ho impostato delle soglie, una alta e una bassa, e un relè che scatta a seconda della T. succede però che quando la T è intorno ad una delle due soglie (quindi si trova prima sotto e subito dopo sopra alla soglia) il relè ovviamente si eccita e torna a riposo diverse volte in pochi secondi. la formula che ho usato per il sensore di T (trovata in internet) è la seguente:

tempC = (5.0 * tempC * 100.0)/1024.0;

questa formula non fa una media della T, forse basta fare la media di 2 temperature per risolvere? cosa mi consigliate di fare?
Grazie!
Ciao!

http://forum.arduino.cc/index.php?topic=181980.0

Le due soglie, evidentemente sono troppo ravvicinate e risentono dell'errore della misura.

Ad esempio, se hai impostato le due soglie a 25.1°C e 25.3°C è possibile che il sistema entri in oscillazione.

Se vuoi maggiore aiuto dovresti postare schema e programma.

le soglie sono 28.5 la massima e 27.6 la minima. il problema non si verifica quando la T è tra le due soglie e si avvicina a una soglia, ma si verifica quando la T è fuori dal range delle soglie e si avvicina ad una delle 2. non so se mi spiego?

if(tempC == 28.00){ //28 gradi è la temperatura ottimale per il mio acquario
digitalWrite (ventole,LOW);
digitalWrite (riscaldatore,LOW);
}
else if(tempC <= 27.60){ //SE LA TEMPERATURA è INFERIORE A 27.60 GRADI
digitalWrite(ventole,LOW); //SPEGNE VENTOLE
digitalWrite(riscaldatore,HIGH); //ACCENDE RISCALDATORE
}
if(tempC >= 28.5){ //SE TEMPERATURA SUPERIORE A 28.5 GRADI
digitalWrite(ventole,HIGH); //ACCENDE VENTOLE
digitalWrite(riscaldatore,LOW); //SPEGNE RISCALDATORE
}

Nell'ultimo confronto non hai inserito "else if"

Per fare la media di più lettura puoi usare questo --> Lettura consecutiva valori ingressi analogici - #4 by PaoloP - Hardware - Arduino Forum

Edit:
E' molto difficile per la natura dei float che riesca ad azzeccare 28.0, quell'if non funzionerà.
Per il riscaldatore dovresti usare un PID.

Ciao!
Scusate se scrivo solo ora ma ero impegnato...
mi è venuta un'idea che forse risolverebbe il problema ma vorrei sapere da voi se è fattibile.
In poche parole vorrei contare i cicli di loop. A quel punto l' idea sarebbe di verificare se la T rimane costante per N_cicli_di_loop e se è costante compie un'azione. dovrei così eliminare il problema dell' oscillazione...
Ma come si contano i cicli del loop se si possono contare..?
Non so se è fattibile questa soluzione e se è una soluzione valida... voi cosa ne pensate?

Come già detto, nel tuo sketch il primo e l'ultimo confronto sono inesatti: il primo è inutile (come ti ha gia detto il buon Paolo), mentre nell'ultimo hai omesso l'else.

Non complicarti la vita con cervellotiche soluzioni che non risolvono il problema.

Il tuo problema è dovuto ad un mix di problemi come le tolleranze, l'errore introdotto dai float, l'agitazione termica etc.
La soluzione è semplicissima, basta che introduci un fattore di isteresi, bastano +/- 0.2°, attorno ai valori delle soglie e sei a posto.
In pratica fai commutare on/off come serve al raggiungimento esatto del valore della soglia, lo stato del relè non deve più cambiare se la lettura flutta entro i +/- 0.2° dell'isteresi.

il codice è stato leggermente modificato:

if(tempMedia <= SOGLIA_T_MIN){ //se la temperatura è SOGLIA_T_MIN
digitalWrite(Ventole,LOW); //ventole off
digitalWrite(Riscaldatore,HIGH); //riscaldatore on

}
else if (tempMedia >= SOGLIA_T_MAX){ //SE TEMPERATURA SUPERIORE A SOGLIA_T_MAX
digitalWrite(Ventole,HIGH); //ventole on
digitalWrite(Riscaldatore,LOW); //riscaldatore off

}
else if (tempMedia >SOGLIA_T_MIN && tempMedia < SOGLIA_T_MAX){ //se la temperatura è tra le 2 soglie (temperatura desiderata)
digitalWrite(Ventole,LOW); //ACCENDE VENTOLE
digitalWrite(Riscaldatore,LOW); //SPEGNE RISCALDATORE

}

ho dato un range di un grado e nella parte del calcolo (che non sto a scrivere) ho fatto la media. e ho corretto gli errori. proverò la soluzione isteresi… grazie!

Ciao,
mi pare che stai utilizzando analogReference di default.
imposta :
analogReference (INTERNAL);
e la precisione migliora notevolmente.
La tensione massima letta sarà 1,1 volt.

ho provato a mettere nel setup:
analogReference (INTERNAL1V1);

prima avevo 22 gradi ora 113!!!!!
ho sbagliato qualcosa?

ok…ho messo in setup
analogReference(INTERNAL1V1);
e nella formula:
((5.0 * tempC_1 * 100.0)/1024.0)

al posto di 5 cambio con 1. forse dovrei mettere 1,1 dato è la V massima letta…
((1.0 * tempC_1 * 100.0)/1024.0)

sembrerebbe più preciso…

Metti nelle dichiarazioni delle variabili :

float vref = 1.1;

poi metti su setup :

analogReference( INTERNAL );

in loop :

temperatura = ( 100.0 * vref *tempC_1 ) / 1024.0;

fammi sapere, ciao

lucadh:
le soglie sono 28.5 la massima e 27.6 la minima. il problema non si verifica quando la T è tra le due soglie e si avvicina a una soglia, ma si verifica quando la T è fuori dal range delle soglie e si avvicina ad una delle 2. non so se mi spiego?

if(tempC == 28.00){ //28 gradi è la temperatura ottimale per il mio acquario
digitalWrite (ventole,LOW);
digitalWrite (riscaldatore,LOW);
}
else if(tempC <= 27.60){ //SE LA TEMPERATURA è INFERIORE A 27.60 GRADI
digitalWrite(ventole,LOW); //SPEGNE VENTOLE
digitalWrite(riscaldatore,HIGH); //ACCENDE RISCALDATORE
}
if(tempC >= 28.5){ //SE TEMPERATURA SUPERIORE A 28.5 GRADI
digitalWrite(ventole,HIGH); //ACCENDE VENTOLE
digitalWrite(riscaldatore,LOW); //SPEGNE RISCALDATORE
}

if(tempC == 28.00){… questa riga è un non senso, è quasi impossibile che viene beccata esattamente 28.00 si deve fare sempre >=X & <=Y se no ti viene l’esaurimento ]:smiley: