diff --git a/README.md b/README.md index 6b2f9d3..9e5e44f 100644 --- a/README.md +++ b/README.md @@ -311,7 +311,7 @@ Tests whether an alarm has been triggered. If the alarm was triggered, returns t ##### Parameters **alarmNumber:** The number of the alarm to test, ALARM_1 or ALARM_2 *(byte)* ##### Returns -Description *(type)* +Value of the alarm flag bit *(bool)* ##### Example ```c++ if ( RTC.alarm(ALARM_1) ) { //has Alarm1 triggered? @@ -322,6 +322,44 @@ else { } ``` +### checkAlarm(byte alarmNumber) +##### Description +Tests whether an alarm has been triggered. If the alarm was triggered, returns true, else returns false. The alarm flag is not reset. +##### Syntax +`RTC.checkAlarm(alarmNumber);` +##### Parameters +**alarmNumber:** The number of the alarm to test, ALARM_1 or ALARM_2 *(byte)* +##### Returns +Value of the alarm flag bit *(bool)* +##### Example +```c++ +if ( RTC.checkAlarm(ALARM_1) ) { //has Alarm1 triggered? + //yes, act on the alarm +} +else { + //no alarm +} +``` +### clearAlarm(byte alarmNumber) +##### Description +Clears the given alarm flag bit. +##### Syntax +`RTC.clearAlarm(alarmNumber);` +##### Parameters +**alarmNumber:** The number of the alarm to test, ALARM_1 or ALARM_2 *(byte)* +##### Returns +Value of the alarm flag bit, before it was cleared *(bool)* +##### Example +```c++ +if ( RTC.checkAlarm(ALARM_1) ) { //has Alarm1 triggered? + //yes, act on the alarm + RTC.clearAlarm(ALARM_1); //clear the alarm flag +} +else { + //no alarm +} +``` + ## Other functions ### temperature(void) ##### Description diff --git a/examples/alarm_ex9/alarm_ex9.ino b/examples/alarm_ex9/alarm_ex9.ino new file mode 100644 index 0000000..730ba72 --- /dev/null +++ b/examples/alarm_ex9/alarm_ex9.ino @@ -0,0 +1,113 @@ +// Arduino DS3232RTC Library +// https://github.com/JChristensen/DS3232RTC +// Copyright (C) 2020 by Jack Christensen and licensed under +// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html +// +// DS3231/DS3232 Alarm Example Sketch #9 +// +// Use Alarm 1 to turn on an LED at a given time, and Alarm 2 to turn +// it off at another time. +// Detect the alarms by polling the alarm flags. +// Assumes the RTC time is already set. +// +// Hardware: +// Arduino Uno, DS3231 RTC. +// Connect RTC SDA to Arduino pin A4. +// Connect RTC SCL to Arduino pin A5. +// Connect a push button from Arduino pin 3 to ground. +// Holding the button down during a reset or power on +// will cause the alarm times to be set. This allows +// us to test for the correct state after a reset or +// power cycle. +// +// Jack Christensen 06Sep2020 + +#include // https://github.com/JChristensen/DS3232RTC +#include // http://arduiniana.org/libraries/streaming/ + +// pin definitions +const uint8_t BUTTON_PIN(3); + +// current time from the RTC in text format +char timestamp[32]; + +void setup() +{ + Serial.begin(115200); + delay(1000); + Serial << F( "\n" __FILE__ " " __DATE__ " " __TIME__ "\n" ); + pinMode(LED_BUILTIN, OUTPUT); + pinMode(BUTTON_PIN, INPUT_PULLUP); + + // print the current time + time_t t = RTC.get(); + formatTime(timestamp, t); + Serial << millis() << F(" Current RTC time ") << timestamp << endl; + + // set the alarms if the button is pushed + if (!digitalRead(BUTTON_PIN)) { + // initialize the alarms to known values, clear the alarm flags, clear the alarm interrupt flags + RTC.setAlarm(ALM1_MATCH_DATE, 0, 0, 0, 1); + RTC.setAlarm(ALM2_MATCH_DATE, 0, 0, 0, 1); + RTC.alarm(ALARM_1); + RTC.alarm(ALARM_2); + RTC.alarmInterrupt(ALARM_1, false); + RTC.alarmInterrupt(ALARM_2, false); + RTC.squareWave(SQWAVE_NONE); + + // set alarm 1 to occur in 1-2 minutes + // set alarm 2 to occur 5 minutes after alarm 1 + tmElements_t tm; + breakTime(t + 120, tm); + tm.Second = 0; + time_t a1 = makeTime(tm); + time_t a2 = a1 + 300; + formatTime(timestamp, a1); + timestamp[8] = 0; // keep just hh:mm:ss + Serial << millis() << F(" Alarm 1 set to ") << timestamp << endl; + formatTime(timestamp, a2); + timestamp[5] = 0; // keep just hh:mm + Serial << millis() << F(" Alarm 2 set to ") << timestamp << endl; + RTC.setAlarm(ALM1_MATCH_HOURS, minute(a1), hour(a1), 1); + RTC.alarm(ALARM_1); // ensure alarm flag is cleared + RTC.setAlarm(ALM2_MATCH_HOURS, minute(a2), hour(a2), 1); + RTC.alarm(ALARM_2); // ensure alarm flag is cleared + } +} + +void loop() +{ + enum states_t {LED_OFF, LED_ON}; + static states_t state(LED_OFF); + + switch (state) { + case LED_OFF: + if (RTC.checkAlarm(ALARM_1)) { // time to turn on? + state = LED_ON; + RTC.clearAlarm(ALARM_2); + digitalWrite(LED_BUILTIN, HIGH); + formatTime(timestamp, RTC.get()); // get current RTC time + Serial << millis() << F(" Alarm 1 at ") << timestamp << endl; + } + break; + + case LED_ON: + if (RTC.checkAlarm(ALARM_2)) { // time to turn on? + state = LED_OFF; + RTC.clearAlarm(ALARM_1); + digitalWrite(LED_BUILTIN, LOW); + formatTime(timestamp, RTC.get()); // get current RTC time + Serial << millis() << F(" Alarm 2 at ") << timestamp << endl; + } + break; + } +} + +// format a time_t value, return the formatted string in buf (must be at least 25 bytes) +void formatTime(char *buf, time_t t) +{ + char m[4]; // temporary storage for month string (DateStrings.cpp uses shared buffer) + strcpy(m, monthShortStr(month(t))); + sprintf(buf, "%.2d:%.2d:%.2d %s %.2d %s %d", + hour(t), minute(t), second(t), dayShortStr(weekday(t)), day(t), m, year(t)); +} diff --git a/keywords.txt b/keywords.txt index 7c21ca2..8adbdac 100644 --- a/keywords.txt +++ b/keywords.txt @@ -9,6 +9,8 @@ readRTC KEYWORD2 setAlarm KEYWORD2 alarmInterrupt KEYWORD2 alarm KEYWORD2 +checkAlarm KEYWORD2 +clearAlarm KEYWORD2 squareWave KEYWORD2 oscStopped KEYWORD2 temperature KEYWORD2 diff --git a/library.properties b/library.properties index d25e7be..83a9704 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=DS3232RTC -version=1.2.12 +version=1.3.0 author=Jack Christensen maintainer=Jack Christensen sentence=Arduino Library for Maxim Integrated DS3232 and DS3231 Real-Time Clocks. diff --git a/src/DS3232RTC.cpp b/src/DS3232RTC.cpp index 0d519a9..a3d44c6 100644 --- a/src/DS3232RTC.cpp +++ b/src/DS3232RTC.cpp @@ -296,22 +296,41 @@ void DS3232RTC::alarmInterrupt(byte alarmNumber, bool interruptEnabled) // triggered, and resets the alarm flag bit. bool DS3232RTC::alarm(byte alarmNumber) { - uint8_t statusReg, mask; - - statusReg = readRTC(RTC_STATUS); - mask = _BV(A1F) << (alarmNumber - 1); - if (statusReg & mask) - { + uint8_t statusReg = readRTC(RTC_STATUS); + uint8_t mask = _BV(A1F) << (alarmNumber - 1); + if (statusReg & mask) { statusReg &= ~mask; writeRTC(RTC_STATUS, statusReg); return true; } - else - { + else { return false; } } +// Returns true or false depending on whether the given alarm has been +// triggered, without resetting the alarm flag bit. +bool DS3232RTC::checkAlarm(byte alarmNumber) +{ + uint8_t statusReg = readRTC(RTC_STATUS); + uint8_t mask = _BV(A1F) << (alarmNumber - 1); + return (statusReg & mask); +} + +// Clears the given alarm flag bit if it is set. +// Returns the value of the flag bit before if was cleared. +bool DS3232RTC::clearAlarm(byte alarmNumber) +{ + uint8_t statusReg = readRTC(RTC_STATUS); + uint8_t mask = _BV(A1F) << (alarmNumber - 1); + bool retVal = statusReg & mask; + if (retVal) { + statusReg &= ~mask; + writeRTC(RTC_STATUS, statusReg); + } + return retVal; +} + // Enable or disable the square wave output. // Use a value from the SQWAVE_FREQS_t enumeration for the parameter. void DS3232RTC::squareWave(SQWAVE_FREQS_t freq) diff --git a/src/DS3232RTC.h b/src/DS3232RTC.h index 0f627ca..4afb437 100644 --- a/src/DS3232RTC.h +++ b/src/DS3232RTC.h @@ -68,6 +68,8 @@ class DS3232RTC void setAlarm(ALARM_TYPES_t alarmType, byte minutes, byte hours, byte daydate); void alarmInterrupt(byte alarmNumber, bool alarmEnabled); bool alarm(byte alarmNumber); + bool checkAlarm(byte alarmNumber); + bool clearAlarm(byte alarmNumber); void squareWave(SQWAVE_FREQS_t freq); bool oscStopped(bool clearOSF = false); int16_t temperature();