Come far lavorare ATmega a 128KHz di clock

Sempre per un progetto a cui sto lavorando da un po' di tempo apro un nuovo topic, poiché ho letto da qualche parte che l'ATmega328 si può impostare per lavorare con un clock di soli 128KHz.
Io sono riuscito, con l'aiuto del forum ad arrivare ad 1MHz, risparmiando molta energia, in termini di consumo, visto che realizzerò uno stand alone alimentato con batteria da 3,6V.
Poiché anche 128KHz mi sono più che sufficienti per quanto devo gestire penso che potrei ridurre i consumi davvero al minimo (ora sono a circa 3,5mA ed ancora devo sperimentare lo sleep).
Non dispongo di programmatori ma solo di Arduino col quale, usandolo come ISP, e creando una nuova board virtuale nel file boards.txt, sono riuscito appunto ad impostare il chip per il clock a 1MHz.
Con questa stessa tecnica dovrei impostare i fuses per avere invece 128KHz, ma sul programma di calcolo AVR® Fuse Calculator – The Engbedded Blog non so davvero cosa inserire. Ho fatto una prova e ho brickato un chip, non voglio fare una strage...
Oltre ai fuses ci sono altri valori che forse vanno settati.
Qualcuno ha idee da darmi?

Pagina 27 del datasheet: trovi che devi impostare il fuse CKSEL3..0 a 0011, quindi lavora un po' col Fusecalc impostando gli appropriati valori nella maschera in basso. Quindi per avere 0011 devi impostare così:
CKSEL3: spuntato
CKSEL2: spuntato
CKSEL1: NON spuntato
CKSEL0: NON spuntato

perché "spuntato" = 0 e "NON spuntato" = 1.
Dando "Apply values" vedi infatti che nel menu a tendina appare 128 kHz.

Grazie leo! XD
Avevo visto il reference ma non avevo capito che dovevo muovermi; in realtà nel menu a tendina esistono 3 configurazioni 0011, quindi la differenza dipende anche dal valore di SUT0 e SUT1, che servono per impostare o meno un ritardo al reset, con due possibili alternative; quindi posso lasciare quello senza delay o scegliere uno degli altri due a prescindere da cosa devo fare o ha importanza?
Ma secondo te, il resto delle righe da mettere in boards.txt come devono essere?
In ogni caso spero di fare domani il lavoro per il recupero del morto, una volta che va a buon fine posso sperimentare... :grin:

Non lo so!
Ti spiego: se prendi i valori di "default" per un Arduino UNO contenuti nel file boards.txt e li inserisci nella maschera del FuseCalc ottieni impostazioni ASSURDE! Clock esterno a 8 MHz??? Ma quando mai....
Quindi o i dati dei fuse sono messi nel file boards.txt a caso, tanto si torna al discorso che secondo me NON servono a nulla dato che avrdude NON può programmare i fuse usando la scheda Arduino, oppure che il FuseCalc sia approssimativo (ma non mi è parso per gli Attiny85).

PS:
leggendo il (massiccio) datasheet, mi par di capire che le scelte preferite sono quelle che garantiscono un tempo di avvio rallentato. Pare quindi per SUT preferibile impostare 10, ossia SUT1 NON spuntato e SUT0 spuntato nella maschera di FuseCalc.

leo72:
clock esterno a 8 MHz??? Ma quando mai....
Quindi o i dati dei fuse sono messi nel file boards.txt a caso, tanto si torna al discorso che secondo me NON servono a nulla dato che avrdude NON può programmare i fuse usando la scheda Arduino

Con i fuse non programmi la frequenza di lavoro di Arduino, programmi il tipo clock e l'eventuale tipo di quarzo, i fuse presenti in boards.txt sono corretti e avrdude li programma eccome usando usando Arduino come isp anche se ci sono dei limiti, alcuni fuse non li puoi modificare tramite la modalità ISP.
Il valore di 8 MHz che ti appare in FuseCalc, ma anche con qualunque altro tool di programmazione serio, p.e. AVRstudio, è solo un valore convenzionale per indicare che usi un quarzo di valore pari o maggiore a 8MHz, ovvero il terzo range di funzionamento dell'oscillatore, vedi tabella 8.3 sul data sheet nel capitolo dedicato al clock.

menniti:
Sempre per un progetto a cui sto lavorando da un po' di tempo apro un nuovo topic, poiché ho letto da qualche parte che l'ATmega328 si può impostare per lavorare con un clock di soli 128KHz.

Può lavorare anche con solo 1Hz di clock, come quasi tutti i microprocessori, invece di complicarti la vita con l'oscillatore interno RC, molto impreciso, usa il classico quarzo da 16MHz, così non devi cambiare nulla nei fuse e non rischi di "mattonare" l'ATmega, e utilizza il Clock Prescaler interno.
Il prescaler ti permette di dividere la frequenza del quarzo, e quindi il clock di lavoro del micro, per un fattore compreso tra 2 e 256 in otto step, quindi 2-4-8-16-32-64-128-256, partendo da un quarzo da 16MHz puoi ottenere 62500 Hz dividendolo per 256, con conseguenti consumi ancora più bassi.
Il prescaler, che si imposta da software agendo sul registro CKLPR, vedi data sheet al paragrafo 8.12.2, si usa moltissimo per le applicazioni a basso consumo, infatti puoi tenere il micro in modalità bassa corrente quando non deve elaborare nulla, per poi portarlo alla massima velocità quando deve fare molti calcoli e rimetterlo lento quando torna in idle.
Il modo migliore per risparmiare energia è spegnere le periferiche che non si usano e mettere il micro in sleep, è possibile scendere fino a solo 100 nA di consumo, per poi risvegliarlo in funzione di un evento e rimetterlo al lavoro con un consumo di energia scalabile in base alle esigenze, in questo modo è facile far durare una piccola batteria anche degli anni.
Non mi pare che esista una libreria per Wiring che gestisce il prescaler e lo sleep, potrebbe essere l'occasione buona per scriverla.

astrobeed:
Con i fuse non programmi la frequenza di lavoro di Arduino, programmi il tipo clock e l'eventuale tipo di quarzo

Certo, facevo un discorso semplicistico.

i fuse presenti in boards.txt sono corretti e avrdude li programma eccome usando usando Arduino come isp anche se ci sono dei limiti, alcuni fuse non li puoi modificare tramite la modalità ISP.

Posso esporti un caso? Esperienza diretta.
Un Attiny85 programmato tramite ArduinoISP (quindi usando l'Arduino come programmatore ISP): "sembrava" che i fuse fossero stati modificati ma in realtà non li aveva toccati. Usando l'USBtinyISP invece ce l'ho fatta. Usando proprio i fuse nel file boards.txt cercavo di disattivare il divisore x8 ma senza successo.
Che intendi poi che certi fuse non li puoi toccare? Io conosco 3 fuse: low, high ed ext.

Posso esporti un caso? Esperienza diretta.
Un Attiny85 programmato tramite ArduinoISP (quindi usando l'Arduino come programmatore ISP): "sembrava" che i fuse fossero stati modificati ma in realtà non li aveva toccati.

Mai usati gli Attiny85, non li conosco e potrebbero esserci delle limitazioni rispetto all'ATmega 328

Che intendi poi che certi fuse non li puoi toccare? Io conosco 3 fuse: low, high ed ext.

Intendo che alcuni bit dei fuse non sono modificabili tramite programmazione ISP, ma non è un problema reale di cui preoccuparsi dato che interessa solo certe funzionalità non presenti su tutti gli ATmega e che si usano molto raramente.
Il vero problema dei fuse, con la programmazione ISP, è che si setta per sbaglio il pin RESET come GPIO poi non è più possibile riprogrammare l'ATmega (= bricked), per rimediare tocca ricorrere agli altri metodi di programmazione supportati dagli AVR usando un idoneo programmatore esterno.
Due ottimi programmatori per AVR low cost, originali Atmel, sono l'AVRISP MKII e L'AVR Dragon, il secondo è più costoso e difficile da usare, però ha molte più funzionalità e si può considerare uno strumento professionale entry level.

Ah, ok: capito il discorso dei fuse. Sì, essi sono registri composti da diversi bit, di cui non tutti hanno lo stesso effetto su micro differenti.
Sapevo anche la storia del bit di reset, difatti per ora non ho mai manipolato altro a parte i fuse per impostare il tipo di clock.

astrobeed:
Può lavorare anche con solo 1Hz di clock, come quasi tutti i microprocessori, invece di complicarti la vita con l'oscillatore interno RC, molto impreciso, usa il classico quarzo da 16MHz, così non devi cambiare nulla nei fuse e non rischi di "mattonare" l'ATmega, e utilizza il Clock Prescaler interno.
Il prescaler ti permette di dividere la frequenza del quarzo, e quindi il clock di lavoro del micro, per un fattore compreso tra 2 e 256 in otto step, quindi 2-4-8-16-32-64-128-256, partendo da un quarzo da 16MHz puoi ottenere 62500 Hz dividendolo per 256, con conseguenti consumi ancora più bassi.
Il prescaler, che si imposta da software agendo sul registro CKLPR, vedi data sheet al paragrafo 8.12.2, si usa moltissimo per le applicazioni a basso consumo, infatti puoi tenere il micro in modalità bassa corrente quando non deve elaborare nulla, per poi portarlo alla massima velocità quando deve fare molti calcoli e rimetterlo lento quando torna in idle.
Il modo migliore per risparmiare energia è spegnere le periferiche che non si usano e mettere il micro in sleep, è possibile scendere fino a solo 100 nA di consumo, per poi risvegliarlo in funzione di un evento e rimetterlo al lavoro con un consumo di energia scalabile in base alle esigenze, in questo modo è facile far durare una piccola batteria anche degli anni.
Non mi pare che esista una libreria per Wiring che gestisce il prescaler e lo sleep, potrebbe essere l'occasione buona per scriverla.

Ciao,
sullo sleep la libreria esiste, ora sto cumulando info per buttarmici poi a capofitto, da qualche parte ho certamente il link, mi pare me l'abbia dato proprio leo! L'idea è quella di creare uno schedino minimo, voglio evitare (anche per limitare i costi al massimo, visto chedevo farne per ora 7, poi potrebbero essere di più) la componentistica del clock esterno.
Quello che vorrei ottenere è proprio questo, portare il micro ad un consumo prossimo allo "0" e riattivarlo qando il pin a cui è collegato il sensore va su high. Se ho ben capito dovrei usare il pin 2 o 3 di Arduino, che sono collegati ad interrupt, ma ancora non c'ho capito nulla.
Aggiungo, tanto per incasinare la cosa, che sto sperimentando su ATmega con l'intenzione di usare però ATtiny, per ragioni di spazio e sempre di consumo; ma se con questo non dovessi riuscire torno trnquillamente ad ATmega, ecco perché voglio andare fino in fondo!

Ciao,

qui di seguito trovi dei link dove trovi dei test fatti sui consumi ottenibili durante lo stato di sleep dell'ATmega.

In JeeLbas http://jeelabs.org/ trovi numerosi post sul risparmio d'energia (compresi gli sketch)
JeeNode e' una scheda compatibile con Arduino che e' nata con lo scopo di essere alimentata a batteria + radio (ATMega 328P a 16 MHz e 3.3V di alimentazione).

Fra i vari post trovi:

http://jeelabs.org/2009/12/09/low-power-mode-again/
http://jeelabs.org/2010/09/01/sleep/
http://jeelabs.org/2010/06/30/going-for-gold-with-the-bmp085/

I consumi nello stato di sleep erano dell'ordine dei 20 µA, con il brown-out detector (BOD) disabilitato, i consumi calano ulteriormente a circa un quarto (5 µA o meno).
Il BOD puo' essere anche disabilitato, per lo stato di sleep, a livello software.

Ci sono molti altri di post sul consumo, specie, se non ricordo male, del 2009.

Qui invece trovi il link gli esperimenti sul consumo di una scheda Arduino compatibile http://www.rocketscream.com/blog/2011/04/26/mini-ultra-8-mhz-current-consumption-part-2/#more-349 che funziona a 8 MHz.
Sempre col BOD disabilitato i consumi sono scesi sotto i 5 µA (2,1 µA di cui 0,5 dell'ATMega e 1,6 µA del regolatore di tensione).

Buona sperimentazione,
Marco.

Qui il discorso era già saltato fuori:
http://arduino.cc/forum/index.php/topic,59679.0.html
Queste sono due librerie che ti posso interessare:
http://www.nongnu.org/avr-libc/user-manual/group__avr__power.html
http://www.nongnu.org/avr-libc/user-manual/power_8h_source.html

Nell'ultimo reply avevo poi segnalato:

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()

ma occorre testarla. Quello di ridurre però la freq attraverso i prescaler interessa anche a me, gli avete gia provati ? In caso il codice sarebbe:

CLKPR|=(1<<CLKPS3).....

vero?

Per l'oscillatore a 125kHz ho visto su datasheet che deve essere CKSEL3..0=0011 (pag 34) dice pero anche che:
Note that the 128 kHz oscillator is a very low power clock source, and is not designed for high
accuracy.

Ho trovato questa:
http://www.arduino.cc/playground/Code/Prescaler
dove dice infatti che le funzioni millis() e delay() non funzionano in caso di prescaler, son pero implementate quelle corrette

ritornando al discorso dei fuse e di arduino sull'attiny85...
quelli specificati nel file boards.txt non funzionano durante l'upload degli sketch perchè sono riferiti al bootloader, ma basta uscire dall'ide e anche usando arduinoisp con avrdude da linea di comando perchè funzioni tutto.
I programmatori per sbrikkare sono quelli di tipo hvsp (high voltage serial programmer)tipo avrdragon ma anche meno.. :wink: Electronics-Lab.com Blog
attenti a prescalare, tutte le funzioni che hanno a che fare col tempo sballeranno (delay , millis, pwm, i tempi di conversione di analogread ecc...)

La variazione di millis(), delay()....... ok che cambiano mentre quelli della seriale dovrebbe restare uguali pero? (forse NewSerLine non è più corretta)

mmm... mi sà di no, cambia anche quella
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1292389555

Da quel post concludeva dicendo che sbagliava l'arduino scelto comunque la cosa è da verificare perchè se fosse cosi la cosa si complicherebbe di molto. Quando lavoraro con avr infatti occorreva inserire la dichiarazione della freq tipo:
define F_CPU 1000000UL // 1 MHz
e da li infatti la funzione delay andava ad adattarsi come si vede qui:
http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html
forse bisognerebbe mettere mano a wiring.c

guarda dentro il file hardwareserial la funzione che setta il baudrate è dipendente dal parametro F_CPU
:wink:

Vero ma da quello che ho capito in 10 sec leggendo dal datasheet il prescaler non dovrebbe interessare le librerie della seriale perchè il clock di queste viene calcolato tramite l'hardware. Quel F_CPU nella libreria penso serva solo per disattivare u2x in modo da avere meno errori di trasmissione