Risveglio da modalità SLEEP attraverso interrupt esterno e timer

Salve a tutti.

Il progetto in questione è una piccola serra (contenente diversi sensori, ventole, sistema di riscaldamento, irrigazione, ecc.) che principalmente deve:

  • Leggere periodicamente dai sensori, aggiornare i dati e prendere le dovute decisioni;
  • Visualizzare lo stato su un display e permettere l'interazione con l'utente attraverso dei tasti.

In quanto l'idea è quella di alimentare il progetto con una batteria, risulta rilevante il risparmio energetico. Ciò che sono riuscito a fare fino ad ora, in due sketch differenti e con le librerie AVR, è:

  • Mettere in "sleep" il sistema e risvegliarlo attraverso interrupt esterno, ad esempio con un tasto;
  • Avere un timer (WatchDog) che possa risvegliare il sistema ed eseguire una procedura di aggiornamento periodicamente.

Quello che vi chiedo è se risulta possibile combinare queste due soluzioni in modo che il mio sistema:

  • Normalmente il sistema si trovi in SLEEP (con lcd spento)
  • Allo scadere del timer esegua una routine di aggiornamento dati e decisioni, anche in maniera asincrona rispetto al resto del programma
  • Nel momento in cui venga premuto un tasto si "risvegli", accenda il display e quindi visualizzi informazioni sul display e permetta all'utente di modificarne parametri ecc.
  • Dopo un certo tempo di "attività" esso torni di nuovo in SLEEP

Grazie.

Buonasera,
essendo il tuo primo post nella sezione Italiana del forum, nel rispetto del regolamento di detta sezione (… punto 13, primo capoverso), ti chiedo cortesemente di presentarti IN QUESTO THREAD (spiegando bene quali conoscenze hai di elettronica e di programmazione ... possibilmente evitando di scrivere solo una riga di saluto) e di leggere con molta attenzione tutto il su citato REGOLAMENTO ... Grazie. :slight_smile:

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposito thread, nessuno ti potrà rispondere, quindi ti consiglio di farla al più presto. :wink:
P.P.S.: Ti informo inoltre che, probabilmente, potresti avere problemi anche con QUESTO tuo post dato che hai ripreso un thread che era fermo dal ... 2016 e questo è contrario al regolamento.

Salve, mi scuso per non avere rispettato il regolamento. Mi sono presentato nel Thread da Lei indicato. Per quanto riguarda il post del 2016, non ne ero a conoscenza fosse contrario al regolamento.

Grazie, buona serata.

Giacomo

giacomo_boldini:
Quello che vi chiedo è se risulta possibile combinare queste due soluzioni in modo che il mio sistema:

  • Normalmente il sistema si trovi in SLEEP (con lcd spento)
  • Allo scadere del timer esegua una routine di aggiornamento dati e decisioni, anche in maniera asincrona rispetto al resto del programma
  • Nel momento in cui venga premuto un tasto si "risvegli", accenda il display e quindi visualizzi informazioni sul display e permetta all'utente di modificarne parametri ecc.
  • Dopo un certo tempo di "attività" esso torni di nuovo in SLEEP

Grazie.

Se sei riuscito a mandarlo in sleep e risvegliarlo con il watchdog non ti resta che gestire la logica che a te interssa via software. Ovvero quando ti scatta il watchdog periodico (suppongo via segnale da RTC) fai quello che devi fare (decisioni, aggiornamento dati, ecc.) e poi rimandi in sleep la MCU se le condizioni lo consentono, lavorare in modo asincrono dipende solo da te, la MCU di Arduino non è un PC e non ha capacità multithread quindi devi essere tu a sviluppare il programma nin modo che nessuna delle sue componenti sia bloccante (Es. non puoi udare istruzioni delay, cicli di attesa) ma tramite costrutti e funzioni specifiche (Es. millis() ) fare n modo che i compiti svenagano svolti senza nloccare l'esecuzione del programma per più del tempo strettamente necessario affinché ogni parte sia eseguita.
Non dichiari il tipo di Arduino in uso , se fosse una Uno hai comunque due interrupt hardware sfruttabili quindi per poter gestire la parte del pulsante puoi replicare quanto fatto con il primo interrupt, sempre per supposizione lo avrai interfacciato con l'RTC, per gestire il pulsante, premendolo risvegli Arduino e accendi il display, per fare questo ti posso consigliare di utilizzare un pin di Arduino per pilotare un transistor (o un mosfet in base all'assorbimento del display) per accendere e spegnere il display in questo modo quando vai in sleep e spegni tutto (display compreso) quando Arduino si risveglia con l'RTC non accendi il display, quando l'utente preme il pulsante invece piloti il pin relativo ed accendi il display consentendo all'utente di fare tutto ciò che serve, quando torni in sleep spegni il display tramite il solito pin che comando il transistor.
Dopo un certo tempo di inattività per spegnere devi usare millis() e trascorso il tempo da te deciso spegni il display, eventuali altre cose e mandi in sleep la MCU

fabpolli:
Se sei riuscito a mandarlo in sleep e risvegliarlo con il watchdog non ti resta che gestire la logica che a te interssa via software. Ovvero quando ti scatta il watchdog periodico (suppongo via segnale da RTC) fai quello che devi fare (decisioni, aggiornamento dati, ecc.) e poi rimandi in sleep la MCU se le condizioni lo consentono, lavorare in modo asincrono dipende solo da te, la MCU di Arduino non è un PC e non ha capacità multithread quindi devi essere tu a sviluppare il programma nin modo che nessuna delle sue componenti sia bloccante (Es. non puoi udare istruzioni delay, cicli di attesa) ma tramite costrutti e funzioni specifiche (Es. millis() ) fare n modo che i compiti svenagano svolti senza nloccare l'esecuzione del programma per più del tempo strettamente necessario affinché ogni parte sia eseguita.
Non dichiari il tipo di Arduino in uso , se fosse una Uno hai comunque due interrupt hardware sfruttabili quindi per poter gestire la parte del pulsante puoi replicare quanto fatto con il primo interrupt, sempre per supposizione lo avrai interfacciato con l'RTC, per gestire il pulsante, premendolo risvegli Arduino e accendi il display, per fare questo ti posso consigliare di utilizzare un pin di Arduino per pilotare un transistor (o un mosfet in base all'assorbimento del display) per accendere e spegnere il display in questo modo quando vai in sleep e spegni tutto (display compreso) quando Arduino si risveglia con l'RTC non accendi il display, quando l'utente preme il pulsante invece piloti il pin relativo ed accendi il display consentendo all'utente di fare tutto ciò che serve, quando torni in sleep spegni il display tramite il solito pin che comando il transistor.
Dopo un certo tempo di inattività per spegnere devi usare millis() e trascorso il tempo da te deciso spegni il display, eventuali altre cose e mandi in sleep la MCU

Salve,
In realtà sono riuscito a mandarlo in "sleep" ma non a risvegliarlo con un timer, in quanto si risveglia con la pressione di un tasto, al qualche ho "agganciato" un'interrupt (attraverso la libreria AVR/sleep.h).
Sono inoltre riuscito ad utilizzare un timer interno (WhachDog Timer) per generare delle interrupt al suo scadere ed eseguire del codice, anche facendo risvegliare il sistema da un sonno (non so se esattamente identico a quello precedente).

Quello che non riesco a fare è unire le due cose, in quanto non riesco a far "sopravvivere" il timer alla modalità sleep. Ovvero, vorrei riuscire a mandare in SLEEP profonda il sistema e permetterne il risveglio attraverso il tasto O la scadenza del timer. Dopo di che, una volta sveglio, se trattasi di interrupt generata da timer il sistema andrà semplicemente ad aggiornare i dati, altrimenti resta sveglio un po' (esegue un numero fissato di volte il loop) per interagire con l'utente e successivamente torna a dormire. Quello che mi manca, secondo me, è un meccanismo unico per entrambi i casi di far addormentare e risvegliare il sistema.

Per quanto riguarda l'uso del RTC: sto cercando di evitarne l'uso e sono riuscito a simulare un'attesa di 5 minuti attraverso la successione di diverse scadenze del WDT (che dovrebbe arrivare a circa 8 secondi). Se essa però risulta l'unica strada percorribile per questo genere di problema provvederò.

Spero di essere stato chiaro, grazie.

Posta il codice delle due prove, in linea di massima devi usare due interrupt differenti e quindi non dovresti aver problema ad unire le due prove.
L'RTC non è indispensabile e se il tuo progetto non lo richiede puoi continuare sulla tua linea, tuttvai l'uso di un RTC offre alcuni vantaggi ad esempio tempistiche molto più precise su temporizzazioni lunghe e minor consumo delle batterie se gli intervalli tra un risveglio e l'altro possono essere anche molto lunghi, ad esempio se tu risvegli la MCU ogni minuto allora serve a poco ma se tu avessi la necessità di risvegliare la MCU ogni ora allora il consumo si ridurrebbe di molto, più aumenta il tempo di sleep più l'uso dell'RTC ti abbassa i consumi.
Detto ciò indica anche che Arduino usi (Uno/MEGA/ECC?) e posta i due programmi che usi e che non riesci ad unire