Go Down

Topic: RTC interrupt does not wake up my Arduino (Read 3111 times) previous topic - next topic

xDiNozzOx

Hi everyone!
I'm using DS1337 Real Time Clock to generate interrupts which then wake up my Arduino from sleep mode. But this isn't working out for me. When I tested external interrupt without sleep mode, just in basic program to do something when interrupt occurs it works fine. But as soon as I put it in sleep mode and try to wake it up with external interrupt that doesn't happen.

I'm using DS1337 library found here: https://github.com/sridharrajagopal/DSRTCLib

'Write Alarm' function didn't work for me so I just used 'getRegister' function to set up the alarm myself based on the datasheet.
Right now I'm stuck. I don't have any idea what I'm doing wrong so I'm asking you to help me.

Thank you in advance,

xDiNozzOx

P.S. code:

Code: [Select]
#include <DSRTCLib.h>
#include <Wire.h>
#include <avr/power.h>
#include <avr/sleep.h>

// definition for register addresses
#define AL1REG1 0x07
#define AL1REG2 0x08
#define AL1REG3 0x09
#define AL1REG4 0x0A

#define AL2REG1 0x0B
#define AL2REG2 0x0C
#define AL2REG3 0x0D

#define CONREG 0x0E
#define STAREG 0x0F

/*
  DS1339 RTC Example
  Tests and examples for common RTC library features.
  This shows the basic functions (reading and setting time/alarm values), converting back and forth between epoch seconds and calendar dates,
  and using alarm interrupts.

  Don't let the 'Binary sketch size' throw you; this example file and all its print statements add a lot of overhead.

*/

int ledPin =  6;        // LED on pin 6
int INT_PIN = 3;        // INTerrupt pin
int int_number = 1;     // INT1

DS1339 RTC = DS1339(INT_PIN, int_number);

void isr(){   // ISR function
  detachInterrupt(int_number);
  RTC.setRegister(STAREG, B00000000); // reseting alarm flag
}

void enterSleep(){  // function for entering sleep mode
  digitalWrite(ledPin, LOW);
  attachInterrupt(int_number, isr, FALLING);
 
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
 
  sleep_enable();
 
  sleep_mode();
 
  sleep_disable();
  power_all_enable();
}

/* ----------------- { SET UP } ---------------------------- */
void setup(){               
  pinMode(INT_PIN, INPUT);           
  //digitalWrite(INT_PIN, HIGH);
 
  pinMode(ledPin, OUTPUT);           
  digitalWrite(ledPin, LOW);         
 

  //enable deep sleeping
  //set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  //sleep_enable();

  Serial.begin(9600);               
  Serial.println ("DSRTCLib Tests");

  RTC.start();                       // make sure RTC is running
 
  if(!RTC.time_is_set()){            // set the time if not already   
    Serial.print("Clock not set. ");
    set_time();
  }
 
  // warning if OSC is not working
  if(!RTC.time_is_set()){
    Serial.println("Clock did not set! Check that its oscillator is working.");
  }
 
  delay(100);
 
  // set up for alarm '2' every minute (at 00 sec)
  attachInterrupt(int_number, isr, FALLING);
  //RTC.setRegister(0x07, B10000000);
  RTC.setRegister(AL2REG1, B10000000);
  RTC.setRegister(AL2REG2, B10000000);
  RTC.setRegister(AL2REG3, B10000000);
  RTC.setRegister(CONREG, B00011110);
}

/* ----------------- { MAIN PROGRAM} ---------------------------- */
void loop(){
 
  digitalWrite(ledPin, HIGH);
  delay(100);
 
  enterSleep();
 
}

/* ----------------- { FUNCTIONS TO SET AND PRINT TIME - not the problem ATM } ---------------------------- */
void set_time()
{
    Serial.println("Enter date and time (YYYYMMDD HH:MM:SS)");
    int year, month, day, hour, minute, second;
    int result = read_date(&year, &month, &day, &hour, &minute, &second);
    if (result != 0) {
      Serial.println("Date not in correct format!");
      return;
    }
   
    // set initially to epoch
    RTC.setSeconds(second);
    RTC.setMinutes(minute);
    RTC.setHours(hour);
    RTC.setDays(day);
    RTC.setMonths(month);
    RTC.setYears(year);
    RTC.writeTime();
    read_time();
}

void read_time()
{
  Serial.print ("The current time is ");
  RTC.readTime(); // update RTC library's buffers from chip
  printTime(0);
  Serial.println();

}

void printTime(byte type)
{
  // Print a formatted string of the current date and time.
  // If 'type' is non-zero, print as an alarm value (seconds thru DOW/month only)
  // This function assumes the desired time values are already present in the RTC library buffer (e.g. readTime() has been called recently)

  if(!type){
    Serial.print(int(RTC.getMonths()));
    Serial.print("/"); 
    Serial.print(int(RTC.getDays()));
    Serial.print("/"); 
    Serial.print(RTC.getYears());
  }
  else{
    //if(RTC.getDays() == 0) // Day-Of-Week repeating alarm will have DayOfWeek *instead* of date, so print that.
    {
      Serial.print(int(RTC.getDayOfWeek()));
      Serial.print("th day of week, ");
    }
    //else
    {
      Serial.print(int(RTC.getDays()));
      Serial.print("th day of month, ");     
    }
  }
 
  Serial.print("  ");
  Serial.print(int(RTC.getHours()));
  Serial.print(":");
  Serial.print(int(RTC.getMinutes()));
  Serial.print(":");
  Serial.print(int(RTC.getSeconds())); 
}

int read_int(char sep){
  static byte c;
  static int i;

  i = 0;
  while (1){
    while (!Serial.available())
    {;}

    c = Serial.read();
    // Serial.write(c);
 
    if (c == sep){
      // Serial.print("Return value is");
      // Serial.println(i);
      return i;
    }
    if (isdigit(c)){
      i = i * 10 + c - '0';
    }
    else{
      Serial.print("\r\nERROR: \"");
      Serial.write(c);
      Serial.print("\" is not a digit\r\n");
      return -1;
    }
  }
}

int read_int(int numbytes){
  static byte c;
  static int i;
  int num = 0;

  i = 0;
  while (1){
    while (!Serial.available())
    {;}

    c = Serial.read();
    num++;
    // Serial.write(c);
 
    if (isdigit(c)){
      i = i * 10 + c - '0';
    }
    else{
      Serial.print("\r\nERROR: \"");
      Serial.write(c);
      Serial.print("\" is not a digit\r\n");
      return -1;
    }
    if (num == numbytes){
      // Serial.print("Return value is");
      // Serial.println(i);
      return i;
    }
  }
}

int read_date(int *year, int *month, int *day, int *hour, int* minute, int* second){
 
  *year = read_int(4);
  *month = read_int(2);
  *day = read_int(' ');
  *hour = read_int(':');
  *minute = read_int(':');
  *second = read_int(2);

  return 0;
}



larryd

I believe you want to change

attachInterrupt(int_number, isr, FALLING);
To
attachInterrupt(1, isr, LOW);
No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

xDiNozzOx

Amm.. I tried all the options given for attachInterrupt function, none of them are working for me  :(

el_supremo

#3
Aug 10, 2014, 08:59 pm Last Edit: Aug 10, 2014, 10:54 pm by el_supremo Reason: 1
isr() and enterSleep() don't need to attach/detach the interrupt and the isr() should not use RTC.setRegister.
So, the isr() function is simply this:
Code: [Select]

void isr(){   // ISR function
}


enterSleep is this:
Code: [Select]

void enterSleep(){  // function for entering sleep mode
 digitalWrite(ledPin, LOW);

 set_sleep_mode(SLEEP_MODE_PWR_SAVE);
 
 sleep_enable();
 
 sleep_mode();
 
 sleep_disable();
 power_all_enable();
}


and loop() does the reset of the interrupt:
Code: [Select]

void loop(){

 digitalWrite(ledPin, HIGH);
 delay(100);
 
 enterSleep();
 RTC.setRegister(STAREG, B00000000); // resetting alarm flag
 
}


and BTW
Code: [Select]
attachInterrupt(int_number, isr, FALLING);
is correct. You do need FALLING - not LOW.

Pete
Don't send me technical questions via Private Message.

xDiNozzOx

I appreciate your help, but still nothing happens. LED blinks once and only when I upload the program or start the serial monitor. I don't know it's a mystery that I'm trying to solve for day or two now. My last hope is this forum.   :)

Could it be HW problem? Not likely, its jut one 8 DIL chip and some pull up resistors..

larryd

No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

el_supremo

I've had a look at the DSRTCLib code and you can save yourself a lot of pain by using the functions supplied there.

Call  DSRTCLib::init() from your setup() function and then call DSRTCLib::snooze(1) from loop() to sleep for one second. All you have to do is toggle the LED whenever snooze wakes up.

Pete
Don't send me technical questions via Private Message.

xDiNozzOx


Peruse this:
See "Waking from sleep with a signal"
http://www.gammon.com.au/forum/?id=11497


I tried it. And I didn't get any positive results.

xDiNozzOx


I've had a look at the DSRTCLib code and you can save yourself a lot of pain by using the functions supplied there.

Call  DSRTCLib::init() from your setup() function and then call DSRTCLib::snooze(1) from loop() to sleep for one second. All you have to do is toggle the LED whenever snooze wakes up.

Pete


Yes I could use that (and I think mask for the alarm is wrong in the library) but I have much greater goals. I want to write a program in which you can choose the interval of sleep mode (every second, minute, hour, day). I'm going to include this in much greater project where my main problem is power consumption. I tried WDT, works great, but max interval is 8s.

Anyway I'm stuck with this RTC right now. It is frustrating; I'm trying all sorts of combinations and nothing works :(

Go Up