Si, più o meno in quel senso (ma lo hai provato?...
)
Però intanto il solito consiglio: cerca di imparare ad indentare bene, perché se per programmi corti non è significativo, quando inizierai a fare cose più complesse diventa più facile per te capire come funziona il tuo programma e poterne fare quindi un debug più rapido, e per noi per leggere il tuo listato senza farci "incrociare gli occhi"
Nell'IDE premi Ctrl-T e te lo indenta automaticamente lui, poi però cerca di mantenere quello stesso stile. Inoltre non mettere tutte ste inutili righe vuote, lascia sempre solo UNA riga vuota almeno tra una funzione e l'altra, oppure prima di blocchi di particolare interesse o che riguardano uno stesso aspetto. Inoltre metti un po' più di commenti: non sono un "accessorio" ma servono in primo luogo a te per impostare correttamente la logica del programma (visto che in linguaggio naturale "ci si capisce di più") ma anche a noi per capire cosa intendi con le varie istruzioni.
Secondo, ti dò per ora solo qualche consiglio generale (ma comunque con lo stesso spirito di quello che dicevo per l'indentazione) partendo da alcune tue istruzioni.
Partiamo da:
int pin = 2;
I numeri dei pin sono degli interi che valgono sicuramente non più di 100, quindi per ottimizzare il tuo codice usa i byte non gli int:
byte pin = 2;
Poi essendo dei valori costanti (non cambi mica configurazione dei pin via software!) puoi definirli come const:
const byte pin = 2;
oppure, meglio, direttamente come simboli tramite la #define (che per convenzione si indicano in maiuscolo per distinguerli dalle variabili):
#define PIN 2
Poi:
volatile int state = HIGH;
Questa variabile non la modifichi all'interno di un ISR (la funzione chiamata tramite interrupt) quindi puoi evitare di dichiararla "volatile". Inoltre contenendo solo HIGH o LOW puoi anche definirla byte o addirittura "bool" che farai valore "true" se HIGH o "false" se LOW (o viciversa, puoi decidere quello che ti fa più comodo):
bool state = false;
pinMode(2, INPUT); // sensore KY-032
attachInterrupt(digitalPinToInterrupt(2), prova, FALLING);
Se hai definito la costante/simbolo "PIN" perché qui usi il numero del pin? Usa il simbolo, no?
pinMode(PIN, INPUT); // sensore KY-032
attachInterrupt(digitalPinToInterrupt(PIN), prova, FALLING);
digitalWrite(pin, state);
Se è in INPUT perché cerchi di impostare lo stato? Quel pin lo devi leggere quindi questa va cancellata.
Per la funzione pioggia() ti suggerisco solo un paio di cose:
if (cambio_stato == true && pioggia1 == false) {
startingTimePioggia1 = millis();
pioggia1 = true;
}
intanto puoi anche semplificare le if in generale quando hai dei valori booleani:
if (cambio_stato && !pioggia1) {
che, dato che "&&" è un "e" e "!" è un "non", leggerai come "se cambio stato e non è pioggia". Più leggibile e naturale no?
if (((millis() - startingTimePioggia1) < TIMEOUTpioggia) && pioggia1 == true) {
if (cambio_stato == true) {
In realtà se metti quelle parentesi per evidenziare meglio i gruppi logici, mettici anche qualche spazio in più per evitare "catene" di parentesi, ad esempio:
if ( ( (millis() - startingTimePioggia1) < TIMEOUTpioggia ) && pioggia1 == true ) {
ma in genere se non sono troppe o non necessiti di una valutazione specifica puoi anche evitarle quasi tutte, ad esempio:
if ( millis() - startingTimePioggia1 < TIMEOUTpioggia && pioggia1) {
Ma più un generale, in pioggia() vedo che hai tre if() nelle quali vai sempre a testare il timeout:
if (((millis() - startingTimePioggia1) < TIMEOUTpioggia) && pioggia1 == true) {
...
}
if (((millis() - startingTimePioggia1) >= TIMEOUTpioggia) && (valorestatopioggia >= 3) && pioggia1 == true) {
...
}
if (((millis() - startingTimePioggia1) >= TIMEOUTpioggia) && (valorestatopioggia < 3) && pioggia1 == true) {
...
}
non ha grosso senso fare tre volte lo stesso test, basta indentare le condizioni:
[
if ( millis() - startingTimePioggia1) < TIMEOUTpioggia) ) {
// Non sono in timeout, verifico la presenza di pioggia
if ( pioggia1) {
...
}
} else { // Significa che siamo oltre il tempo massimo previsto
// Verifico se c'è pioggia
if ( pioggia1 ) {
if (valorestatopioggia >= 3) {
...
} else { // valorestatopioggia minore di 3
...
}
}
}
Per il resto della funzione pioggia() non entro nel merito, devi fare tu un po' di prove ed eventualmente del debug per verificare se funziona come immagini che debba funzionare, e per farlo usa la seriale (ricorda di fare Serial.begin() nel setup) ossia scrivi ogni tanto qualche Serial.println() per tracciare dove passa il programma o quale valore hanno certe variabili che ti interessano.