MKR1310 WAN wake up from deep sleep (standby mode with DS3231)

  Kiến thức lập trình

I am trying to make a simple sensor node for a project of mine and I’ve stumbled upon this issue with the deep sleep or STANDBY mode.

For my hardware, I am using:

Board: Arduino MKR1310 WAN
RTC: DS3231 module

The SQW pin is connected to the INT7(pin 7) of the board.

Here is the sketch. It’s a modified version of the example given here.

#include <Arduino.h>
#include <Wire.h>
#include <RTC.h>
#include <SPI.h>

void ISR();
void setAlarm();
void deepSleep();
void onAlarm();

// the pin that is connected to SQW
#define CLOCK_INTERRUPT_PIN 7

bool alarmSet = false;

void setup() {
    Serial.begin(9600);

    // initializing the rtc
    if(!rtc.begin()) {
        Serial.println("Couldn't find RTC!");
        Serial.flush();
        while (1) delay(10);
    }

    if(rtc.lostPower()) {
        // this will adjust to the date and time at compilation
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    }

    //we don't need the 32K Pin, so disable it
    rtc.disable32K();

    // Making it so, that the alarm will trigger an interrupt
    pinMode(CLOCK_INTERRUPT_PIN, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(CLOCK_INTERRUPT_PIN), ISR, FALLING);

    // set alarm 1, 2 flag to false (so alarm 1, 2 didn't happen so far)
    // if not done, this easily leads to problems, as both register aren't reset on reboot/recompile
    rtc.clearAlarm(1);
    rtc.clearAlarm(2);

    // stop oscillating signals at SQW Pin
    // otherwise setAlarm1 will fail
    rtc.writeSqwPinMode(DS3231_OFF);

    // turn off alarm 2 (in case it isn't off already)
    // again, this isn't done at reboot, so a previously set alarm could easily go overlooked
    rtc.disableAlarm(2);
}

void loop() {
    // Initial safety delay
    delay(10000);
    
    char date[10] = "hh:mm:ss";
    rtc.now().toString(date);
    Serial.print(date);

    // the stored alarm value + mode
    if(!alarmSet){
      setAlarm();
    }
    DateTime alarm1 = rtc.getAlarm1();
    Ds3231Alarm1Mode alarm1mode = rtc.getAlarm1Mode();
    char alarm1Date[12] = "DD hh:mm:ss";
    alarm1.toString(alarm1Date);
    Serial.print(" [Alarm1: ");
    Serial.print(alarm1Date);
    Serial.print(", Mode: ");
    switch (alarm1mode) {
      case DS3231_A1_PerSecond: Serial.print("PerSecond"); break;
      case DS3231_A1_Second: Serial.print("Second"); break;
      case DS3231_A1_Minute: Serial.print("Minute"); break;
      case DS3231_A1_Hour: Serial.print("Hour"); break;
      case DS3231_A1_Date: Serial.print("Date"); break;
      case DS3231_A1_Day: Serial.print("Day"); break;
    }
    Serial.println("]");
    deepSleep();
}


void setAlarm() {
  if(!rtc.setAlarm1(
            rtc.now() + TimeSpan(10),
            DS3231_A1_Second // this mode triggers the alarm when the seconds match. See Doxygen for other options
    )) {
        Serial.println("Error, alarm wasn't set!");
    }else {
        Serial.println("Alarm will happen in 10 seconds!");
        alarmSet = true;
    }
}

void deepSleep() {
  // Set the sleep mode to standby
  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
  __DSB();
  // SAMD sleep and wait for interrupt;
  __WFI();
}

void ISR() {
  Serial.println("I WOKE UP!");
  rtc.clearAlarm(ALARM_1);
  alarmSet = false;
}

RTC.h

#include <RTClib.h>

#define ALARM_1 ((uint8_t)1)
#define ALARM_2 ((uint8_t)2)
#define EXT_INT ((uint8_t)4)

RTC_DS3231 rtc;

The thing is that if I remove the deepSleep function call, the alarm goes off and ISR function is called once every 10 seconds. But just using this sketch as it is, the controller goes to sleep and never wakes up.

What exactly am I doing wrong? I have no idea. Please help!

NOTE:

The big delay at the start of the loop is to be able to program the board without resetting it.

LEAVE A COMMENT