Arduino NANO BLE - DS3231 alarm+interrupt example gets stuck

I am using the rtc.lib example called DS_3231alarm. With UNO it works fine (interrupt on pin 2). The alarm function runs and "Alarm Occurred!" message is diplayed once. With the Nano i have tried 13, 12 and finally 4 but it gets stuck.

I checked all the contacts with a multimeter - the only "strange" reading is between GND and SQW they are not in contact but have a small resistance (32 Ohm that I can read also when the DS3231 is totally disconnected).

To be more precise: if a run the example sketch with a "wrong" INT pin, the alarm fires regularly at the set time and the loop goes on forever (with SQW value always at 1). As soon as I declare the right interrupt pin at the first alarm the loop freezes.

I wonder if it is a hw failure. Can I run a ... diagnostic?

The sketch is exactly the same. The original project was working... as I could not understand what "change" could have led to misfunction I reverted to the basic examples.
???

Tks for any help...
Flavio

The Nano 33 BLE does not tolerate the printing from the alarm interrupt. When I modify the call to set a flag and respond to that flag in loop, I can see the alarm triggered and cleared every minute the same as with the Uno.

/* Example implementation of an alarm using DS3231
 *
 * VCC and GND of RTC should be connected to some power source
 * SDA, SCL of RTC should be connected to SDA, SCL of arduino
 * SQW should be connected to CLOCK_INTERRUPT_PIN
 * CLOCK_INTERRUPT_PIN needs to work with interrupts
 */

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

RTC_DS3231 rtc;

// the pin that is connected to SQW
#define CLOCK_INTERRUPT_PIN 2
volatile boolean interruptFlag = 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), onAlarm, 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);

  // schedule an alarm 10 seconds in the future
  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!");
  }
}

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

  // the stored alarm value + mode
  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;
  }

  // the value at SQW-Pin (because of pullup 1 means no alarm)
  Serial.print("] SQW: ");
  Serial.print(digitalRead(CLOCK_INTERRUPT_PIN));

  // whether a alarm fired
  if (interruptFlag)
  {
    interruptFlag = false;
    Serial.print(" Fired: ");
    Serial.print(rtc.alarmFired(1));
  }

  // Serial.print(" Alarm2: ");
  // Serial.println(rtc.alarmFired(2));
  // control register values (see https://datasheets.maximintegrated.com/en/ds/DS3231.pdf page 13)
  // Serial.print(" Control: 0b");
  // Serial.println(read_i2c_register(DS3231_ADDRESS, DS3231_CONTROL), BIN);

  // resetting SQW and alarm 1 flag
  // using setAlarm1, the next alarm could now be configurated
  if (rtc.alarmFired(1))
  {
    rtc.clearAlarm(1);
    Serial.print(" - Alarm cleared");
  }
  Serial.println();

  delay(2000);
}

void onAlarm()
{
  //Serial.println("Alarm occured!");
  interruptFlag = true;
}

/*static uint8_t read_i2c_register(uint8_t addr, uint8_t reg) {
    Wire.beginTransmission(addr);
    Wire.write((byte)reg);
    Wire.endTransmission();

    Wire.requestFrom(addr, (byte)1);
    return Wire.read();
}*/

1 Like

P.S. I completed another test... if I detach the SQW pin everything works fine. With an oscilloscope I can read the square wave of 1s every 5s (that is my setting for the alarm).

When I connect the SQW pin to pin 4 of the Arduino Nano BLE the sketch sets the alarm, prints two lines, waiting, and when the alarm fires stops dead.
???

Not easy to buy a new one to test ... with the risk of melting it down again.
Flavio

Uauhuuh! I'll do that first thing in the morning!

Thanks!
F

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.