[Risolto]Sensore pioggia con sensore IR ( KY-032)

Se vuoi qualcosa di seria, affidabile e duraturo e... costoso, tempo addietro @gpb01 suggeriva questi

grazie fabpolli, me lo vado a vedere appena posso,

@ Guglielmo, lo conosci direttamente perhchè lo hai usato? si interfaccia facilmente con arduino?

grazie

Scusa la schiettezza ma manco il tempo di una ricerca ti sei preso, cercando GR-11 Arduino il primo risultato chiarisce tutto e ha anche il codice d'esempio

wow fabpolli!!!! ho finito ora di lavorare e non ho fatto ancora nulla... sei stato molto gentile a segnalarmelo!!! :slight_smile:

grazie

Ciao a tutti, prima di spendere 100 euro tra prodotto e spedizione sto approfondendo quanto visto nel link sotto:

Lo sto provando con risultati sufficienti, quello che nn capisco è come mai quando faccio scorrere una goccia su una superficie trasparente inclinata o cmq il sensore rileva il passaggio veloce di un oggetto,anche il mio dito, il led "SLED" presente sul sensore stesso si accende(con intensità diverse in funzione di quanto veloce è il passaggio dell'oggetto/goccia, ma cmq lo stato del pin digitale non cambia... il led "SLED" se si accende segnala proprio un oggetto rilevato? Cosi sto leggendo su vari tutorial... il sensore so trova a 5 metri da arduino, serve qualche accorgimento nei collegamenti?

Pensavo che forse un loop troppo lungo potrebbe farmi perdere quella lettura... che sia necessario usare pin interrupts?

Grazie per i consigli

simosere:
prima di spendere 100 euro tra prodotto e spedizione

Eh, ok, ma se vuoi una cosa ben fatta ed affidabile, in genere non costa poco. :wink:

Sai, nel mio lavoro (sono un informatico) a molti clienti sembra sfuggire il criterio secondo il quale ci sono tre opzioni: una cosa può costare poco, essere ben fatta, e realizzata in poco tempo. Se ne possono scegliere solo due. :wink:

cmq lo stato del pin digitale non cambia...

Ma intanto, confermi che tu NON hai toccato il trimmer R6, vero?
Se non sai perché te lo chiedo, informati sempre sui moduli che devi usare, ad esempio un ottimo tutorial con tutte le spiegazioni che ti occorrono lo trovi QUI.

il led "SLED" se si accende segnala proprio un oggetto rilevato?

Sled = Sense LED quindi si...

il sensore so trova a 5 metri da arduino, serve qualche accorgimento nei collegamenti?

Eh, direi che 5 metri sono tantini generalmente, ma comunque dipende anche da come lo hai connesso e dal tipo di cavi che hai usato. Dato che il progettino al quale ti riferisci nonprevedeva l'uso di Arduino e non hai spiegato a cosa ti serve il sensore, ci fai uno schemino del tuo progetto soprattutto delle connessioni (anche su carta, poi fotografalo ed alleghi qui l'immagine)?

Pensavo che forse un loop troppo lungo potrebbe farmi perdere quella lettura...

Beh non avendo ancora la sfera di cristallo (la sto aspettando da AliExpress) magari ci fai vedere il codice che stai usando?

Ma intanto, confermi che tu NON hai toccato il trimmer R6, vero?
Se non sai perché te lo chiedo, informati sempre sui moduli che devi usare, ad esempio un ottimo tutorial con tutte le spiegazioni che ti occorrono lo trovi QUI.

no assolutamente, si mi sono informato un pò prima di smanettarci :slight_smile:

Eh, direi che 5 metri sono tantini generalmente, ma comunque dipende anche da come lo hai connesso e dal tipo di cavi che hai usato. Dato che il progettino al quale ti riferisci nonprevedeva l’uso di Arduino e non hai spiegato a cosa ti serve il sensore

allora il cavo è un cavo bipolare schermato, con la schermatura collegata a massa di arduino e uno dei due cavetti mi porta i 5V e l’altro il segnale digitale al pin 14 dell’arduino Mega.
Il collegamento è stato fatto direttamente in questo modo:

5v Sensore -----> 5v Arduino Mega
gnd Sensore ----> gnd arduino Mega (utilizzando come detto la schermatura)
out sensore ----->> pin 14 arduino Mega

l’idea sarebbe quella di adattare il sensore in oggetto come sensore di rilevamento pioggia. cosa che dalle prove che ho fatto sembra dare esito positivo nel rilevamento della goccia(il led sled si accende ad ogni passaggio della goccia ad intensità di luminosità diversa in funzione della velocità della goccia), ma andando a vedere il seriale dove stampo lo stato del pin 14, mi rimane sempre HIGH e non rileva il passaggio a LOW.

Dato che il progettino al quale ti riferisci non prevedeva l’uso di Arduino e non hai spiegato a cosa ti serve il sensore, ci fai uno schemino del tuo progetto soprattutto delle connessioni (anche su carta, poi fotografalo ed alleghi qui l’immagine)?

[/quote]

intendi di tutto il progetto o solo della parte di questo sensore?

Beh non avendo ancora la sfera di cristallo (la sto aspettando da AliExpress) magari ci fai vedere il codice che stai usando?

hai ragione… ahahahah in allegato il file

prova KY-032 .txt (70.2 KB)

simosere:
il cavo è un cavo bipolare schermato, con la schermatura collegata a massa di arduino e uno dei due cavetti mi porta i 5V e l'altro il segnale digitale al pin 14 dell'arduino Mega.

Hm, 5 metri non sono pochi, però teoricamente potrebbe forse andare.

Ma prima di iniziare a pensare ad altro, perché non fai una prova collegando direttamente il sensore ad Arduino, senza quel cavo e vedere così se è il modulo ad essere difettoso oppure se funziona correttamente?

Nel primo caso visto che il led Sled si accende magari è solo una saldatura fallata, mentre nel secondo caso devi allora concentrarti sul cablaggio (ad es. hai verificato con un tester che il cavo che porta il segnale sia integro?) e magari se, invece di un pin digitale, lo metti su un pin analogico, e fai un piccolo e semplice sketch che ti riporta sulla seriale (diciamo ogni 200ms) il valore della analogRead() quali valori leggi? E vedi qualcosa che cambia quando passi una mano davanti al sensore?
Solamente in base all'esito di questi test si potrà andare ad investigare sulla possibile soluzione.

prima di montarlo sul campo diciamo, ho fatto delle prove da banco e non ho riscontrato la stessa cosa. Ad ogni passaggio della goccia, risultava sia l'accensione del led(a diverse intensità in funzione della velocità della goccia) e l'aumento della variabile che avevo impostato da aumentare. Quindi il sensore funzionava con arduino nano e a pochi cm di distanza.

il cavo a cui è connesso ora in digitale lavorava fino al cambio del sensore in analogico con un'altro sensore che non mi ha dato nessun problema, nel senso che funzionava a dovere.(ho solo smontato il sensore vecchio e messo il KY-032, non è cambiato altro.

passando la mano davanti al sensore nella "configurazione da campo" rileva correttamente la mano.

Una cosa che credo sia certa(ma chiariscimelo per cortesia), se il led SLED si accende,anche leggermente e per pochissimo, significa che il sensore deve cambiare stato passando da HIGH a LOW? oppure ci deve stare un pò con il led SLED acceso per far "percepire" il cambio di stato?

e magari se, invece di un pin digitale, lo metti su un pin analogico, e fai un piccolo e semplice sketch che ti riporta sulla seriale (diciamo ogni 200ms) il valore della analogRead() quali valori leggi? E vedi qualcosa che cambia quando passi una mano davanti al sensore?
Solamente in base all'esito di questi test si potrà andare ad investigare sulla possibile soluzione.

vedo di fare nel frattempo queste verifiche che mi consigli

Beh intanto devi capire bene come funziona quel sensore. Se vedi la pagina che ti avevo linkato (ma l'hai letta?), il circuito trasmittente è questo:

Di fatto emette un segnale modulato con una frequenza che è calibrata tramite il trimmer per andare a 38kHz esatti. Questo si fa ad esempio anche nei telecomandi e serve per evitare che segnali spuri e disturbi siano scambiati per un segnale, grazie al circuito ricevente:

Quel sensore HS0038B3VM, come in parte anche la sigla lascia intendere, è un sensore di segnali infrarossi filtrato per rilevare solo quelli a 38kHz (lo schema interno lo trovi sempre in quella pagina) per cui OUT sarà HIGH quando non è presente nessun ostacolo (puoi notare nello schema interno che ha una resistenza di pull-up) o LOW quando viene rilevato un ostacolo (grazie al transistor che vedi sempre nello schema interno che porta a GND).

se il led SLED si accende,anche leggermente e per pochissimo, significa che il sensore deve cambiare stato passando da HIGH a LOW? oppure ci deve stare un pò con il led SLED acceso per far "percepire" il cambio di stato?

non ho quel sensore, ma direi che se l'accensione è molto breve ovviamente il tuo sketch deve essere in grado di leggere lo stato del pin quando è passato a LOW. Se dici che hai dei tempi del loop() molto lunghi, è possibile che non riesca a "vedere" in tempo il passaggio della goccia, in tal caso potrebbe essere utile o "snellire" il loop oppure provare ad usare gli interrupt (quindi sul FALLING chiami una funzione che semplicemente ti imposta una variabile volatile bool a true e tu verifichi quella nel codice).

Hai detto che con prova "da banco" funzionava, ma non ho capito se le hai fatte anche con QUESTO sensore o solo con l'altro ma in tal caso ti consiglierei di provarlo comunque portandolo vicino ad Arduino e capire quindi se il problema sia il cavo o il modulo.

Quindi vedi bene il discorso cablaggio e soprattutto cosa rilevi se provi a collegarlo ad un pin analogico (non è che hai magari un oscilloscopio, no vero? ;)) e quindi mettendo o togliendo la mano davanti al sensore.

ok docdoc, siete troppo tecnici non ci capisco una mazza con i circuiti... si certo link che mi hai girato lho letto sia prima che dopo il tuo aiuto.

Hai detto che con prova "da banco" funzionava, ma non ho capito se le hai fatte anche con QUESTO sensore o solo con l'altro ma in tal caso ti consiglierei di provarlo comunque portandolo vicino ad Arduino e capire quindi se il problema sia il cavo o il modulo.

si parlo di QUESTO sensore. cmq ho capito faccio un pò di prove.

non non ho l'oscilloscopio...

in tanto grazie, vi faccio sapere

se ho capito bene:

quindi sul FALLING chiami una funzione che semplicemente ti imposta una variabile volatile bool a true e tu verifichi quella nel codice).

int pin = 2;
volatile int state = HIGH;
volatile bool cambio_stato = false;

void setup(){
pinMode(2, INPUT); // sensore KY-032
attachInterrupt(digitalPinToInterrupt(2), prova, FALLING);
}

void loop(){
pioggia();
}

void prova(){
cambio_stato = true;
}


void pioggia() {

digitalWrite(pin, state);

 if (cambio_stato == true && pioggia1 == false) {
   startingTimePioggia1 = millis();
   pioggia1 = true;
 }
 if (((millis() - startingTimePioggia1) < TIMEOUTpioggia) && pioggia1 == true)  {
   if (cambio_stato == true) {
     valorestatopioggia++;
     if (valorestatopioggia > 0) {
       attiva_ricordavalorestatopioggia = true;
       ricordavalorestatopioggia++;
     }
   }
 }

 if (((millis() - startingTimePioggia1) >= TIMEOUTpioggia) && (valorestatopioggia >= 3) && pioggia1 == true)  {
   startingTimePioggia1 = millis();
   valorestatopioggia = 0;
 }
 if (((millis() - startingTimePioggia1) >= TIMEOUTpioggia) && (valorestatopioggia < 3) && pioggia1 == true)  {
   valorestatopioggia = 0;
   pioggia1 = false;
 }
cambio_stato = false;
}

Si, più o meno in quel senso (ma lo hai provato?.. :wink: )

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” :wink: 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) {

  • if (cambio_stato) {*

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.

grazie mille!!!

no no lho provato, sono a lavoro e in pausa pranzo lho scritto cosi al volo... con vari tutorial sotto mano... su word

per il resto che dirti sei stato non gentile ma di più oltre che disponibile!!!

grazie mille ancora e appena mi dedico al tutto vi faccio sapere

ancora grazie :slight_smile:

Doc doc funge!!! Con l'interrupt risolto! Una precisione incredibile.

Grazie dei consigli ancora

Ho modificato il titolo magari a qualcuno può far comodo! :slight_smile:

Una cosa che mi è venuto in mente ora, non serve nessuna resistenza pull up prima di collegarlo al pin digitale? Da come dicevamo è già presente sul circuito giusto?

Grazie

Edit:per evitare disturbi eventuali, quando il vecchio sensore era collegato in analogico,essendo arduino vicino alla caldaia, avevo ogni tanto,quando partiva, falsi positivi, all'epoca con una resistenza da 10k di pull down tra a0 e gnd risolsi. Qui devo fare la stessa cosa? Solo dhe di pull up? Sempre 10 k?

simosere:
Una cosa che mi è venuto in mente ora, non serve nessuna resistenza pull up prima di collegarlo al pin digitale? Da come dicevamo è già presente sul circuito giusto?

Si, questa da 30k, mentre il transistor, quando attivo, come vedi "trascina" l'out a GND:


Le resistenze in questi casi puoi immaginarle un po' come delle "molle di ritorno": senza alcun peso tengono "in alto" il gancio, quando sul gancio metti un peso, lasciano scendere il gancio a terra.

Edit:per evitare disturbi eventuali, quando il vecchio sensore era collegato in analogico,essendo arduino vicino alla caldaia, avevo ogni tanto,quando partiva, falsi positivi, all'epoca con una resistenza da 10k di pull down tra a0 e gnd risolsi. Qui devo fare la stessa cosa? Solo dhe di pull up? Sempre 10 k?

Non so quale caratteristiche avesse quello vecchio, ma attualmente qui non serve. Al massimo metti una ferrite (puoi recuperarla da qualche vecchio cavo USB ad esempio) o un condensatorino, ma per ora vedi come va così.

grazie doc!!! testo la situazione ed in caso intervengo!

ancora grazie

ho constatato che anche se di rado, quando si avvia la caldaia si presenta una falsa lettura. diciamo che su 10 avvii un solo falso positivo.

ho provato:

  • messa ferrite su cavo che porta segnale/5V e gnd da sensore ad arduino. la ferrite si trova in prossimità di arduino
  • avendocela pronta ho posizionato per prova anche una resistenza pull-up da 10k

ho provato prima la sola ferrite con esito non positivo, ho aggiunto anche la resistenza di pull-up da 10k in sieme alla ferrite e l'esito non è cambiato.

il condensatore come lo devo posizionare? da quanto? mi fai un piccolo schemino?

disponibili ho:

  • plastico da 100nf
  • ceramico da 10nf e 100nf
  • elettrolitico da 470uF

grazie

Il valore preciso si potrebbe identificare magari guardando il tipo di disturbo con un oscilloscopio, comunque al tuo posto proverei col 100nF tra segnale e massa.

Poi se non dovesse ancora andare, credo che l'elettrolitico sia eccessivo ma magari lascio la parola a chi è più esperto di me di disturbi di questo tipo.