Gestire attachInterrupt Falling e Rising sullo stesso pin

Ciao a tutti!!
Sarei grato se qualcuno mi sapesse dare qualche dritta sull'argomento che vado a presentare.
Ho un a scheda elettronica che voglio alimentare con una batteria tampone, quando viene a meno la tensione di rete(220V), si attiva una batteria che mi tiene in vita arduino.
Quello che intendo fare è gestire l'evento di connessione della batteria tampone con un attachInterrupt(RISING) che mi rileva la presenza di alimentazione della batteria.
Fino a qui la cosa penso sia facilmente gestibile. :fearful:
Il problema è che il sistema arduino + (sensori, display) consumano abbastanza (80-100 mA)e la vita della batteria è molto ridotta.
Cercando nel forum e in internet ho visto che c'è la possibilità di mettere in sleep l'arduino per farlo consumare meno, è possibile risvegliare arduino con lo stesso attachInterrupt che uso per batteria tampone? in questo caso quando ritorna la tensione di rete voglio rilevare il fronte di discesa è fare in modo che l'arduino si risvegli.
La mia prima idea è stata quella di gestire la cosa in questo modo, ma se avete soluzioni più semplici sono ben accette!! :smiley:

l'interrupt che vuoi usare è il CHANGE, che rileva il cambio stato di un pin. Poi rilevi lo stato attuale del pin e se rising fai X, se falling fai y... no?

Lesto grazie per le dritte!!!
Non avevo mai usato l'interrupt CHANGE. Si penso possa andare bene.
Dopo aver riconosciuto l'interrupt mi basta verificare lo stato del pin con un semplice digitalRead?Poi posso eseguire X se è basso o Y se è alto, giusto?

esatto! però al contrario, se ora leggi che il pin è ALTO, allora hai avuto un rising... perchè l'interrupt ovviamente viene lanciato dopo il cambio, il chip non legge nel futuro :slight_smile:

Gli eventi in pratica avvengono in 2 momenti differenti.
Il primo evento, se non è capito male, è RISING: nel momento in cui un pin ti manda un segnale alto, vuol dire che si è attivato il circuito di emergenza. Poi tu fai delle cose e dopo metti in sleep il micro. Lo vuoi risvegliare quando il pin torna low, quindi con un evento FALLING.
E' giusto?

L'Arduino che cosa fa, nel frattempo? Nel senso: puoi metterlo in sleep su due piedi?
Oppure devi salvare lo stato in cui si trova?

Io opterei per 2 interrupt differenti, ognuno per i 2 stati:

  1. primo interrupt: evento RISING. Attivi un interrupt che cambia una var di stato
  2. se nel codice ti accorgi che quella var è cambiato di stato, stacchi il primo interrupt, salvi lo stato, attacchi il secondo interrupt sull'evento FALLING e poi metti in sleep il micro
  3. al verificarsi dell'evento FALLING, il micro viene risvegliato.

Controlla bene sul datasheet che modalità di sleep puoi usare. Non tutte lasciano attivi tutti gli interrupt, alcune ne disattivano alcuni tipi. Forse in sleep ti converrebbe usare un PCINT, un interrupt sul cambio di stato di un pin, perché non tutti gli interrupt lavorano senza clock di sistema.

Si Leo il funzionamento che voglio ottenere è proprio quello.
Ci sono punti in cui il software è in attesa, mentre altri in cui il software esegue delle scritture sul display o altri in cui legge sensori, più raramente effettua movimentazioni di un motore. Le casistiche sono molte, forse la cosa migliore al ripristino è ricordarsi in che modalità ero e attivare una procedura di inizializzazione che mi riporta alla modalità in cui il micro è andato in sleep.

Quello che mi hai suggerito tu se non ho capito male, è di usare lo stesso pin ma di associargli due interrupt in manera sequenziale, cioè disattivi un L'interrupt rising metti in sleep e attivi quello di falling.
Io sto utilizzando un mega 2560, quello che mi consigli è di guardare il data sheet in modo da capire quali pin di interrupt rimangono abilitati nelle varie modalità di sleep?
Cosa intendi quando dici usare un PCINT?

Se usi l'Atmega2560 hai a disposizione 8 interrupt esterni, non 2 come nel caso dell'Atmega328. Per cui dovresti essere a posto senza dover ricorrere agli interrupt di cambio di stato (PCINT).

Se usi gli interrupt, questi restano attivi anche in modalità asincrona, cioè senza clock di sistema (quindi col chip in sleep) ma solo per "sentire" lo stato LOW. Ma questa è la condizione che ti serve, giusto?

Quindi ogni pin di interrupt è utile alla causa, indipendentemente dalla modalità di sleep,anche per quella a maggior risparmio SLEEP_MODE_PWR_DOWN, giusto?
Se dovessi gestirlo con un cambio di stato alto? Cioè sentire l'alimentazione della rete invece che lo stacco della batteria....

Ho fatto alcune prove di messa in modalità sleep e come mi dicevi funziona solo con lo stato LOW, quindi devo rivedere la parte elettronica, cioè fare in modo che riconosco lo stacco della batteria e non l'attacco della rete.Grazie!

Allora prova la PinChangeInt, è una lib che serve ad usare gli interrupt PCINT.
http://code.google.com/p/arduino-pinchangeint/
Questi funzionano anche in modalità power down, ma solo in modalità CHANGE, quindi un passaggio da alto a basso o viceversa. Ma penso che potrebbe fare al caso tuo.

Ciao a tutti,sono riuscito a far funzionare il codice per la gestione dello stand-by di arduino e sembra andare bene.
Praticamente quando si attiva la batteria vado a dare un +5 all'interrupt che manda in stand-by con la modalità set_sleep_mode(SLEEP_MODE_PWR_DOWN) l'arduino.
Quando si verifica uno stato low sull'interrupt questo si risveglia.Ho usato due attachInterrupt sullo stesso pin, attivandoli in maniera sequenziale.
Anche togliendo la retro illuminazione del display con l'arduino in modalità stand-by rimane sempre un consumo che si aggira sui 90-100mAh, quello che vi chiedo è se c'è un modo per ridurre ulteriormente i consumi modificando il software.O secondo voi non si possono ulteriormente abbassare i consumi.
Avete qualche consiglio a proposito!Ringrazio in anticipo per le risposte :slight_smile:

Devi disalimentare Sensori e display

Se tolgo l'alimentazione al display perdo le informazioni che c'erano riportate, ma se mi confermi che l'unica possibilità è questa vedo di programmare l'arduino in questo senso.

Comunque il discorso Sleep mode ha senso solo se usi uno standAlone.
In una mega 2560, anche se metti il processore in sleep, tutto il resto continua ad assorbire la stessa Q.ta di corrente.
( sia della scheda 2560, sia della circuiteria esterna )

In pratica cambia molto poco

Mi sembra di ricordarmi che esiste un'altra modalità di interrupt, la LOW, e può servire per mantenere il micro in sleep fino a che il pin è basso, però bisognerebbe leggere i datasheet del micro...

Janos:
Mi sembra di ricordarmi che esiste un'altra modalità di interrupt, la LOW, e può servire per mantenere il micro in sleep fino a che il pin è basso, però bisognerebbe leggere i datasheet del micro...

Quello a cui ti riferisci tu è la modalità di sleep "PowerDown", dove viene disattivato l'oscillatore interno.
In questa modalità gli unici interrupt che funzionano sono gli interrupt esterni denominati INTx impostati per attivarsi con un segnale LOW, che può essere rilevato anche in modalità asincrona, cioè in assenza di clock di sistema. Tutti gli altri stati non vengono rilevati in PowerDown, serve una modalità meno aggressiva che non disattivi il clock (cap. 13).

Bene provo a farmi un po di cultura sul datasheet del micro! Comunque se lo stand alone è la direzione migliore per ridurre i consumi e questo punto anche le dimensioni del sistema prenderò in considerazione questa soluzione.

Si io sto utilizzando appunto la modalità POWER_DOWN, che appunto tiene attivi solo gli interrupt per il risveglio del micro.
Ma non mi è sufficiente in quanto ci sono consumi ancora alti per una batteria a 9V.
Il display rimane acceso ma la retroilluminazione viene spenta, il problema è che se spengo del tutto il display poi si questo non si ripristina, scrive caratteri a caso come se fosse entrato un disturbo.
Ho un dubbio, se sono in modalità POWER_DOWN i sensori che sono eventualmente attaccati all'arduino dissipano altra corrente giusto?

fischio85:
Si io sto utilizzando appunto la modalità POWER_DOWN, che appunto tiene attivi solo gli interrupt per il risveglio del micro.
Ma non mi è sufficiente in quanto ci sono consumi ancora alti per una batteria a 9V.

Il motivo te l'hanno già spiegato. Usando una scheda, metti in sleep solo il micro, non tutto il resto della circuiteria.

[questo]
Il display rimane acceso ma la retroilluminazione viene spenta, il problema è che se spengo del tutto il display poi si questo non si ripristina, scrive caratteri a caso come se fosse entrato un disturbo.
[/quote]
Il consumo della sola logica di un display LCD è di solito nell'ordine di qualche mA.

Ho un dubbio, se sono in modalità POWER_DOWN i sensori che sono eventualmente attaccati all'arduino dissipano altra corrente giusto?

Dovresti infatti assicurarti di lasciare i pin in uno stato che non porti ad un consumo energetico verso l'esterno, altrimenti il tuo stand-by è inutile.

Ti consiglio una lettura o due di http://www.gammon.com.au/forum/?id=11497; oltre il power_down ci sono altre cose che potresti fare per ridurre il consumo. Però, in fin dei conti devi anche ridurre il consumo della scheda Arduino, o con il bare board, o togliendo le cose che consumano. Per esempio, il LED "Power" e se stai usando SPI il LED su pin 13 poiché pin 13 è usato per SCK. Inoltre, il regolatore di tensione consuma, e con più o meno difficoltà e rischio con i diversi modelli Arduino è possibile alimentare la scheda dal 5V e staccare i regolatori.
Ciao,
Lenni