Interrupt con RTC e Sleep Mode è possibile ?

Salve, vorrei sapere se è possibile con il DS1307 ( http://datasheets.maxim-ic.com/en/ds/DS1307.pdf ) creare interrupt e mettere arduino in modalità in sleep mode ? In caso di risposta affermativa come posso realizzarlo?

grazie

Visto che hai aperto un nuovo topic invece di continuare sullo stesso, addirittura mettendo il link ad esso, ritengo il comportamento talmente inspiegabile ed inutile, che non rispondo :)

Scusami non volevo, sistemo il post... =(

Non senza sbattimenti. Nel senso che il DS1307 non prevede un allarme. Diversamente, il PCF8563 prevede un allarme interno impostabile dall'utente che genera un segnale di interrupt su un pin esterno, segnale che può essere poi intercettato dall'Arduino/Atmega mediante un interrupt di cambio di stato su quel pin.

Grazie,
ma c’e’ una cosa che mi frulla in testa…
Non potrei sfruttare l’SQW/OUT per l’interrupt? Sto dicendo una castroneria?

Ni. Nel senso che quel pin è solo un rimando esterno di un segnale di clock ricavato da quello del quarzo con un divisore (puoi avere, se non ricordo male, 32768 Hz, 8193 Hz, 4096 Hz, 1 Hz). Lato Arduino devi perciò intercettarlo e crearti un contatore che conti un certo numero di colpi e poi attivare la tua funzione a tempo.

Con un PCF8563 puoi tenere il micro in sleep finché non arriva un unico segnale sul pin. Qui è il PCF che fa il lavoro al posto tuo. Inoltre l'allarme è programmabile e si attiva fino ad 1 settimana all'intervallo scelto dall'utente (ogni ora, ogni giorno, ogni giorno della settimana ecc.).

Ho pensato di fare un interrupt con timer2 per stampare l’ora di un RTC esterno DS1307.
Quello che voglio fare e’ stampare l’orario ogni 20 minuti, accade pero’ che 20 secondi prima dello scoccare dei 20 minuti arduino si sveglia torna in sleep conta nuovamente i 20 secondi mancanti e stampa.
Ho il sospetto che perdo 1 secondo ogni minuto e non capisco perche’.
Vi posto il codice

// Library RTC
#include <Wire.h>
#include <RTClib.h>

// Library XBEE SLEEP MODE
#include <avr/interrupt.h>   
#include <avr/io.h> 
#include <avr/sleep.h>
#define INIT_TIMER_COUNT 0
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT

// Variable XBEE SLEEP MODE
int int_counter = 0;      
int second = 0;
int XBee_pin = 7;          // This pins wake up xbee and put it to sleep
int seconds = 1200;          // Time sleeping (aprox seconds) MINIMUM VALUE = 5
int time = 2*seconds;      
boolean flag = false;

// Variable RTC
RTC_DS1307 RTC;
unsigned int giorno, mese, anno, ora, minuti, secondi;

// Aruino runs at 16 Mhz, so we have 61 Overflows per secondi 1/ ((16000000 / 1024) / 256) = 1 / 61 this subroutine is executed 61 times per second
ISR(TIMER2_OVF_vect) {                
 int_counter ++;
 if (int_counter == 15) { 
  second++;
  int_counter = 0;        
 }
 if (second == time-1) {           
  digitalWrite(XBee_pin, LOW);
 }
 if (second == time) {
  second = 0;
  flag = true;
  Print_Date();
  digitalWrite(XBee_pin, HIGH);
 }
}

void Xbee_Setup(){
 pinMode(XBee_pin, OUTPUT);
 digitalWrite(XBee_pin,HIGH);
 //Timer2 Settings:  Timer Prescaler /1024
 TCCR2B |= ((1 << CS22) | (1 << CS21) | (1 << CS20));
 //Timer2 Overflow Interrupt Enable
 TIMSK2 |= (1 << TOIE2);
 RESET_TIMER2;
 sei();
 digitalWrite(XBee_pin, LOW);
// delay(20);
 Print_Date();
 digitalWrite(XBee_pin,HIGH);
}

void Rtc_Setup(){
 Wire.begin();
 RTC.begin();
 if (! RTC.isrunning()) {
  Serial.print("RTC ");
  Serial.println(" is NOT running!");
  //RTC.adjust(DateTime(__DATE__, __TIME__));
 }
}

// Function print date 
void Print_Date() {
 Serial.print(giorno);
 Serial.print("/");
 Serial.print(mese);
 Serial.print("/");
 Serial.print(anno);
 Serial.print(" ");
 Serial.print(ora);
 Serial.print(":");
 Serial.print(minuti);
 Serial.print(":");
 Serial.print(secondi);
 Serial.println("");
 Serial.println("");
}

void setup(){  
 Serial.begin(19200);    // Inizializza la porta seriale
 Rtc_Setup();
 Date_Setup();
 Xbee_Setup(); 
}

void SleepNow(){
 set_sleep_mode(SLEEP_MODE_PWR_SAVE);   // sleep mode is set here
 sleep_enable();          // enables the sleep bit in the mcucr register
 sleep_mode();            // here the device is actually put to sleep!! THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
 sleep_disable();         // first thing after waking from sleep: disable sleep...
 Date_Setup();
}

// Function to init date rtc
void Date_Setup() {
 DateTime now = RTC.now();
 giorno = now.day();
 mese = now.month();
 anno = now.year();
 ora = now.hour();
 minuti = now.minute();
 secondi = now.second();
}

void loop(){
 if(flag == true){
  Date_Setup();
  flag=false;
 }
 if(flag == false){ 
  SleepNow();
 }
}

Con quel timer lì il micro si sveglia esattamente 61 volte al secondo, è anche scritto nei commenti.

Comunque a me non torna. Prima dichiara time pari a 1200*2, quindi 2400 secondi, che sono 40 minuti, poi aggiorna i secondi ogni 15 incrementi della variabile counter, che poi è appunto incrementata 61 volte al secondo.... Quindi a me pare normale che si attivi prima dei 20 minuti. Ma dovrebbe attivarsi diversi minuti prima, non solo 20 secondi prima.

Avevo il sospetto di non aver capito bene quello che accade nella ISR. Adesso che mi hai dato queste spiegazioni qualcosa di più chiaro ce l'ho anche se ancora non sono riuscito a capire la relazione che c'e' fra int_counter, time e second. [...]

int second = 0;
int seconds = 1200;          // Time sleeping (aprox seconds) MINIMUM VALUE = 5
int time = 2*seconds;


// Arduino runs at 16 Mhz, so we have 61 Overflows per secondi 1/ ((16000000 / 1024) / 256) = 1 / 61 this subroutine is executed 61 times per second
ISR(TIMER2_OVF_vect) {                
 int_counter ++;
 if (int_counter == 15) { 
  second++;
  int_counter = 0;        
 }
 if (second == time-1) {           
  digitalWrite(XBee_pin, LOW);
 }
 if (second == time) {
  second = 0;
  flag = true;
  Print_Date();
  digitalWrite(XBee_pin, HIGH);
 }
}

Come posso ottenere i secondi in relazione ai contatori?

Secondo quel codice ogni 15 interrupt viene incrementato il contatore dei secondi. Ma questo è sbagliato perché dovrebbe essere ogni 61 interrupt.

Ma quel codice lo hai copiato così oppure lo hai modificato tu? Mi viene da pensare che fosse il codice di qualcun altro ancora adattato dal tipo da cui l'hai copiato per qualche suo scopo particolare.