sleep mode

ciao,
sto facendo prove per vedere il consumo dei attiny85 in sleep mode, prendendo spunto qua e là ho messo su questo codice, il problema è che in sleep mode a 5 v consumano comunque 0.3mA
e non 0.01 o 0.002 come da datasheet.
mi chiedo dov'è l'errore?
premetto che il BOD è disattivato nei fuse

/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
#include <stdlib.h>  

#include <avr/sleep.h>  
 

void setup() {                
  // initialize the digital pin as an output.
 
  pinMode(2, OUTPUT);     
}

void loop() {

  digitalWrite(2, HIGH);   // set the LED on
  delay(1000);              // wait for a second
  digitalWrite(2, LOW);    // set the LED off
  delay(1000);              // wait for a second
 shutdown(); 
  
  
}

void shutdown(void) {    
 attachInterrupt(0, vuoto, HIGH);
  
set_sleep_mode(SLEEP_MODE_PWR_DOWN);    
sleep_mode();  
    sleep_disable();
 detachInterrupt(0);
}

void vuoto(){}

Ciao Garinus.
devi disattivare manualmente l'ADC, ora non ricordo il comando e sono al lavoro, se c'è Leo in giro lui lo avrà a portata di mano, è una riga soltanto, se poi ti fai una ricerca "menniti 128 KHz" (vado piano, che vuoi farci :grin:) dovresti trovare una discussione nelle cui ultime pagine ho postato il codice, ti scovi la riga con la scritta ADC e sei a posto.

ah è l'ADC che consuma tutto quello?
poi perchè non si sveglia più?

ho provato pure col metodo bella addormentata nel bosco ma nulla...

garinus:
ah è l'ADC che consuma tutto quello?
poi perchè non si sveglia più?

ho provato pure col metodo bella addormentata nel bosco ma nulla...

Cioè hai provato a dare un bacio al micro? TI si guardato allo specchio prima? Forse l'hai addormentato per sempre :stuck_out_tongue_closed_eyes:
Scherzi a parte, francamente finora l'ho usato solo in circuiti con ingressi digitali, non ho mai verificato se l'ADC si risvegliasse, sempre se ti stai riferendo SOLO all'ADC; probabilmente nella fase di risveglio devi mettere ance lo specifico comando di accensione.
Se ho capito male spiegami meglio qual è il problema.

non l'ADC ma proprio tutto.. mando il pin a high e lui non fa nulla..

garinus:
non l'ADC ma proprio tutto.. mando il pin a high e lui non fa nulla..

Credo che per l'interrupt devi usare uno dei pin predisposti, non uno qualsiasi. Se vuoi usarne uno qualsiasi devi importare la lib PinChangeInt

utilizzo il pin due che nel 85 equivale al INT0 che dovrebbe essere l'input dell'interrupt hardware 0 giusto?
con il settaggio dell'adc vado a consumo ok perfetto. grazie, ora non resta che svegliare il bel tiny addormentato

ok capito l'arcano, dal datasheet:
Note that recognition of falling or rising edge interrupts on INT0 requires the presence of an
I/O clock, described in “Clock Systems and their Distribution” on page 23.

perciò un rising non può svegliare il micro..
questo mi comporta un casino nel progetto.. mi basavo per svegliarlo su un rising..

L'INT0 sull'Attiny85 è il piedino 7, non il 2 (datasheet pag. 2). Per la corrispondenza fra pin logici e piedini fisici consulta il file /hardware/tiny/cores/tiny/pin_arduino.c. Contiene nei commenti i collegamenti giusti.

ADCSRA &= ~(1 << ADEN);

disattiva l'ADC.

Questo codice funziona perfettamente. Collega un led sul pin 3 (che è il piedino 2) ed un pulsantino sul piedino 7.
Quando è in sleep premi il pulsantino e lo risvegli: vedi il lampeggio di conferma. Poi torna a nanna.

#include <avr/sleep.h>  // libreria standard (avrlib) per lo sleep
#include <PinChangeInterruptSimple.h> // questa libreria permette di usare un qualsiasi pin come interrupt
/* Sleep test */
#define Sveglia 0    // pin 7 dell'attiny corrispondente a INT0
#define LED     3    // pin 3 dell'attiny85

void sbadiglio()        // risveglio dallo sleep
{
  // inserire eventuali azioni legate all'interrupt
}

void setup()
{
  pinMode(Sveglia, INPUT);
  //digitalWrite(Sveglia, HIGH);
  pinMode(LED, OUTPUT);
  
  attachPcInterrupt(Sveglia, sbadiglio, LOW);    // interrupt 0 
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // setta registri per il modo sleep
  sleep_enable();                        // abilita la sleep all'uso
}

void A_nanna()                      // funzione attivazione sleep
{
    attachPcInterrupt(Sveglia, sbadiglio, CHANGE); // riattiva l'interrupt
    ADCSRA &= ~(1 << ADEN);
    sleep_mode();                          // mette in stato di sleep
    sleep_disable();      // disattiva la modalità sleep e riporta il micro a piena operatività
    detachPcInterrupt(Sveglia);  // disattiva l'interrupt
}
void loop()
{
  for(byte i=0;i<4;i++)
   {
    digitalWrite(LED, HIGH);
    delay(200);
    digitalWrite(LED, LOW);
    delay(200);
   }
  A_nanna();               // mette il micro in sleep
}
//digitalWrite(Sveglia, 1);              // pull up attiva sul pin interrupt, ma conviene usare una 180K esterna

Leo, togli questo comment, vale solo per i miei nanetti :grin:

Allora te lo ricordi, eh :smiley:

leo72:
Allora te lo ricordi, eh :smiley:

Poiché su quel pin c'è il sensore rotativo con l'altro capo collegato a massa, quando si viene a trovare "chiuso", anche in sleep scorre corrente inutile; con la pull-up interna che è di 20-50K nella migliore ipotesi mi scorrevano 72µA, con una 180K invece l'ho portata a 20µA senza avere problemi; in realtà in altri casi si potrebbe portare fino a 330K, ma in questo caso specifico la rotazione mi innescava un loop per cui dovevo resettare il micro. Quindi questo è il valore trovato sperimentalmente per garantirmi il minor consumo compatibilmente col tipo di sensore usato. A parte la battuta sulla "paternità" era per evitare che qualcuno che facesse copia/incolla potrebbe pensare che sia sbagliato usare le pull-up interne.

Eh eh.. Il codice che ho postato è una mia elaborazione di un tuo codice iniziale. Siamo entrambi genitori dello stesso figlio :stuck_out_tongue:

Battute a parte, aprirò a breve un post perché ho BISOGNO di alcuni tuoi test, proprio in riferimento al consumo.

ma perchè usi la funzione attachpcInterrupt anzichè attachinterrupt?

si comunque utilizzavo già quel pin. non si svegliava perchè non essendoci il clock non poteva valutare se era un rising

La attachPcInterrupt è una funzione propria del core Tiny e quindi è ottimizzata per i micro di quella famiglia.

garinus:
ma perchè usi la funzione attachpcInterrupt anzichè attachinterrupt?

Come ti ha già detto Leo quello è un codice che è stato scritto per i tiny85, sul 328 devi usare il comando che conosci.

si comunque utilizzavo già quel pin. non si svegliava perchè non essendoci il clock non poteva valutare se era un rising

Cosa vuol dire che non c'è il clock? E come lavora il tuo micro, a pedali? Se vuoi svegliarlo con un "rising" devi dirglielo nella sintassi, tu hai scritto HIGH e lui si aspetta uno stato logico fisso HIGH, scrivi RISING al posto di HIGH e vedrai che ti funziona.

@ Leo: siamo dei con-papà, che dolcezza :* per le prove sono a disposizione, oggi ma più probabile giovedì devo aggiornare due nanetti, quindi ordina e sarai esaudito XD

quando si mette il micro in pwd mode il datasheet dice che non c'è battito, ops clock.
quindi il micro non può leggere un rising. io avevo messo high ma per errore. sempre dal dataheet si legge che uno stato high non attiva un interrupt ma solo un low o i vari change.

quindi l'attachinterrupt non è presente nel core tiny? solo la attachpc?

Quindi nella modalità pwr_down si ferma il clock? Sinceramente non ho approfondito sul datasheet i "rapporti" tra modalità di sleep e tipologie di interrupt, se così è funzionano solo HIGH e LOW.
Esistono due diverse librerie, una per il 328 ed una per il tiny, la prima usa attachInterrupt, la seconda attachPcInterrupt, e relativi detach, ovviamente. Tieni presente che con queste lib puoi usare qualsiasi pin come interrupt ed in più ti funziona anche la modalità CHANGE, che a questo punto, sostituirebbe, seppur con tempi molto più ampi, il falling e rising.

menniti:
Quindi nella modalità pwr_down si ferma il clock?

Si, in power down il clock è fermo ed è per questo motivo che non si possono usare per il risveglio le periferiche che lo richiedono attivo.

astrobeed:

menniti:
Quindi nella modalità pwr_down si ferma il clock?

Si, in power down il clock è fermo ed è per questo motivo che non si possono usare per il risveglio le periferiche che lo richiedono attivo.

OK, grazie, ecco perché, come giustamente dice Garinus, non può usare falling e rising, mentre funzionano regolarmente HIGH, LOW e, con la specifica lib, il CHANGE.