Alarma con el reloj rtc 3231 que despierte del modo sleep al arduino uno.

Hola,

No consigo hacer funcionar que el reloj DS3231 AT24C32 despierte al Arduino Uno tras un sleep. Mejor dicho, no consigo que el Arduino se ponga en modo sleep. Siempre está despierto si conecto el pin SQW del RTC al pin 2 del Arduino. Si desconecto este pin, sí entra en modo sleep hasta que lo vuelvo a conectar.

Este es el código que utilizo (lo encontré en internet). Cuando lo ejecuto, siempre aparece el mensaje “Woke up”.
Le hice una pequeña modificación para leer el estado del pin 2 del arduino en cada segundo, obteniendo valores de 010101110011001100… No entiendo este comportamiento.
Agradecería si alguien puede ayudarme.
Muchas gracias.

#include <Wire.h>
#include <DS3231.h>
#include <avr/sleep.h>

int wakePin = 2; // pin used for waking up
int led=13;

DS3231 clock;
RTCDateTime dt;
boolean state;

void setup()
{

Serial.begin(9600);

// Initialize DS3231
Serial.println(“Initialize DS3231”);
delay(100);
clock.begin();

pinMode(wakePin, INPUT_PULLUP);
pinMode(led, OUTPUT);
//
// Disarm alarms and clear alarms for this example, because alarms is battery backed.
// Under normal conditions, the settings should be reset after power and restart microcontroller.
clock.armAlarm1(false);
clock.clearAlarm1();

// Set Alarm1 - Every 20s in each minute
// setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
clock.setAlarm1(0, 0, 0, 20, DS3231_MATCH_S);
attachInterrupt(0, wakeUpNow, FALLING);

// Check alarm settings
checkAlarms();
}

void checkAlarms()
{
RTCAlarmTime a1;
RTCAlarmTime a2;

if (clock.isArmed1())
{
a1 = clock.getAlarm1();

Serial.print("Alarm1 is triggered ");
switch (clock.getAlarmType1())
{

case DS3231_MATCH_S:
Serial.print(“when seconds match: “);
Serial.println(clock.dateFormat(”__ ::s”, a1));
delay(100);
break;
default:
Serial.println(“UNKNOWN RULE”);
break;
}
}
}

void wakeUpNow() {
// execute code here after wake-up before returning to the loop() function
// timers and code using timers (serial.print and more…) will not work here.
// we don’t really need to execute any special functions here, since we
// just want the thing to wake up
Serial.println(“Woke up”);
delay(100);
}

void sleepNow() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable(); // enables the sleep bit in the mcucr register
attachInterrupt(0,wakeUpNow, FALLING); // use interrupt 0 (pin 2) and run function
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…
// detachInterrupt(0); // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.
}

void loop()
{

dt = clock.getDateTime();

Serial.println(clock.dateFormat(“d-m-Y H:i:s - l”, dt));
delay(100);
// Call isAlarm1(false) if you want clear alarm1 flag manualy by clearAlarm1();
if (clock.isAlarm1())
{
Serial.println(“ALARM 1 TRIGGERED!”);
digitalWrite(led, HIGH);
delay(10000);
digitalWrite(led, LOW);
Serial.println(“Entering sleep”);
delay(100); // sleep function called here
sleepNow();
}

delay(900);
}

Hola compadre, este hombre tiene error en sus ejemplos, pero si te fijas en el vídeo explicativo de todas las partes de su magnífica librería, verás donde están, aun así, gracias al creador de la librería, a solucionado mi vida je. De todas formas te comparto mi propio ejemplo. Ten cuidado, no entiendo el por qué, pero a veces salta la interrupción del reloj fuera de la hora programada, sucede cada cierto tiempo. Yo lo he solucionado comprobando la hora en la condición “isAlarm” la que cambia en la interrupción que es una variable tipo boolean.

Aquí mi ejemplo, espero que te sea de ayuda, saludos.

/*
  DS3231: Real-Time Clock. Alarm simple
  Read more: www.jarzebski.pl/arduino/komponenty/zegar-czasu-rzeczywistego-rtc-DS3231.html
  GIT: https://github.com/jarzebski/Arduino-DS3231
  Web: http://www.jarzebski.pl
  (c) 2014 by Korneliusz Jarzebski
*/

#include <JeeLib.h> // sensor library from https://github.com/jcw/jeelib
ISR(WDT_vect) {
  Sleepy::watchdogEvent();
}

#include <Wire.h>
#include <DS3231.h>

DS3231 clock;
RTCDateTime dt;
boolean isAlarm = false;

void alarmFunction()
{
  Serial.println("*** INT 0 ***");
  isAlarm = true;
}

void setup()
{
  Serial.begin(9600);
  
  // Initialize DS3231
  Serial.println("Initialize DS3231");;
  clock.begin();
 
  // Disarm alarms and clear alarms for this example, because alarms is battery backed.
  // Under normal conditions, the settings should be reset after power and restart microcontroller.
  clock.enable32kHz(false);
  clock.enableOutput(false);

  // Manual (Year, Month, Day, Hour, Minute, Second)
  clock.setDateTime(__DATE__, __TIME__);

// setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
  clock.setAlarm1(0, 0, 0, 30, DS3231_MATCH_S);
  clock.setAlarm2(0, 0, 0,  DS3231_EVERY_MINUTE);

  // Attach Interrput 0. In Arduino UNO connect DS3231 INT to Arduino Pin 2
  attachInterrupt(2, alarmFunction, FALLING);

}

void loop()
{
  dt = clock.getDateTime();
  if(dt.second!=0 || dt.second!=30){
  delay(100);
  Sleepy::powerDown();
  //Serial.println(clock.dateFormat("d-m-Y H:i:s - l", dt));
  //delay(1000);
  }
  if (isAlarm)
  {
    clock.clearAlarm1();
    clock.clearAlarm2();
    Serial.println("Despierto durante 1 segundo");
    delay(1000);
  }
}