From 2ae8cf6e449cb50bc72ba93dbd40a4be02a2d911 Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Tue, 4 Jul 2023 18:16:33 +0200 Subject: [PATCH 1/2] chore(examples): update to manage RTC alarm in BCD or MIX mode In this sketch the RTC is configured in BCD or MIX mode (for the stm32 devices that supports it) An Alarm A is set to wakeup the system from low power deep sleep. Signed-off-by: Francois Ramu --- .../AlarmTimedWakeup/AlarmTimedWakeup.ino | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/examples/AlarmTimedWakeup/AlarmTimedWakeup.ino b/examples/AlarmTimedWakeup/AlarmTimedWakeup.ino index b64b097..59ea702 100644 --- a/examples/AlarmTimedWakeup/AlarmTimedWakeup.ino +++ b/examples/AlarmTimedWakeup/AlarmTimedWakeup.ino @@ -1,9 +1,11 @@ /* - AdvancedTimedWakeup + AlarmTimedWakeup - This sketch demonstrates the usage of Internal Interrupts to wakeup a chip in deep sleep mode. + This sketch demonstrates the usage of Internal Interrupts to wakeup a chip in deep sleep mode, + when the RTC is configured in BCD or MIX mode (BCD and BINARY) In this sketch: + - RTC is configured in BCD (default) or MIX mode (BCD and BINARY) - RTC date and time are configured. - Alarm is set to wake up the processor each 'atime' and called a custom alarm callback which increment a value and reload alarm with 'atime' offset. @@ -19,7 +21,7 @@ STM32RTC& rtc = STM32RTC::getInstance(); /* Change this value to set alarm match offset in millisecond */ /* Note that STM32F1xx does not manage subsecond only second */ -static uint32_t atime = 567; +static uint32_t atime = 600; // Declare it volatile since it's incremented inside an interrupt volatile int alarmMatch_counter = 0; @@ -35,21 +37,32 @@ static byte month = 1; static byte year = 18; void setup() { +#if defined(RTC_BINARY_NONE) + // Select RTC clock source: LSI_CLOCK, LSE_CLOCK or HSE_CLOCK. + // By default the LSI is selected as source. + // rtc.setClockSource(STM32RTC::LSE_CLOCK); + // Select the STM32RTC::MODE_BCD or STM32RTC::MODE_MIX + // By default the STM32RTC::MODE_BCD is selected. + // rtc.setBinaryMode(STM32RTC::MODE_BCD); + rtc.begin(true); /* reset the RTC else the binary mode is not changed */ +#else rtc.begin(); +#endif /* RTC_BINARY_NONE */ rtc.setTime(hours, minutes, seconds); rtc.setDate(weekDay, day, month, year); pinMode(LED_BUILTIN, OUTPUT); - Serial.begin(9600); + Serial.begin(115200); while (!Serial) {} + Serial.println(" Start !"); // Configure low power LowPower.begin(); LowPower.enableWakeupFrom(&rtc, alarmMatch, &atime); // Configure first alarm in 2 second then it will be done in the rtc callback - rtc.setAlarmEpoch( rtc.getEpoch() + 2); + rtc.setAlarmEpoch(rtc.getEpoch() + 2); } void loop() { @@ -63,8 +76,7 @@ void loop() { LowPower.deepSleep(); } -void alarmMatch(void* data) -{ +void alarmMatch(void* data) { // This function will be called once on device wakeup // You can do some little operations here (like changing variables which will be used in the loop) // Remember to avoid calling delay() and long running functions since this functions executes in interrupt context @@ -91,7 +103,7 @@ void alarmMatch(void* data) //Update epoch_ms - might need to add a second to epoch epoc_ms += _millis; if (epoc_ms >= 1000) { - sec ++; + sec++; epoc_ms -= 1000; } #endif From f221acef2287acb889d70929072af6b9c05938ca Mon Sep 17 00:00:00 2001 From: Francois Ramu Date: Fri, 29 Sep 2023 17:27:04 +0200 Subject: [PATCH 2/2] chare(examples): configure RTC alarm in BIN mode to wakeup from sleep In this sketch the RTC is configured in BINary only mode (for the stm32 devices that supports it) An Alarm A is set to wakeup the system from low power deep sleep. Signed-off-by: Francois Ramu --- .../binAlarmTimedWakeup.ino | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 examples/binAlarmTimedWakeup/binAlarmTimedWakeup.ino diff --git a/examples/binAlarmTimedWakeup/binAlarmTimedWakeup.ino b/examples/binAlarmTimedWakeup/binAlarmTimedWakeup.ino new file mode 100644 index 0000000..bd2b55e --- /dev/null +++ b/examples/binAlarmTimedWakeup/binAlarmTimedWakeup.ino @@ -0,0 +1,76 @@ +/* + binAlarmTimedWakeup + + This sketch demonstrates the usage of Internal Interrupts to wakeup a chip in deep sleep mode. + when the RTC is configured in BINary mode (BIN_ONLY) + + In this sketch: + - RTC in BINARY only for the stm32 that supports this mode + - Alarm is set to wake up the processor each 'atime' and called a custom alarm callback + which increment a value and reload alarm with 'atime' offset. + + This example code is in the public domain. +*/ + +#include "STM32LowPower.h" +#include + +/* Get the rtc object */ +STM32RTC& rtc = STM32RTC::getInstance(); + +/* Change this value to set alarm match offset in millisecond */ +static uint32_t atime = 600; +static uint32_t time_ts; /* value to get the binary time */ + +// Declare it volatile since it's incremented inside an interrupt +volatile int alarmMatch_counter = 0; + +void setup() { + // Select RTC clock source: LSI_CLOCK, LSE_CLOCK or HSE_CLOCK. + // By default the LSI is selected as source. + // rtc.setClockSource(STM32RTC::LSE_CLOCK); + // Select the STM32RTC::MODE_BIN + rtc.setBinaryMode(STM32RTC::MODE_BIN); + rtc.begin(true); /* reset the RTC else the mode is not changed */ + + pinMode(LED_BUILTIN, OUTPUT); + + Serial.begin(115200); + while (!Serial) {} + Serial.println(" Start !"); + + // Configure low power + LowPower.begin(); + LowPower.enableWakeupFrom(&rtc, alarmMatch, &atime); + + rtc.getEpoch(&time_ts); + + // Configure first alarm in 2 seconds then it will be done in the rtc callback + rtc.setAlarmEpoch(0, STM32RTC::MATCH_SUBSEC, (time_ts + 2000), STM32RTC::ALARM_A); +} + +void loop() { + Serial.print("Alarm Match: "); + Serial.print(alarmMatch_counter); + Serial.println(" times."); + Serial.flush(); + digitalWrite(LED_BUILTIN, HIGH); + LowPower.deepSleep(); + digitalWrite(LED_BUILTIN, LOW); + LowPower.deepSleep(); +} + +void alarmMatch(void* data) { + // This function will be called once on device wakeup + // You can do some little operations here (like changing variables which will be used in the loop) + // Remember to avoid calling delay() and long running functions since this functions executes in interrupt context + uint32_t _millis = 1000; + + if (data != NULL) { + _millis = *(uint32_t*)data; + } + + rtc.getEpoch(&time_ts); + alarmMatch_counter++; + rtc.setAlarmEpoch(0, STM32RTC::MATCH_SUBSEC, (time_ts + _millis), STM32RTC::ALARM_A); +}