I try to wake up an arduino nano from power_off with a timed alarm from the ds3231 real time clock.
The ds3231 module int/sqw pin is connected to pin 2 on the arduino. The arduino is powered off but never wakes up.
Edit: also (on most arduinos and most interrupt pins) you cannot wake up from SLEEP_MODE_PWR_DOWN by edge-triggered interrupts. You must use another sleep mode, like SLEEP_MODE_IDLE.
Edit: also (on most arduinos and most interrupt pins) you cannot wake up from SLEEP_MODE_PWR_DOWN by edge-triggered interrupts. You must use another sleep mode, like SLEEP_MODE_IDLE.
Before you spend too much time looking at the clock module, can you try putting the Arduino in a power down mode and then manually change the state of the interrupt pin to wake it up ?
Edit:
I have also found that calling attachInterrupt can sometimes trigger the interrupt service routine one time which, in your case, would detach the interrupt, but I cannot explain this behaviour.
6v6gt:
Before you spend too much time looking at the clock module, can you try putting the Arduino in a power down mode and then manually change the state of the interrupt pin to wake it up ?
As you can imagine I have already spent several hours trying to solve that problem.
The sketch works when I manually connect pin2 to GND. Then the interrupt is triggered and the arduino wakes up.
Once the alarm is triggered you must reset a flag so that it can be triggered again. You can do that by calling RTC.alarm( ALARM_1 ). You normally use this function like this:
void loop()
{
if ( RTC.alarm( ALARM_1 ) )
{
// do something when alarm is triggered
}
}
I have wasted a lot of time getting this alarm thing to work and wake up my arduino. I'm almost certain you must use a FALLING interrupt for it to work correctly, but I could be wrong.
To add to what guix has said, you should attach the interrupt once in setup() (using RISING or FALLING) and not detach it again. Then use the code provided by guix to detect that the interrupt has occurred and reset the alarm. I don't know how to reset the alarm using that library but it must be in there somewhere.
If you would like to check that the interrupt is working at all try this code which starts the 1Hz square wave and the interrupt toggles the LED.
/*
A simple sketch to test that a DS3231 RTC is interrupting
using the 1Hz square wave output.
The LED should blink on and off once per second.
Pete (El_Supremo)
*/
#include <Wire.h>
// RTC interrupt (SQW) connected to this pin.
// The interrupt routine then toggles LED_PIN
// On my Teensy 2 it is pin 7
// On NANO it is pin 2
#define RTC_ALARM_PIN 2
volatile short outbit = 0;
volatile unsigned char interrupted = 0;
//=====================================
void rtc_interrupt(void)
{
// Toggle the LED pin
outbit ^= 1;
digitalWrite(LED_BUILTIN, outbit);
}
//=====================================
void setup()
{
Serial.begin(9600);
Wire.begin();
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
RTC_init();
}
void loop(void)
{
}
//=====================================
#define CLOCK_ADDRESS 0x68
#define RTC_CONTROL 0x0E
#define RTC_CTLSTAT 0x0F
#define RTC_CRYSTAL 0x10
//=====================================
void RTC_write_register(unsigned char reg,unsigned char value)
{
Wire.beginTransmission(CLOCK_ADDRESS);
Wire.write(reg);
Wire.write(value);
Wire.endTransmission();
}
//=====================================
void RTC_init(void)
{
// Set up the RTC interrupt pin
pinMode(RTC_ALARM_PIN, INPUT_PULLUP);
// Attach the SQW interrupt
attachInterrupt(digitalPinToInterrupt(RTC_ALARM_PIN), rtc_interrupt, FALLING);
// Initialize control registers for SQW interrupt
RTC_write_register(RTC_CONTROL,0x00);
RTC_write_register(RTC_CTLSTAT,0x00);
}
guix:
Once the alarm is triggered you must reset a flag so that it can be triggered again. You can do that by calling RTC.alarm( ALARM_1 ). You normally use this function like this:
void loop()
{
if ( RTC.alarm( ALARM_1 ) )
{
// do something when alarm is triggered
}
}
walto:
As you can imagine I have already spent several hours trying to solve that problem.
The sketch works when I manually connect pin2 to GND. Then the interrupt is triggered and the arduino wakes up.
OK. In that case I would conclude that the pull down from the Clock Module is too soft for the Arduino to detect and would be thinking of slotting in a small one-shot (monostable Multivibrator) to condition the signal so it is not overlooked by the Arduino.
Edit: It looks like you have solved it in the meantime. I guess that is the end of a few frustrating hours of experimentation.
You need to use FALLING (not RISING or LOW). LOW will keep interrupting as long as the signal is LOW.
The clock ticks on the FALLING edge so that's the one to use with the DS3231.
Probably.
I have always set attachinterrupt in setup() and let it interrupt at whatever rate is set and not use detachinterrupt at all. Then in loop(), detect that the interrupt has just occurred, one way or another, and clear the alarm (this isn't needed with the 1Hz square wave).
6v6gt:
OK. In that case I would conclude that the pull down from the Clock Module is too soft for the Arduino to detect
Highly unlikely. But would believe a wiring error, or maybe there is no pull up on the input. If you remove the pull up from the RTC module, you need one on the processor side.
aarg:
Highly unlikely. But would believe a wiring error, or maybe there is no pull up on the input. If you remove the pull up from the RTC module, you need one on the processor side.
The internal pull up is sufficient. (I also checked with external pull ups and found no difference to the internal pullup)
el_supremo:
Probably.
I have always set attachinterrupt in setup() and let it interrupt at whatever rate is set and not use detachinterrupt at all. Then in loop(), detect that the interrupt has just occurred, one way or another, and clear the alarm (this isn't needed with the 1Hz square wave).
Pete
Calling attachinterrupt only in setup loop does not work (for some reason I don't know).