Anemometro e protezione antivento per tende da sole

Ciao, posto in Generale per proporre un progetto "completo" all'attenzione degli Admin: se ho capito male la procedura mi scuso in anticipo e attendo suggerimenti su come ravvedermi :slight_smile:

Ho montato delle tende da sole motorizzate (con telecomando) e, visto quanto costano, volevo proteggerle con un sensore antivento. Siccome 200€ e passa mi sembravano un prezzo un po’ esoso per l’accessorio originale, avendo un Arduino Starter Kit che languiva nel cassetto da un po’ (senza che fossi mai andato oltre i LED lampeggianti), mi sono detto “quanto potrà essere difficile?” e mi sono lanciato: primo progetto, ma funziona!
I requisiti che mi ero dato:

  • misurare la velocitĂ  del vento tramite un anemometro
  • calcolare velocitĂ  media e massima del vento su una finestra temporale impostabile
  • visualizzare velocitĂ  istantanea, media e massima su un display LCD
  • selezionare l’unitĂ  di misura con cui le velocitĂ  sono visualizzate tramite pressioni “brevi” di un pulsante, ciclando tra m/s, km/h, mph (miglia US all’ora) e nodi (miglia marine all’ora)
  • regolare la luminositĂ  dell’LCD tramite pressioni “lunghe” dello stesso pulsante usato per selezionare l’unitĂ  di misura: tenendo premuto il pulsante per piĂą di 2 secondi, la luminositĂ  aumenta progressivamente fino al massimo, poi diminuisce fino a zero e così via finchĂ© non si rilascia il pulsante
  • se la velocitĂ  media o massima del vento superano soglie di sicurezza impostabili (tramite costanti di configurazione), accendere una spia di allarme ed emettere il comando di “riavvolgimento tende” tramite il telecomando.

Non essendoci un sensore per rilevare lo stato della tenda (abbassata, alzata o in transito), questo prototipo continua a emettere il comando di “riavvolgimento tende” a intervalli regolari finché non termina la condizione di allarme (cioè finché non cala il vento).
L’elenco dei materiali è:

  • 1 controller Arduino UNO (o equivalente) con breadboard, jumper vari e un alimentatore 12 V
  • un anemometro “a palette” (il meno caro che ho trovato su Internet, circa 20€: plasticoso ma funziona): sul rotore è montato un piccolo magnete che, girando, chiude un contatto ogni volta che passa sopra un sensore (Reed switch)
  • 2 resistenze da 10 kohm + 3 resistenze da 220 ohm
  • 1 LCD 16x2 compatibile Hitachi HD44780 (ho usato quello dello starter kit)
  • 1 transistor (ho usato il MOSFET N-channel IRF520 incluso nello starter kit) per pilotare la retroilluminazione dell’LCD
  • 1 pulsante (momentary switch) per la selezione dell’unitĂ  di misura e la regolazione della luminositĂ  del display
  • 1 LED 5V per la segnalazione dello stato di allarme
  • 1 optoisolatore (ho usato il 4N35 a 6 pin incluso nello starter kit) per collegare il telecomando
  • il telecomando delle tende, da “hackerare” saldando due fili ai contatti del pulsante che comanda il riavvolgimento delle tende (i due fili saranno poi collegati alle uscite dell’optoisolatore). DISCLAIMER OBBLIGATORIO: come per tutte le modifiche “fai da te” ad apparecchi elettronici, oltre ad invalidare qualsiasi tipo di garanzia, c’è sempre il rischio di fare qualche danno. In questo caso, i rischi sono limitati perchĂ© 1) il telecomando funziona a bassissima tensione e 2) i potenziali danni sono limitati al telecomando, che alle brutte si può sostituire con relativamente poca spesa. Comunque, togliete le batterie prima di saldare i fili.

Non avendo nessuna esperienza pratica nella progettazione elettronica, per il circuito mi sono affidato completamente agli esempi del libro incluso nello starter kit e a qualche “copia & incolla” da Internet. In pratica, le “linee guida” che ho seguito sono:

  • ad ogni input digitale (pulsante, sensore dell’anemometro) ho messo in parallelo una resistenza di “pull-down” da 10 kohm collegata a massa in modo che, con interruttore aperto, il segnale sul pin di input sia “basso” (0 V)
  • ad ogni LED (allarme, retroilluminazione dell’LCD, optoisolatore) ho messo in serie una resistenza da 220 ohm come limitatore di corrente
  • sia il LED di allarme, sia quello integrato nell’optoisolatore saranno accesi al massimo per qualche decina di secondi in tutta la vita dell’apparecchio, per cui dovrebbe essere accettabile collegarli direttamente agli output digitali del controller. Invece, l’LCD è sempre attivo e la sua retro-illuminazione è relativamente potente, per cui non mi sembrava prudente alimentare il LED dell’LCD direttamente da un output PWM. Quindi ho interposto un transistor, anche se il MOSFET di potenza incluso nel kit – destinato a controllare motori elettrici e carichi simili - è probabilmente “esagerato”: gate (pin sinistro) collegato a un output digitale PWM del controller, source (pin destro) collegato a massa (tramite una resistenza da 220 ohm) e drain (pin centrale) collegato al catodo della retro-illuminazione dell’LCD (l’anodo è collegato direttamente a +5 V).
  • il pin digitale a cui si assegna l’output PWM per controllare l’intensitĂ  della retro-illuminazione dell’LCD deve – ovviamente – essere uno di quelli abilitati alla modulazione in larghezza degli impulsi (per Arduino Uno: i pin digitali 3, 5, 6, 9, 10 e 11)
  • il pin a cui si collega l’input dal sensore dell’anemometro deve essere abilitato alla gestione degli interrupt (per Arduino Uno: solo i pin digitali 2 e 3)

In allegato:

  • schema di cablaggio per il breadboard
  • schema elettrico
  • sketch
  • foto del risultato dopo aver infilato il tutto (meno il breadboard!) in una vecchia scatola di derivazione che ho tagliato con il traforo.

Ho commentato “pesantemente” il codice (in inglese, deformazione professionale) per cui dovrebbe risultare auto-esplicativo. Ci sono alcuni aspetti del codice degni di nota (almeno per me, neofita assoluto di Arduino), ma ne parlerò in un post separato perché altrimenti diventa troppo lungo...
Le prossime evoluzioni saranno:

  • aggiunta di una fotoresistenza per riavvolgere automaticamente le tende al tramonto (facile, penso, salvo calibrazione); alcuni anemometri ce l’hanno giĂ  integrata (il mio, ad esempio, è visibilmente predisposto ma è il modello “economico” e la fotoresistenza non c’è)
  • aggiunta di un sensore pioggia per evitare che si inzuppino (meno facile: ho visto che ci sono molti tutorial basati su sensori resistivi, ma non sono convinto che funzionino bene con l’acqua piovana – povera di sali e con bassa conduttivitĂ  – e durino a lungo; i rilevatori di pioggia piĂą seri sono per lo piĂą basati su sensori ottici – tipo quelli dei tergicristalli delle automobili - ma quelli in commercio costano parecchio e soprattutto integrano tutta la logica necessaria a bordo, il che rovina il divertimento! Sono alla ricerca di una soluzione creativa e ogni suggerimento è ben accetto)
  • integrazione del telecomando via radio, eliminando la necessitĂ  di “hackerare” il telecomando originale (difficile, immagino, soprattutto a seconda di quanto è “proprietaria” la codifica dei comandi: non ho ancora incominciato a documentarmi, anche qui ogni suggerimento è benvenuto).

Sarò molto grato per tutti i commenti che mi aiutino a identificare e correggere le “ingenuità” progettuali che sicuramente ho commesso, e soprattutto gli eventuali “orrori” in cui sono incappato inconsapevolmente. Grazie e buon divertimento.

myWind_v5.ino (16.7 KB)

Va benissimo messo qui e ... complimenti per il lavoro ! :slight_smile:

Guglielmo

A completamento della descrizione del progetto, posto qui alcune considerazioni sul codice (lo sketch è allegato al post originale). Probabilmente sono un po' scontate ma, da completo neofita della programmazione embedded (faccio software per banche e assicurazioni!), sono punti che non mi erano evidenti e che forse potranno essere utili a qualche altro principiante:

  • nel codice ho aggiunto gli #include e le dichiarazioni di funzione necessari per farlo diventare codice C++ formalmente corretto, quindi si può compilare (e, soprattutto, debuggare, versionare su GitHub, etc.) con un “vero” IDE (ad es. PlatformIO). Comunque, funziona perfettamente anche con l’IDE Arduino.
  • i calcoli per la temporizzazione (cioè tutte le volte che il codice calcola “quanti millisecondi sono passati dall’ultima volta che…?”, ad es. riga 201) non richiedono alcuna gestione esplicita degli overflow del timer di sistema, cioè quando il contatore interno dei millisecondi a partire dall’ultima accensione - o reset - arriva alla sua capienza massima di intero unsigned a 32 bit (cioè 232-1) e viene resettato a zero (timer wrap: accade circa ogni 50 giorni di funzionamento continuo). La rappresentazione binaria in complemento a 2 assicura automaticamente che il risultato di una operazione aritmetica su variabili intere unsigned sia corretto anche in caso di overflow di una o piĂą variabili. Quindi il “trucco” consiste semplicemente nel dichiarare tutte le variabili destinate alla temporizzazione come unsigned long. Una curiositĂ : se in una espressione compaiono variabili di tipo diverso, il compilatore converte implicitamente tutti i valori al tipo con il dominio minore (piĂą limitato); per cui se in una espressione compaiono sia int, sia unsigned long il compilatore converte tutto in unsigned long e – a patto che gli interi siano positivi - il “trucco” dei millisecondi funziona correttamente.
  • l’aggiornamento della variabile lastWindMillis (riga 251) è un po’ particolare: tipicamente tutte le variabili di temporizzazione lastXxxMillis, che servono per calcolare il numero di millisecondi trascorsi dall’ultimo evento Xxx, vengono aggiornate con il valore corrente del timer di sistema (ad es. lastXxxMillis = currentMillis) in modo che, anche in caso di ritardo (cioè se un intervallo è “andato lungo”, ad esempio perchĂ© in qualche altra parte del codice c’è un delay), il prossimo intervallo abbia la durata corretta. Nel caso della misurazione della velocitĂ , invece, vogliamo che la durata media degli intervalli di tempo sia tendenzialmente corretta. Per ottenere questo effetto, lastWindMillis viene incrementata della durata nominale dell’intervallo (riga 251) in modo che indichi l’istante nel quale l’ultima misurazione sarebbe dovuta avvenire (e non quando effettivamente è avvenuta); in caso di ritardo, il prossimo intervallo sarĂ  automaticamente piĂą corto (compensazione del “drift”) e la durata media degli intervalli tenderĂ  al valore nominale.
  • le variabili che vengono scritte da un interrupt handler devono essere definite con il qualificatore volatile (riga 122), altrimenti l’ottimizzatore del compilatore (esecuzione fuori ordine, eliminazione delle assegnazioni multiple senza corrispondenti letture nel flusso di esecuzione, etc.) fa danni. Inoltre, prima di leggere e/o sovrascrivere queste variabili al di fuori dell’interrupt handler è necessario disabilitare gli interrupt (riga 204) e poi riabilitarli subito dopo (riga 207).
  • tutti gli input digitali (pulsante, sensore dell’anemometro) hanno bisogno di una logica di debouncing (soppressione dei rimbalzi: dopo un input valido, qualsiasi ulteriore input va ignorato per un certo numero di millisecondi, ad es. riga 201), altrimenti l’inevitabile “rumore” elettrico che segue ogni transizione di stato viene interpretato come sequenze casuali di on-off molto veloci (i “rimbalzi”, appunto) che, nel caso della misurazione della velocitĂ  di rotazione dell’anemometro, provocano errori inaccettabili. Da notare che, impostando l’intervallo di debouncing per il sensore del vento (con la costante WIND_PULSE_INTERVAL, riga 86), si limita implicitamente anche il numero massimo di giri al secondo rilevabili e, quindi, la velocitĂ  massima del vento misurabile dall’anemometro. Per questa applicazione, però, è un limite accettabile: ci interessa poco misurare velocitĂ  molto maggiori del limite massimo impostato per il riavvolgimento delle tende (ad es. con 20 millisecondi --> la massima velocitĂ  di rotazione rilevabile è di 50 giri al secondo, che con il mio anemometro equivalgono a circa 40 m/s = 144 km/h, mentre io voglio che le tende vengano riavvolte giĂ  a partire da 20-30 km/h).
  • il sensore magnetico (Reed switch) dell’anemometro consente fisicamente di rilevare solo il numero di giri che il rotore compie per intervallo di tempo; per convertirla in velocitĂ  lineare (tangenziale) in teoria basta applicare la formula: [velocitĂ  tangenziale in m/s] = pi x [velocitĂ  angolare in giri / s] x [diametro del rotore in m]. Nella pratica, però, la velocitĂ  di rotazione è influenzata da molti fattori: il vento non trascina il rotore “afferrandolo” in modo rigido solo all’estremitĂ  delle palette, il rotore ha una sua inerzia, le palette generano portanza a seconda dell’angolo di incidenza del flusso d’aria, etc. Quindi per ottenere un minimo non dico di precisione, ma almeno di verosimiglianza, il calcolo della velocitĂ  lineare va calibrato: io ho usato un anemometro “vero” (che uso per i droni) con cui ho misurato la velocitĂ  del flusso d’aria di un asciugacapelli (circa 10 m/s = 36 km/h, una velocitĂ  al di sopra della quale sicuramente voglio che le tende vengano riavvolte), e poi ho modificato per tentativi il valore della costante WIND_SENSOR_DIAMETER (riga 85) fino a ottenere con il “mio” anemometro Arduino una misura ragionevolmente simile. Nota: alcuni anemometri piĂą “seri” hanno piĂą di 1 magnete sul rotore e quindi producono piĂą di 1 impulso a ogni giro (tipicamente 2 o 4); in tal caso si può semplicemente dividere WIND_SENSOR_DIAMETER per il numero di magneti.

Complimenti (e +1) per il progetto e per la dettagliata esposizione. :slight_smile:

Solo una nota: mi pare che il 4N35 nello schema sia disegnato al contrario, cosi com'è non ha molto senso...

Ciao, Ale.

Bel progettino, complimenti anche per questa documentazione, utilissima per chi volesse realizzare qualcosa di simile! :sunglasses:

Mi disturba solo la scritta ABB sottosopra sul coperchio della scatolina (perché?), ma so di essere ossessivo-compulsivo quindi non farci caso... :smiling_imp:

docdoc:
Bel progettino, complimenti anche per questa documentazione, utilissima per chi volesse realizzare qualcosa di simile! :sunglasses:

Mi disturba solo la scritta ABB sottosopra sul coperchio della scatolina (perché?), ma so di essere ossessivo-compulsivo quindi non farci caso... :smiling_imp:

Banalmente, ho disegnato la sagoma per l'LCD sul retro del coperchio, e mi sono accorto che era al contrario solo dopo aver ritagliato il buco... >:( . Comunque, anche a disegnarlo nel verso giusto, avrei tagliato la scritta ABB a metà, e la scatola era già rovinata e con buchi "extra": più che altro volevo vedere se ci stava tutto o se avrei avuto bisogno di una scatola più grande. Mi riprometto di farne una definitiva a partire da una scatola nuova: se e quando posterò una nuova foto in onore della tua compulsione :slight_smile:

complimenti

k++

ilguargua:
Complimenti (e +1) per il progetto e per la dettagliata esposizione. :slight_smile:

Solo una nota: mi pare che il 4N35 nello schema sia disegnato al contrario, cosi com'è non ha molto senso...

Ciao, Ale.

Grazie Ale, però non ho capito perché pensi che sia disegnato al contrario. Bada bene: non dico che così sia "dritto", ma solo che non so valutare se è dritto o al contrario (ho scopiazzato pedissequamente dal progetto 15 del libro dello Starter Kit). Ho controllato, e l'optoisolatore è cablato proprio così:

  • pin 1 (anodo del LED integrato, contrassegnato da un pallino) --> digital pin 13
  • pin 2 (catodo del LED integrato) --> terra attraverso una resistenza da 220 ohm
  • pin 3 (not connected) --> niente
  • pin 4 (emittitore del fototransistor BJT npn integrato) --> un contatto del bottone del telecomando
  • pin 5 (collettore del fototransistor BJT npn integrato) --> l'altro contatto del bottone del telecomando
  • pin 6 (base del fototransistor BJT npn integrato) --> niente

Quanto a funzionare, funziona: quando il led è acceso, i pin 4 e 5 vengono cortocircuitati e "simulano" la pressione del bottone sul telecomando.

:confused: Mi spieghi, per favore? Grazie in anticipo

Un ultimo paio di considerazioni sul codice che, pur non essendo specifiche per Arduino, potrebbero non essere evidenti a tutti (poi la smetto, promesso! :slight_smile: ):

  • l’array wind[] (riga 123) in cui vengono memorizzate le ultime misurazioni della velocitĂ  del vento (cioè la finestra temporale sulla quale vengono calcolate le velocitĂ  media e massima) non ha bisogno di essere inizializzato: un indice (sampleCount) tiene conto di quanti campioni sono stati raccolti fin ora e permette di gestire correttamente il transitorio iniziale, cioè i primi secondi di funzionamento durante i quali l’array non è ancora “pieno” (righe 216-217). Una volta che l’array si è riempito, viene gestito a rotazione (rolling): un altro indice (currentSample) permette di sovrascrivere sempre la misurazione piĂą vecchia (righe 243-246). Il calcolo della media semplice è commutativo, quindi si possono sommare i campioni raccolti partendo sempre dal primo (e poi dividere per il numero di campioni raccolti), senza preoccuparsi di qual è il campione piĂą recente (righe 221-224).

  • per la variabile di stato che memorizza l’unitĂ  di misura correntemente selezionata (displayMode, riga 142) è stato definito un apposito tipo enumerato (SpeedUnit, riga 136). Può sembrare che non ci sia nessun vantaggio pratico rispetto a definire questa variabile semplicemente come intero e che, anzi, si crei qualche scomoditĂ : non solo non posso usare l’operatore ++, ma per incrementare la variabile il compilatore mi obbliga anche a fare un casting esplicito (riga 269). Il punto è proprio questo: avendo definito la variabile come enum, assegnandogli un valore intero senza casting il compilatore darebbe un errore, attirando così la mia attenzione sul fatto che devo assumermi la piena responsabilitĂ  di quello che sto facendo. In pratica il cast è una “liberatoria” con cui assicuro al compilatore che mi sto impegnando a rispettare “manualmente” il dominio dell’enumerazione; naturalmente, avendo preso un impegno, poi lo devo onorare aggiungendo un controllo che assicuri che i valori da assegnare alla variabile abbiano un significato valido rispetto alla definizione dell’enumerazione (righe 268-271).

Mi spieghi, per favore?

Niente, va bene così, sono io che avevo immaginato che volevi leggere il pulsante con l'Arduino non il contrario!

Ciao, Ale.

Ottimo, grazie per la conferma! Si, nello schema magari dovrei chiarire meglio che in alto ci sono tutti gli input, e in basso gli output... Ciao!

Bel progetto, ero curioso di vedere come era impostata la logica del pulsante, e vedo che usa un paio di "stratagemmi" a cui non avevo mai pensato (come il debounce implicito controllando BUTTON_SHORT_INTERVAL).

Un "appunto" che mi sento di fare è sul portarsi dietro lungo tutta la logica i livelli hardware diretti, se un domani si vogliono cambiare i collegamenti, ad esempio passare da pulsante che chiude verso massa a pulsante che chiude verso Vcc o viceversa, tocca modificare un sacco di condizioni (cioè oltre a fare fatica si rischia anche di fare errori).

Personalmente cerco di astrarre ancora di più, e lavorare sempre in logica positiva, oltre a tenere dentro le funzioni le variabili che servono solo dentro alle funzioni stesse, dichiarandole static se devono mantenere il valore come le globali. Nel seguente codice nota come la logica (i due if finali) è governata solo da due variabili impulsive onQualchecosa e non c'è neanche l'ombra di HIGH/LOW :wink:

void checkButton()
{
  static int lastPressedState = 0;                       // inizializzata solo la prima volta
  static unsigned long lastButtonMillis;
  static unsigned long lastBrightnessMillis;

  int pressed = digitalRead(BUTTON_PIN) == PRESS_LEVEL;  // pressed=1 quando puls.premuto
  int onPress = pressed && !lastPressedState;            // rileva fronte pressione
  int onRelease = !pressed && lastPressedState;          // rileva fronte rilascio
  lastPressedState = pressed;

  if (onPress) lastButtonMillis = lastBrightnessMillis = currentMillis;  // tempo alla pressione
  unsigned long elapsed = currentMillis - lastButtonMillis;              // trascorso da pressione

  int onClick = onRelease && (elapsed > BUTTON_SHORT_INTERVAL) && (elapsed < BUTTON_LONG_INTERVAL);
  int longPress = pressed && (elapsed > BUTTON_LONG_INTERVAL);
  int onRepeat = longPress && (currentMillis - lastBrightnessMillis > BRIGHTNESS_INTERVAL);
  if (onRepeat) lastBrightnessMillis = currentMillis;

  if (onClick)
  {
    if ( displayMode < NUM_MODES-1 )
      displayMode = (SpeedUnit)(displayMode+1);
    else
      displayMode = MS;
  }

  if (onRepeat)
  {
    displayBrightness += BRIGHTNESS_INCREMENT*brightnessDirection;
    analogWrite(LCD_BKL_PIN, 255*displayBrightness/100);
    if (displayBrightness >= 100) brightnessDirection = -1;
    if (displayBrightness <= 0) brightnessDirection = 1;
  }
}

Ciao, io per il sensore pioggia ho risolto cosi:

Sensore utilizzato come contagoccie(non risente di luce diretta o cambi repentini di luce, rileva i fulmini però e le api in estate :slight_smile: ....)

scatola con coperchio trasparente

il sensore si trova all'interno della scatola rivolto verso l'alto(punta il cielo), il tutto inclinato a 45°, in pratica ogni goccia che cade o scorre sul sensore cambia lo stato del sensore stesso e incrementa un conteggio. se nei 60 secondi di verifica che ho impostato dalla prima attivazione, raggiungo la soglia di chiusura delle tende le chiudo, altrimenti allo scadere azzero il conteggio. ho dovuto implementare un'interrupt dato che il passaggio dell goccia era troppo veloce per farlo rilevare senza...

spero di esserti stato di aiuto.(ringrazio ancora steve per l'idea e i vari consigli dati all'epoca, io l'ho solo ottimizzata...)

ciao

Claudio_FF:
Personalmente cerco di astrarre ancora di piĂą, e lavorare sempre in logica positiva, oltre a tenere dentro le funzioni le variabili che servono solo dentro alle funzioni stesse, dichiarandole static se devono mantenere il valore come le globali.

Grazie mille per le preziose indicazioni: proprio il tipo di feeback che andavo cercando! Sulle variabili locali statiche avrei dovuto arrivarci da solo: tutte quelle variabili globali usate solo in un punto... L'astrazione dai dettagli dell'hardware è un ottimo principio (soprattutto per quando riguarda la riusabilità futura), ma a prima vista il codice mi sembrava essere un pelo più "ostico" come leggibilità. Tuttavia, già alla seconda occhiata è perfettamente chiaro, per cui lo adotterò senz'altro. Grazie anche per esserti preso la briga di riscrivere il mio codice: più efficace di mille parole.

simosere:
Ciao, io per il sensore pioggia ho risolto cosi:

Sensore utilizzato come contagoccie(non risente di luce diretta o cambi repentini di luce, rileva i fulmini però e le api in estate :slight_smile: ....)

Ciao, grazie mille per il suggerimento "testato sul campo". Non ho capito benissimo il principio di funzionamento "fisico", però: mi sembra che il sensore rilevi gli ostacoli in base alla quantità di luce IR riflessa (solo alla specifica frequenza emessa dal sensore stesso). Quindi il sensore riesce a "vedere" le gocce di pioggia che scorrono sul coperchio trasparente della scatola come ostacoli? Inoltre, non sono certo di aver capito il montaggio: il sensore è perpendicolare al coperchio della scatola, e poi la scatola è montata a 45°?

si tutto corretto!! :slight_smile:

simosere:
si tutto corretto!! :slight_smile:

Ok, capito. Le gocce di pioggia non sono molto riflettenti (essendo trasparenti): la forma convessa della parte "esterna" della goccia fa sì che un po' di luce torni indietro verso il sensore ma non molta, quindi il sensore deve essere impostato su una sensibilità piuttosto alta per premettere il rilevamento delle gocce, rendendo questo approccio abbastanza vulnerabile ai "falsi allarmi" (es. gli insetti). Inoltre, il fatto che "senta" anche i fulmini (che emettono parecchio nell'infrarosso e anche a frequenze più basse, fino alle microonde e oltre) mi fa pensare che il tuo sensore non sia modulato.

Mi piacerebbe provare a trovare una soluzione piĂą "robusta" che 1) usi un sensore IR PCM 38 kHz, che ignora qualsiasi luce IR che non sia modulata alla frequenza giusta, ad es. TSSP58038) e 2) che, invece che la riflessione, sfrutti la rifrazione causata dalla presenza delle gocce d'acqua come i sensori dei parabrezza delle auto, tipo:

Continuerò a cercare, e se non lo troverò proverò a costruirmelo DIY. Comunque, grazie per il suggerimento.

Ciao Fruttello,

si lo so, non è la soluzione migliore che c'è sicuramente, di seguito le mie considerazioni in base a quello che c'è in commercio e alle prove che feci in passato:

  • Sensore a pettine --> di quelli economici che trovi su ebay o amazon, in giro di una settimana si ossidano e li butti
  • Sensore a pettine autocostruito in acciaio INOX --> dopo un'anno sono cominciati i problemi di ossidazione, è comunque un sistema destinato a ossidarsi.
  • Sensore IR per rilevazione ostacoli --> al momento l'unico che mi permette di far funzionare il tutto con una decina di euro spesi tra sensore,scatola e cavo... è vero che possono esserci falsi positivi, ma le soglie impostate per la chiusura sono alte... in questo annetto che lo sto usando gli insetti passano e se ne vanno(poi una spruzzata di prodoto per gli insetti risolve il problema :slight_smile: ) e i fulmini, beh se fulmina c'è anche pioggia e se non c'è arriverĂ  perchè per rilevare un fulmine vuole dire che questo avviene vicino...

tutto il resto lo scartai perchè non adatto alle mi esigenze... tipo bascula... ecc

i sensori ottici(tipo quelli delle auto) che dici tu li cercai anche io, se ne trovano ma sono costosi( 100 euro...) e alimentati a 12V , nel mio caso avrei avuto noie con aggiunta di alimentatore e ricablaggio.

ti metto questo link dove affrontai alcune cose riguardo il sensore che ti ho consigliato e nel post #1 e #3 trovi un sensore tipo quello delle auto che appunto costa un centinaio di euro...

spero di esserti stato di aiuto, alla fine stai affrontando quello che affrontai io tempo fa.

Ciao

Claudio_FF:
Un "appunto" che mi sento di fare è sul portarsi dietro lungo tutta la logica i livelli hardware diretti, se un domani si vogliono cambiare i collegamenti, ad esempio passare da pulsante che chiude verso massa a pulsante che chiude verso Vcc o viceversa, tocca modificare un sacco di condizioni (cioè oltre a fare fatica si rischia anche di fare errori).

Personalmente cerco di astrarre ancora di piĂą, e lavorare sempre in logica positiva, oltre a tenere dentro le funzioni le variabili che servono solo dentro alle funzioni stesse, dichiarandole static se devono mantenere il valore come le globali.

In allegato una nuova versone dello sketch, migliorato in base ai suggerimenti di Claudio: grazie per i consigli!

What's new:

  • minimizzate le variabili globali, sostituite dove possibile da variabili locali statiche
  • modificata la gestione del pulsante nella funzione checkButton(): ora c'è una costante BUTTON_PRESS_LEVEL che permette di impostare se a pulsante premuto il livello del segnale è HIGH (e.g. con pull-down) oppure LOW (e.g. con pull-up), astraendo maggiormente dalla logica del circuito e migliorando la riusabilitĂ .

myWind_v5.2.ino (17.3 KB)

1 Like

simosere:
spero di esserti stato di aiuto, alla fine stai affrontando quello che affrontai io tempo fa.

Ciao, grazie, di grande aiuto! Del sensore auto sto solo cercando di "imitare" il principio di funzionamento (rifrazione anziché riflessione), e la tua esperienza mi è estremamente utile. Innanzi tutto, dal thread che hai linkato ho capito che in effetti il "tuo" sensore è modulato (contiene un NE555 per generare il segnale PCM a 38kHz e un ricevitore tipo TSSP58038 per filtrare i segnali non modulati, o comunque a una frequenza diversa), quindi è una ottima base di partenza anche per il mio tentativo: devo "solo" adattarlo alla diversa geometria (emettitore e ricevente devono essere a 45° rispetto alla superficie del coperchio trasparente, che trasmette il segnale per riflessione interna - praticamente una guida d'onda) e invertire la logica di rilevamento come "tripwire" (a coperchio asciutto il segnale si trasmette e quindi "non c'è un ostacolo", mentre in presenza di gocce d'acqua la rifrazione disperde parte del segnale e bisognerà tarare la sensibilità del ricevitore in modo che il sensore lo interpreti come "c'è un ostacolo").
Ti faccio sapere come va... se poi non dovesse funzionare, ho sempre la tua soluzione "tried&true" pronta all'uso!