Controllo di vari componenti tramite sensori di temperatura e umidità

Ciao a tutti,
sto impazzendo dietro un progetto di controllo di una minuscola serra tramite arduino.
In pratica uso un sensore di temperatura lm35 e uno di umidità analogico a forcella di cui ora non ricordo il nome.
In sostanza i problemi sono 2: LM35 sul display mi fornisce dei valori di temperatura estremamente variabili che generalmente oscillano dalla temperatura corretta ai 40 °C di secondo in secondo (a volte 400 :o ) e non riesco a capire il perchè.
inoltre i comandi che avviano l'apertura, la chiusura della serra, le ventole e l'irrigazione di fatto non fanno niente. Ho sempre attiva l'uscita digitale sul pin 3 e basta.
Qualche anima pia mi spiega in parole semplici qual è il problema del codice?

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

int mot_av= 3; //il motore gira avanti e apre la serra
int mot_ind= 4; //il motore gira indietro e chiude la serra
int ventola= 5; // inizia a girare la ventola
int pompa= 6; //avvia la pompa

int LM35= A0;
int sensor;
float celsius;
float millivolts;

int stato = 0; // se stato=1 serra aperta, se stato=0 serra chiusa

int sensorU =A3;
int Hum;
int Valore;


LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {

pinMode(mot_av, OUTPUT);
pinMode(mot_ind, OUTPUT);
pinMode(ventola, OUTPUT);
pinMode(pompa, OUTPUT);
pinMode(LM35, INPUT);
pinMode(sensorU, INPUT);
}

void loop() {

sensor=analogRead(LM35);
millivolts=(sensor/1024.0)*5000;
celsius=millivolts/10;

Valore = analogRead(sensorU);
Hum = map(Valore, 1023, 220, 0, 100);

delay(1000);


  lcd.init();  //init dice che non esiste
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Temp");
  lcd.setCursor(5,0);
  lcd.print(celsius);
  lcd.setCursor(11,0);
  lcd.print("C");
  lcd.setCursor(0,1);
  lcd.print("Umid");
  lcd.setCursor(5,1);
  lcd.print(Hum);
  lcd.setCursor(11,1);
  lcd.print("%");
  Serial.print(Hum);

if ((celsius<21)&&(stato==1)){   //chiusura
  digitalWrite(mot_av, LOW);
  digitalWrite(mot_ind, HIGH);
  delay(2000);
  stato=0;   
  }
/*else {
  digitalWrite(mot_ind, LOW);
}*/
  
if ((celsius>21)&&(stato==0)){
  digitalWrite(mot_av, HIGH);
  digitalWrite(mot_ind, LOW);
  delay(10000);
   stato=1; 
}
/*else { 
  digitalWrite(mot_av, LOW);
}*/

if (celsius>28){
  digitalWrite(ventola, HIGH); }
else {
digitalWrite(ventola, LOW);
}
if (digitalRead(Hum<50)){
  digitalWrite(pompa, HIGH);
}
else {
  digitalWrite(pompa, LOW);}
}

Vi ringrazio in anticipo per l'aiuto

  1. chiarisci subito quanto tempo hai
  2. in casi simili prima cosa é l'uso del debug su seriale. Sai cone si fa?
  3. Seconda cosa é ridurre il progetto nelle sue componenti base e verificarle singolarmente, con scatch appropriati
void loop() {

sensor=analogRead(LM35);
millivolts=(sensor/1024.0)*5000;
celsius=millivolts/10;

Valore = analogRead(sensorU);
Hum = map(Valore, 1023, 220, 0, 100);

delay(1000);

le due letture dai 2 pin analogici fatte di seguito una all'altra danno (nel secondo) un valore errato, devi leggerlo 2 volte buttando via il primo risultato

void loop() {

sensor=analogRead(LM35);
millivolts=(sensor/1024.0)*5000;
celsius=millivolts/10;

//aggiungiamo anche un piccolo delay :-)
Valore = analogRead(sensorU);         //prima lettura da scartare
delay(20);
Valore = analogRead(sensorU);        // seconda lettura corretta

Hum = map(Valore, 1023, 220, 0, 100);

delay(1000);

questa comunque non vuol dire nulla

if (digitalRead(Hum<50)){

hum non è un pin digitale, è una variabile

if ((celsius>21)&&(stato==0)){
  digitalWrite(mot_av, HIGH);

qui dici se celsius > 21 e serra chiusa
apri serra
dopodichè non esiste un comando che interrompa il funzionamento del motore di apertura fino a quando la temperatura non cala sotto i 21 (nel qual caso il motore di chiusura rimane sempre attivo)

1 di tempo ne ho pochissimo, un paio di giorni
2 No, ma mi farebbe piacere scoprirlo
3 Stranamente le singole parti se montate da sole con sketch propri funzionano

Grazie Patrick, ho provato la doppia lettura anche se non l'ho ben capita, il problema si attenua sull'LM35 ma non è completamente risolto.

Grazie per Hum, mi era sfuggito.

Il motore si ferma dopo il delay, no?

il motore si ferma solo se gli dici di fermarsi, cioè: lo stato di un pin cambia solo quando tu lo fai cambiare
dicendo motore_avanti, HIGH
il pin resterà high fino a quando non incontrerà l'istruzione motore_avanti, LOW
il delay() causa solamente il freeze (blocco) del programma in quel punto per la durata dei millisecondi specificati nelle parentesi e null'altro
siccome può succedere che lo sketch cicli di continuo ti conviene aggiungere la doppia lettura anche nel primo analogRead

void loop() {
   sensor=analogRead(LM35);
   delay(10)
   sensor=analogRead(LM35);
   ...
   ...
   ...

Visto che cambia lo stato a 0 dopo il delay, ovvero non è più verificata la condizione di movimento del motore if (celsius<21 && stato==1) perchè dovrebbe continuare ad andare?
Al limite posso introdurre nuovamente l'else che ho commentato.

seguimi:

entro in una stanza se non c'è un fiocco rosso attaccato alla maniglia
accendo la luce
attacco un fiocco rosso alla maniglia
esco dalla stanza
................

anche se c'è il fiocco rosso alla maniglia
perchè dovrebbe spegnersi la luce?

tu fai la stessa cosa

if ((celsius<21)&&(stato==1)){   //chiusura
  digitalWrite(mot_av, LOW);
  digitalWrite(mot_ind, HIGH);
  delay(2000);
  stato=0;   
  }

chi e dove è scritto

digitalWrite(mot_ind, LOW)

in modo che quando il motore ha fatto il suo lavoro si spenga

io immagino che il codice giusto possa essere

if ((celsius<21)&&(stato==1)){   //chiusura
  digitalWrite(mot_av, LOW);
  digitalWrite(mot_ind, HIGH); // attivo la chiusura
  delay(2000);                 // attendo il tempo sufficiente alla chiusura (se non ci sono finecorsa)
  digitalWrite(mot_ind,LOW); // fermo il motore
  stato=0;                 // questo serve per sapere se la tenda è chiusa o aperta
  }                          // ora è chiusa

secondo me ti manca definire bene tutti gli stati possibili della tua serra.
Per te la serra può essere o troppo calda o troppo fredda, non esiste uno stato di temperatura ideale?
Credo che l'utilizzo di uno switch...case renderebbe più chiara questa cosa.
Per non far impazzire le aperture/chiusure dovresti valutare l'utilizzo dell'isteresi.

Grazie Patrick, faccio delle prove e ti faccio sapere.

Sì, calda e fredda, Gianluca, nessuno stato intermedio.