Progetto Serra Automatica

Ciao a tutti, ho realizzato lo schema di questo progetto per gestire una serra in modo autonomo e riscontro adesso problemi di disturbo o interferenze soprattutto nei relè.
Spiengandomi meglio se spengo tutto il progetto e lo riaccendo si crea un disturbo tale da azionare i relè quando questi non dovrebbero farlo, se guardate lo sketch della scheda Relè il primo relè si accende solo se riceve dalla Scheda Sensori un input =1 e dopo 2 min si accende il secondo relè per attivare la Scheda Motore.
Quello che succede invece che si attivano IN1 e IN2 della Scheda Relè insieme e di conseguenza fa attivare i relè della Scheda Motore.
Capita pure ma non sempre che il relè collegato alla Scheda Sensori che riguarda la ventola il led IN1 rimane acceso ma il relè non si apre,questo relè è l’unico che ho collegato con una alimentazione esterna.

Sarei lieto di accettare i vostri consigli per un miglioramento di questo progetto e anche per condividerlo con voi e ringraziare tutti coloro che hanno contribuito alla sua realizzazione

SCHEDA SENSORI

/* Questo progetto utilizza due Igrometri e un sensore DHT11 per gestire una Serra Automatica 
*/

int lettura = A0 ; // Pin analogico a cui è collegato il sensore 1
int lettura1 = A1 ; // sensore 2
int pompa = 9 ; //Pin a cui è collegato i rele' per attivare al pompa
int dht11 = 10 ; 
int hc12 = 11 ;
int sensorValue = 1008; // Valore del sensore 1 immerso in acqua
int sensorValue1 = 1010; // Valore del sensore 2 immerso in acqua

#include <HygrometerSensor.h>
#include <Adafruit_Sensor.h>

//DHT11 Sensor:
#include "DHT.h"
#define DHTPIN 12     // Sensore collegato al PIN 12
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);

//I2C LCD:
#include <Wire.h> // Libreria WIRE
#include <LiquidCrystal_I2C.h> // Libreria LCD I2C

// LCD I2C address
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); 


void setup()
{
  delay(1000);
  //I2C LCD
  Serial.begin(9600);
  lcd.begin(20,4);
  Serial.println("Serra Automatica");
 
   pinMode(pompa,OUTPUT); // Uscita relè pompa
   digitalWrite(pompa, LOW); // Stato relè spento

    // PIN 10 al relè - IN2
   pinMode(dht11, OUTPUT); // Uscita relè sensore DHT11
   digitalWrite(dht11, HIGH);

   pinMode(hc12,OUTPUT);
   digitalWrite(hc12, HIGH); // HC-12 Trasmittente

// Avvio sensore DHT11  
  dht.begin();
}

void loop(){
    
// Igrometro 1  
lettura = analogRead(A0);
sensorValue = map (lettura, 1008, 319, 0, 100); // converto il valore analogico in percentuale
Serial.print("Umidità terra 1 : ");
Serial.print(sensorValue);
Serial.println ("%"); //Stampa a schermo il valore  
    
// Igrometro 2    
lettura1 = analogRead(A1);
sensorValue1 = map (lettura1, 1010, 215, 0, 100); // converto il valore analogico in percentuale
Serial.print("Umidità terra 2 : ");
Serial.print(sensorValue1);
Serial.println ("%"); //Stampa a schermo il valore    
   
 if ((lettura >= 775)  && (lettura1 >= 775))
     {
    digitalWrite (pompa,HIGH); //... attiva la pompa 
    digitalWrite (hc12,LOW); // invio dati
        } else  {
  digitalWrite (pompa,LOW); //.... spegne la pompa
  digitalWrite (hc12,HIGH); // nessun dato
        } 
    delay(10000);
  
// Lettura umidità e temperatura del sensore DHT11n
int h = dht.readHumidity();
int t = dht.readTemperature();

// Misura la temperatura e se maggiore di ... gradi attiva relè per accendere la ventola
if (t >= 25 )
   digitalWrite (dht11, LOW); // Attiva Relè 2
else
   digitalWrite (dht11, HIGH); // Spegni Relè 2
delay (2000);

  Serial.print("Temp: ");
  Serial.print(t);
  Serial.print("C, Umid: ");
  Serial.print(h);
  Serial.println("%");


// impostare cursore sulla prima riga:
lcd.setCursor(0, 0);
lcd.print("Temperatura: ");
lcd.print(t);
lcd.print("C");
  
// imposta cursore sulla seconda riga:
lcd.setCursor(0,1);
lcd.print("Umidita' Aria: ");
lcd.print(h);
lcd.print("%");

// imposta il cursore sulla terza riga:
lcd.setCursor(0,2);
lcd.print("Umid..Terra 1: ");
lcd.print(sensorValue);
lcd.print("%");
    

lcd.setCursor(0,3);
lcd.print("Umid..Terra 2: ");
lcd.print(sensorValue1);
lcd.print("%");
 
}

SCHEDA RELÈ

#define RELAY1  9 // Elettrovalvola pompa               
#define RELAY2  10 // Motore irrigazione
#define pin_sensore A0

void setup() {

	pinMode(RELAY1, OUTPUT); // Elettrovalvola
		digitalWrite(RELAY1, HIGH);

  pinMode(RELAY2, OUTPUT); // Motore
		digitalWrite(RELAY2, HIGH);
		
  	pinMode(pin_sensore, INPUT);
	 
		
}
		
void loop() {
		
		if(digitalRead(pin_sensore) == 0 ){
			digitalWrite(RELAY1,HIGH);
			digitalWrite(RELAY2,HIGH);
				}
				else {
  digitalWrite(RELAY1,LOW); // Start l'elettrovalvola
   digitalWrite(RELAY2,HIGH); // Relè on/off spento
			delay(120000);
			digitalWrite(RELAY2,LOW);
   delay(500); //Attesa riempimento impianto                    
   digitalWrite(RELAY2,HIGH); // Avvio motore per irrigare
   delay(210000); // Attesa spegnimento elettrovalvola
   digitalWrite(RELAY1,HIGH); // Elettrovalvola spento
   delay(5000);
    }
}

SCHEDA MOTORE

#define in1 10
#define in2 11
#define fcS 13    //Finecorsa Sinistro ( posizione di reset iniziale )
#define fcD 12    //Finecorsa Destro
#define pin_sensore A0
byte stato_fc =  1 ;

void setup() {
  digitalWrite(in1, HIGH) ;
  digitalWrite(in2, HIGH) ;
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(fcS, INPUT_PULLUP);
  pinMode(fcD, INPUT_PULLUP);
  pinMode(pin_sensore, INPUT_PULLUP);
  while (digitalRead(fcS) == HIGH)  { // legge finecorsa sinistro
    digitalWrite(in2, LOW) ; // avvia motore indietro fino alla posizione iniziale
  }
  digitalWrite(in2, HIGH) ; // motore_stop
}

void loop() {
  if (digitalRead(pin_sensore) == 0 ) { // attende lo start
    delay(100);
    stato_fc = 1 ;
    digitalWrite(in1, LOW) ; // motore_avanti
    while (stato_fc != 0 ) {
      if (digitalRead(fcD) == 0 )   {
        digitalWrite(in1, HIGH); // motore_stop
        stato_fc = 0 ;
      }
    }
    delay(3000);
    stato_fc = 1 ;
    digitalWrite(in2, LOW) ; // motore_indietro
    while (stato_fc != 0 ) {
      if (digitalRead(fcS) == 0 )   {
        digitalWrite(in2, HIGH); // motore_stop
        stato_fc = 0 ;
      }
    }
    delay(100);
  }

}// fine loop

Arduino Nano con HC-12 per invio dati quando si aziona la pompa

#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); //RX, TX

const byte buttonPin = 9;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  mySerial.begin(9600);
}

void loop() {
 
  byte buttonState = digitalRead(buttonPin);
  
  if(buttonState == 0){ //se il pulsante è premuto
    mySerial.println("w1234");//invia un valore preceduto da w
  }
  delay(200);
  }

Ma fare un po' di ricerche sul forum no ? ? ?

Il problema dei disturbi dei relè è uno di quelli di cui si parla un thread si ed uno no ... basta fare un po' di ricerche e trovare un'infinità di suggerimenti ... li hai messi in pratica?

Come hai fatto i collegamenti? Come sono fatte le alimentazioni? Lo vogliamo mettere uno schema elettrico o dobbiamo "indovinare" come hai collegato il tutto?

Guglielmo

gpb01:
Come hai fatto i collegamenti? Come sono fatte le alimentazioni? Lo vogliamo mettere uno schema elettrico o dobbiamo “indovinare” come hai collegato il tutto?

Guglielmo

Ma scusa Guglielmo ho allegato in fondo alla descrizione lo schema di tutti i collegamenti, non basta,?

E cmq a parte le ricerche vi ho postato questo progetto per dare un consiglio se avevo fatto qualche errore

@cicciozuc un consiglio(se non te l’hanno già dato in passato) per i prossimi progetti. Impara ad usare millis() per temporizzare le varie funzioni. Il delay va usato col contagocce. Tutto questo progetto potevi gestirlo tranquillamente con una sola Mega e forse anche solo con una UNO

cicciozuc: Ma scusa Guglielmo ho allegato in fondo alla descrizione lo schema di tutti i collegamenti, non basta,?

"Mea culpa" ... non lo avevo visto ... ... ma ribadisco che TUTTE le alimentazioni dei moduli relè collegati alle UNO NON sono fatte come andrebbero fatte e come decine e decine di volte è stato spiegato su questo forum (... non mi è invece chiaro come è alimentato quello collegato alla MEGA), quindi ... fai le tue ricerche qui sul forum e ... scoprirai come vanno alimentati per cominciare ad eliminare buona parte dei problemi.

Concordo inoltre con "doppiozero" ... uno spreco di hardware incredibile ... ::)

Guglielmo

doppiozero: @cicciozuc un consiglio(se non te l'hanno già dato in passato) per i prossimi progetti. Impara ad usare millis() per temporizzare le varie funzioni. Il delay va usato col contagocce. Tutto questo progetto potevi gestirlo tranquillamente con una sola Mega e forse anche solo con una UNO

Ho imparato a programmare Arduino con i delay e quindi i mills per me sono sconosciuti, ho sempre cercato di assemblare questo progetto con un'unica scheda o con due massimo ma con scarsi risultati, se questo sarebbe possibile per me è ha nuova speranza.

gpb01: non mi è invece chiaro come è alimentato quello collegato alla MEGA[/i]), quindi ... fai le tue ricerche qui sul forum e ... scoprirai come vanno alimentati per cominciare ad eliminare buona parte dei problemi.

Concordo inoltre con "doppiozero" ... uno spreco di hardware incredibile ... ::)

Guglielmo

il relè collegato alla mega è fatto togliendo il jumper dalla scheda alimentando JD con VCC esterno e gnd con gnd esterno,infine il VCC accanto a IN2 con i 5v do Arduino...

cicciozuc:
Ho imparato a programmare Arduino con i delay e quindi i mills per me sono sconosciuti …

Si, ma NON puoi continuare in questo modo … la delay() si può usare dove non crea problemi, poi tocca mettersi li con calma e, come ti ho forse già detto in passato, studiarsi come si usa la funzione millis(), prima QUI, poi QUI e QUI e QUI e tutti gli articoli che sono in QUESTA pagina …

… altrimenti, per te, ogni progetto in cui occorre fare un paio di cose assieme, diventa un incubo … ::slight_smile:

Guglielmo

Per semplificare, ogni volta che usi DELAY significa che SPEGNI letteralmente Arduino che si siede fino alla fine del tempo che hai impostato. Non legge i sensori, non accende o spegne i relé, non cambia il display... Non fa niente! Ha senso? Nel frattempo non potrebbe fare altro? (ancora oggi non mi è chiaro perché DELAY esista...)

steve-cr: (ancora oggi non mi è chiaro perché DELAY esista...)

Esiste su tutte le piattaforme, anche le più complesse, e ci sono tranquillamente singoli casi in cui può fare comodo.

Ovviamente però, è nella logica di chi programma capire quando può essere usato senza creare problemi e quando invece va tassativamente evitato ... ::)

Guglielmo

Leggendo i post consigliati da Guglielmo riguardo la funzione mills() sto capendo che per me va oltre le mie aspettative, non voglio buttarmi proprio giù ma non posso dire è semplice, però non voglio arrendermi proprio ora per il semplice motivo che questo progetto non è un capriccio per passare il tempo ma al contrario mi serve per il mio lavoro, stando sempre fuori a lavorare qualcuno deve pur gestite questa serra...

Sto cercando di esercitarmi con lo sketch della scheda relè inserendo i mills al posto dei delay() ma già sò che sbatterò la testa al muro. Vedremo dove la mia ignoranza mi porterà

cicciozuc: Sto cercando di esercitarmi con lo sketch della scheda relè inserendo i mills al posto dei delay() ma già sò che sbatterò la testa al muro.

Con calma, un esempio alla volta, capendo bene come e perché vengono fatte le varie cose ;)

Guglielmo

Infatti già sono riuscito ad accendere un relè per 10 secondi e me per è gia molto...

const int RELAY1 = 9 ;

int RELAY1State = HIGH;

unsigned long previousMillisRELAY1 = 0;

const long intervalRELAY1 = 10000;

void setup() {
  pinMode(RELAY1, OUTPUT);
}

void loop() {
  
  unsigned long currentMillisRELAY1 = millis();

  if (currentMillisRELAY1 - previousMillisRELAY1 >= intervalRELAY1) {
   
    previousMillisRELAY1 = currentMillisRELAY1;

    if (RELAY1State == HIGH) {
      RELAY1State = HIGH;
    } else {
      RELAY1State = LOW;
    }

Se ti puo servire a qualcosa, considerala in questo modo ...

Con "delay" tu ti limiti a dire al micro "aspetta" per tot millisecondi, e quello lo fa da solo (bloccandosi, appunto, per tutti quei millisecondi)

Con "millis", non puoi, perche' millis si limita a restituirti un numero che rappresenta i millisecondi trascorsi dall'accensione del micro, per cui sta a te crearti una variabile unsigned long (qualsiasi nome, ad esempio, prevmil, tanto per dirme uno ... e ricordandoti che se dovrai gestire tempi diversi con ritardi diversi, ti servira' una di queste variabili per ogni ritardo, per cui potrebbero essere prevmil1, prevmil2, eccetera) ... in questa variabile dovrai mettere il valore di millis nel momento in cui inizia il tempo che devi misurare, e poi in un'if o in un'altro comando simile, dovrai confrontare il valore della tua prevmil con il valore del ritardo che ti serve in quel punto, eseguendo le operazioni solo dopo che tale tempo e' trascorso, per cui potrebbe servire una flag (variabile qualsiasi, anche solo byte) in cui mettere il valore che un'altra if controllera' per sapere se deve o meno eseguire tali operazioni ...

Giusto come idea, poi ci saranno altri sistemi di usarla ... solo per dire che non si puo semplicemente "sostituire" delay con millis, bisogna per forza ripensare l'intera logica dello sketch ... ;)

Ed in riferimento al tuo sketch (che ho visto solo dopo che avevo scritto quanto sopra :D), ricordati che puoi direttamente confrontare millis() con la tua unsigned long, senza dover per forza mettere il valore di millis in un'altra variabile ... giusto per risparmiare qualche riga di sketch e lo spazio di qualche variabile ;)

Più facile a dirsi che a farsi nel mio caso.
cmq da quanto ho imparato oggi la funzione mills() si attiva non appena si accende Arduino e questa dura a scheda sempre accesa 49,7 giorni poi va in overflow cioè supera i 32 bit , ma ho letto che cè un rimedio a questo problema…

Per quanto riguarda le if già sto avendo problemi nella lettura ma questo perchè ancora sbaglio a dare le istruzioni corrette, come suggerisci tu devo creare le variabili unsigned long e confrontarle dentro le if…

Cmq è molto difficile per me, beati voi che già avete queste conoscenze…
Spero con il tempo anche io possa imparare

cicciozuc: cmq da quanto ho imparato oggi la funzione mills() si attiva non appena si accende Arduino e questa dura a scheda sempre accesa 49,7 giorni poi va in overflow cioè supera i 32 bit , ma ho letto che cè un rimedio a questo problema...

In realtà DIMENTICA questa cosa ... ... come la stai usando già elimina questo problema che ... è tale, solo se la si usa male ;)

Quindi ... NON te ne preoccupare ...

Guglielmo

E quindi, sto cercando di inserire tutto quel Hardware sprecato in una Mega2560. Ho imparato ad accendere e spegnere un relè con i mills() ma caricare le istruzioni che usavo in 4 Arduino in una sola non è così semplice… Per quanto riguarda i mills() riflettendo mi servono solo per gestire l’elettrovalvola, per il motore ci sono i finecorsa, per la ventola basta un if/else per attivarla/disattivarla e per l’HC-12 per il momento ho deciso di non inserirla se prima non riesco a completare questo progetto…

Quello che sto facendo adesso è leggere i 2 Igrometri e attivare l’elettrovalvola (IN3) dopo che ha superato la soglia impostata, dopo 2 minuti deve fare partire le istruzioni per il motore avanti/indietro e dopo 4min si spegne IN3, il motore si ferma tramite finecorsa.

Lo sketch non mi dà errori e posso testarlo per il momento solo con un multimetro…

Sarei grato se date uno sguardo a questo sketch se ho +/- sbagliato qualcosa e ovviamente ancora devo finire di completarlo

const byte IN1 = 30; // MOTORE AVANTI
const byte IN2 = 32; // MOTORE INDIETRO
const byte IN3 = 34; // ELETTROVALVOLA
const byte IN4 = 36; // VENTOLA DHT11

unsigned long previousMillisIN1=0;
int intervalIN1 = 240000;
int IN3State = HIGH; // Elettrovalvola SPENTA
int IN1State = LOW;

#define fcS  11  // Finecorsa sinistro motore
#define fcD  12  // Finecorsa destro motore
byte stato_fc =  1 ;

const byte lettura = A0 ; // Pin analogico a cui è collegato il sensore 1
const byte lettura1 = A1 ; // sensore 2

const int sensorValue = 1008; // Valore del sensore 1 immerso in acqua
const int sensorValue1 = 1014;

#include <HygrometerSensor.h>
#include <Adafruit_Sensor.h>

//DHT11 Sensor:
#include "DHT.h"
#define DHTPIN 10     // Sensore collegato al PIN 12
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);

//I2C LCD:
#include <Wire.h> // Libreria WIRE
#include <LiquidCrystal_I2C.h> // Libreria LCD I2C

// LCD I2C address
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() {
  //I2C LCD
  Serial.begin(9600);
  lcd.begin(20,4);
  Serial.println("Serra Automatica");
  
  digitalWrite(IN1, HIGH) ;
  digitalWrite(IN2, HIGH) ;
  digitalWrite(IN3, HIGH) ;
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(fcS, INPUT_PULLUP);
  pinMode(fcD, INPUT_PULLUP);
  while (digitalRead(fcS) == HIGH)  { // legge finecorsa sinistro
    digitalWrite(IN2, LOW) ; // avvia motore indietro fino alla posizione iniziale
  }
  digitalWrite(IN2, HIGH) ; // motore_stop  

  // Avvio sensore DHT11  
  dht.begin();

}

void loop() {
  
  // Igrometro 1  
int lettura = analogRead(A0);
int sensorValue = map (lettura, 1008, 319, 0, 100); // converto il valore analogico in percentuale
Serial.print("Umidità terra 1 : ");
Serial.print(sensorValue);
Serial.println ("%"); //Stampa a schermo il valore  
    
// Igrometro 2    
int lettura1 = analogRead(A1);
int sensorValue1 = map (lettura1, 1010, 215, 0, 100); // converto il valore analogico in percentuale
Serial.print("Umidità terra 2 : ");
Serial.print(sensorValue1);
Serial.println ("%"); //Stampa a schermo il valore

if ((lettura >= 775)  && (lettura1 >= 775)) {
  
  if (IN3State == HIGH) { 
   IN3State = LOW; //... attiva Elettrovalvola
    
  unsigned long currentMillis = millis();
  if ((unsigned long)(currentMillis - previousMillisIN1) >= intervalIN1) {
  previousMillisIN1 = currentMillis;
    
    stato_fc = 1 ;
    digitalWrite(IN1, LOW) ; // motore_avanti
    while (stato_fc != 0 ) {
      if (digitalRead(fcD) == 0 )   {
        digitalWrite(IN1, HIGH); // motore_stop
        stato_fc = 0 ;
      }
    }
    delay(3000);
    stato_fc = 1 ;
    digitalWrite(IN2, LOW) ; // motore_indietro
    while (stato_fc != 0 ) {
      if (digitalRead(fcS) == 0 )   {
        digitalWrite(IN2, HIGH); // motore_stop
        stato_fc = 0 ;
      }
    }
    delay(100);
    
    } else {
      IN3State = HIGH;
  }
  
  }
 }
}

misurando con il multmetro sto capendo che ci sono molti errori da correggere, il led rx che legge i sensori non si accende e sulla seriale a parte quello che stampa nella Serial.println del setup non visualizza niente…pero se collego il pin 11 (finecorsa sinistro) con gnd simulando il finecorsa in contatto sulla seriale compaiono le letture scorrendo velocemente

usando questo sketch

const byte IN1 = 30; // MOTORE AVANTI
const byte IN2 = 32; // MOTORE INDIETRO
const byte IN3 = 34; // ELETTROVALVOLA
const byte IN4 = 36; // VENTOLA DHT11

unsigned long previousMillisIN3=0;
int intervalIN3 = 10000;
int IN3State = HIGH; // Elettrovalvola SPENTA


#define fcS  11  // Finecorsa sinistro motore
#define fcD  12  // Finecorsa destro motore
byte stato_fc =  1 ;

int lettura = A0 ; // Pin analogico a cui è collegato il sensore 1
int lettura1 = A1 ; // sensore 2

int sensorValue = 1008; // Valore del sensore 1 immerso in acqua
int sensorValue1 = 1014;

#include <HygrometerSensor.h>
#include <Adafruit_Sensor.h>

//DHT11 Sensor:
#include "DHT.h"
#define DHTPIN 10     // Sensore collegato al PIN 12
#define DHTTYPE DHT11   // DHT 11
DHT dht(DHTPIN, DHTTYPE);

//I2C LCD:
#include <Wire.h> // Libreria WIRE
#include <LiquidCrystal_I2C.h> // Libreria LCD I2C

// LCD I2C address
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

void setup() {
  //I2C LCD
  Serial.begin(9600);
  lcd.begin(20,4);
  Serial.println("Serra Automatica");
  
  digitalWrite(IN1, HIGH) ;
  digitalWrite(IN2, HIGH) ;
  digitalWrite(IN3, HIGH) ;
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(fcS, INPUT_PULLUP);
  pinMode(fcD, INPUT_PULLUP);
  while (digitalRead(fcS) == HIGH)  { // legge finecorsa sinistro
    digitalWrite(IN2, LOW) ; // avvia motore indietro fino alla posizione iniziale
  }
  digitalWrite(IN2, HIGH) ; // motore_stop  

  // Avvio sensore DHT11  
  dht.begin();

}

void loop() {

  
  
  // Igrometro 1  
lettura = analogRead(A0);
sensorValue = map (lettura, 1008, 319, 0, 100); // converto il valore analogico in percentuale
Serial.print("Umidità terra 1 : ");
Serial.print(sensorValue);
Serial.println ("%"); //Stampa a schermo il valore  
    
// Igrometro 2    
lettura1 = analogRead(A1);
sensorValue1 = map (lettura1, 1010, 215, 0, 100); // converto il valore analogico in percentuale
Serial.print("Umidità terra 2 : ");
Serial.print(sensorValue1);
Serial.println ("%"); //Stampa a schermo il valore

  if ((lettura >= 775)  && (lettura1 >= 775)) {
  
  if (IN3State == HIGH) { 
   IN3State = LOW; //... attiva Elettrovalvola
    
  unsigned long currentMillis = millis();
  if ((unsigned long)(currentMillis - previousMillisIN3) >= intervalIN3) {
  previousMillisIN3 = currentMillis;
  
    if (digitalRead(IN3State) == LOW ) {
    stato_fc = 1 ;
    digitalWrite(IN1, LOW) ; // motore_avanti
    while (stato_fc != 0 ) {
      if (digitalRead(fcD) == 0 )   {
        digitalWrite(IN1, HIGH); // motore_stop
        stato_fc = 0 ;
      }
    }
    
    stato_fc = 1 ;
    digitalWrite(IN2, LOW) ; // motore_indietro
    while (stato_fc != 0 ) {
      if (digitalRead(fcS) == 0 )   {
        digitalWrite(IN2, HIGH); // motore_stop
        stato_fc = 0 ;
      }
    }
    
  } else {
   IN3State = HIGH;
   digitalWrite(IN3, IN3State);
  }

  // Lettura umidità e temperatura del sensore DHT11n
int h = dht.readHumidity();
int t = dht.readTemperature();

// Misura la temperatura e se maggiore di ... gradi attiva relè per accendere la ventola
if (t >= 25 )
   digitalWrite (IN4, LOW); // Attiva Relè 2
else
   digitalWrite (IN4, HIGH); // Spegni Relè 2


  Serial.print("Temp: ");
  Serial.print(t);
  Serial.print("C, Umid: ");
  Serial.print(h);
  Serial.println("%");

 
     // impostare cursore sulla prima riga:
     lcd.setCursor(0, 0);
     lcd.print("Temperatura: ");
     lcd.print(t);
     lcd.print("C");
  
     // imposta cursore sulla seconda riga:
     lcd.setCursor(0,1);
     lcd.print("Umidita' Aria: ");
     lcd.print(h);
     lcd.print("%");

     // imposta il cursore sulla terza riga:
     lcd.setCursor(0,2);
     lcd.print("Umid..Terra 1: ");
     lcd.print(sensorValue);
     lcd.print("%");
    

     lcd.setCursor(0,3);
     lcd.print("Umid..Terra 2: ");
     lcd.print(sensorValue1);
     lcd.print("%");    
      }
    }
  }
}

Queste due righe:

unsigned long currentMillis = millis();
if ((unsigned long)(currentMillis - previousMillisIN1) >= intervalIN1) {

cambiale in:

if ((millis()- previousMillisIN1) >= intervalIN1) {

e questa

previousMillisIN1 = currentMillis;

la sostituisci con:

previousMillisIN1 = millis();

e la sposti come ultima istruzione di quel ciclo if cioè

if ((millis()- previousMillisIN1) >= intervalIN1) {
    ...
    ...
    ...
    previousMillisIN1 = millis();
}

così salva il tempo quando finisce di fare quello che c'è scritto nella if

  • OT on - perché cavolo aggiunge tutti questi spazi che io non ne ho messo neppure uno?
  • OT off -

Anche qui dovresti cambiare con millis...

    delay(3000);
    stato_fc = 1 ;

Patrick_M: Anche qui dovresti cambiare con millis...

    delay(3000);
    stato_fc = 1 ;

grazie Patrick_M... Riflettendo come mi hanno suggerito tempo fà la scheda motore è un processo con un funzionamento e una logica che dovrebbe stare a parte dalle altre schede, pensavo con la Mega metto tutti i sensori e il relè gestito dal dht11 e da li faccio uscire un pin per attivare come input la scheda motore come già facevo, bhè sarebbe il massimo avere tutto in una scheda senza avere problemi di interferenze ma secondo me forse è meglio tenerle separate anche se avranno massa in comune

Patrick_M: - OT on - perché cavolo aggiunge tutti questi spazi che io non ne ho messo neppure uno? - OT off -

gli spazi derivano dalle modifiche errate che tolgo e restano, e poi avere un codice con istruzioni una sotto l'altra mi sembra una gran confusione, di solito uso gli spazi tra fine e inizio di una nuova istruzione