Si può ridurre il consumo di ATmega328 a pochi µA?

Graazie a nuove tecniche sperimentate assieme a leo72 ho realizzato un circuito col solo ATmega328, da utilizzare in un impianto di antifurto [ometto tutta la spiegazione tecnica, ormai risolta]. Il chip è alimentato a 3,3-3,7V e lavora a 1MHz di clock; il consumo a riposo è di circa 1,6-2,6mA, sono troppi [anche qui evito la spiegazione tecnica]; dando un'occhiata al datasheet del chip (ma ho molte difficoltà nella traduzione e nella comprensione) mi pare di aver capito che via software posso "spegnere" una serie di circuiti interni al chip, dato che non mi servono, come p.es. l'ADC. Vorrei sapere se è vero e se potete aiutarmi in tal senso, qui parliamo di programmazione avanzata ed io davvero non so da dove iniziare :astonished:
Sto usando un pin IN digitale per controllare il sensore ed un pin OUT digitale per attivare il TX, nel codice faccio largo uso del delay e di alcune variabili per gestire i vari tempi; non mi serve altro.
Un esperto che abbia idee in merito?

Il data sheet dà un valore più basso per il micro in attività. Quindi deduco che il tuo legga costantemente il pin, giusto?
Se deve trasmettere solo quando legge qualcosa, perché non disattivare il micro mettendolo in power-down ed attivarlo solo quando riceve qualcosa su quel pin? Mi pare che il datasheet permette di risveglio del micro proprio con un impulso su un pin.

Per disattivare dei circuito interni devi con un programmatore ISP settare i rispettivi FuseBit. Non chiedermi adesso come e cosa.
La seconda strategia per risparmiare corrente e mettere il processore in standby e farlo risvegliare da un interupt pilotato da un timer.
Anche per saperne di piú Ti chiedo di indagare personalmente perché non so esserti di aiuto pratico.
Ciao Uwe

Intanto grazie ad entrambi.

leo72:
Il data sheet dà un valore più basso per il micro in attività. Quindi deduco che il tuo legga costantemente il pin, giusto?
Se deve trasmettere solo quando legge qualcosa, perché non disattivare il micro mettendolo in power-down ed attivarlo solo quando riceve qualcosa su quel pin? Mi pare che il datasheet permette di risveglio del micro proprio con un impulso su un pin.

Questo sarebbe già un ottimo primo passo, considerando che io attualmente leggo il pin (anche se sono ancora a livello laboratorio) 24h al giorno, mentre in realtà su quel pin arriveranno 20-30 impulsi la mattina quando apro la tapparella e la sera quando la chiudo.
Come si fa? Hai almeno un riferimento se non lo sai direttamente?

uwefed:
Per disattivare dei circuito interni devi con un programmatore ISP settare i rispettivi FuseBit. Non chiedermi adesso come e cosa.
La seconda strategia per risparmiare corrente e mettere il processore in standby e farlo risvegliare da un interupt pilotato da un timer.
Anche per saperne di piú Ti chiedo di indagare personalmente perché non so esserti di aiuto pratico.
Ciao Uwe

Grazie Uwe, se i fusebit fossero quelli usati per il clock non c'è problema, ormai con leo ci siamo riusciti e al più presto la tecnica sarà pubblicata nella terza versione della mia Guida; mi stai consigliando più o meno la stessa strategia di leo; ho già provato a leggere, infatti ho aperto il topic perché avevo intuito si potesse fare; purtroppo ho molte difficoltà con l'inglese; ormai mi conoscete, non chiedo il piatto servito in tavola, però un minimo di dritte mi servono, poi non mi spavento se devo fare migliaia di prove!

Non si deve ricorrere al programmatore.
Si parla di registri, che sono come quelli usati per impostare gli interrupt. E l'impostazione degli interrupt la fai a run-time, si fa a run-time (ossia con codice) anche quella del risparmio energetico. A tal proposito nel playground c'era un esempio proprio di un Arduino messo a "dormire" e risvegliato da un impulso su un pin. Non mi ricordo la pagina.... ora guardo....

Questo è già qualcosa:
http://www.arduino.cc/playground/Learning/ArduinoSleepCode

Grazie leo,
domani butto questo codice in un chip e cerco di capire se e come funziona, poi non mi resta che togliere tutto il superfluo; ad occhio il principio si basa sul mettere a nanna il chip (non ho capito come...) e a risvegliarlo quando viene "toccato" un interrupt.
Se trovi altro non risparmiarti/mi! :grin:

Viene messo in standby col massimo risparmio energetico sempicemente chiamando la funzione set_sleep_mode.
Prima di far ciò viene attaccato un interrupt al pin da controllare. Nel massimo risparmio energetico uno dei pochi moduli lasciati accesi è proprio quello di gestione degli interrupt esterni.

Una volta risvegliata la CPU, puoi mandare il segnale e poi rimetterla in modalità risparmio energetico.

Sì, chiaro, intanto mi stavo divertendo col traduttore live search, è fantastico :grin: Appena ho capito che chiama la breadboard "Tagliere" e il bootloader o lo sketch "Consiglio di Amministrazione" mi sono sganasciato dalle risate XD XD XD
Meglio trovare una parola per volta sul vocabolario, prima o poi finisco, parliamo di micro o di fettine di carne? :smiley:
Scherzi a parte grazie ancora, domani ti farò sapere, in tanto speriamo che qualcun altro possa dare indicazioni su come spegnere "definitivamente" (quindi anche quando non è in sleep mode) alcune sezioni.
Una sola domanda: la libreria <avr/sleep.h> la carica in automatico dalla cartella in cuji si trova o devo spostarla io?

Fa parte delle librerie di avr-gcc quindi basta includerla come nell'esempio.

Esiste anche questa libreria per spegnere alcune periferiche non utilizzate :
http://www.nongnu.org/avr-libc/user-manual/group__avr__power.html
http://www.nongnu.org/avr-libc/user-manual/power_8h_source.html
io l'ho usata nel mio progetto ma non so dirti il risparmio effettivo.

ypkdani:
Esiste anche questa libreria per spegnere alcune periferiche non utilizzate :
avr-libc: <avr/power.h>: Power Reduction Management
avr-libc: power.h Source File

Grazie, tutto è utile, proverò anche queste!

io l'ho usata nel mio progetto ma non so dirti il risparmio effettivo.

Quello te lo faccio sapere io, dopo aver fatto tutte le prove :wink:

Ehm, non avresti a portata di mano la parte di code usata per applicarle? Non ho questi livelli di conoscenza per cavarmela da solo :blush:

Per arduino mega avevo disattivato molte cose che non mi servivano, per ogni periferica basta fare:

power_adc_disable();
  power_spi_disable();
  power_timer1_disable();
  power_timer2_disable();	
  power_timer3_disable();	
  power_timer4_disable();
  power_timer5_disable();
  power_twi_disable();
  power_usart2_disable();
  power_usart3_disable();

Perfetto! Grazie, ora posso tentare qualcosa.
Ciao

In fondo alla libreria postata c'è anche una cosa molto interessante cioè il System Clock Prescale Register che permette di ridurre la frequenza di funzionamento dell micro in base al carico di lavoro. Sarebbe interessante vedere come funzione sull'arduino visto che mi sembra sia disponibile sia sull'arduino Uno che sul Mega, non vorrei pero che vada a modificare però i tempi di delay() e millis()