STM32 power saving: wake up from RTC alarm and Serial – 6

Spread the love

STM32 power saving: wake up from RTC alarm and Serial
STM32 power saving: wake up from RTC alarm and Serial

As usual, our microcontrollers give a wide range of wake-up sources, we already see a timed wake-up, and now we introduce the wake-up via RTC alarm and Serial of our STM32.

Wake up with internal interrupt raise with the RTC alarm

For this test, It’s better if you read this article first “STM32: internal RTC, clock and battery backup (VBAT)” to understand better how to work the internal RTC.

We want to try to set an alarm to wake the device, and to do this the RTC library helps us.

In this case, we use the perfect integration of STM32LowPower and RTC library, and we can modify the sketch of the alarm used in the linked article to wake from a low-power mode.

/**
 * A simple sketch that set the time to
 * 2022-04-20 at 16:00:00
 * and an alarm at
 * 16:00:10
 * the result is the interrupt after 10 secs 
 * and wake from deep sleep status.
 *
 * by Renzo Mischianti <www.mischianti.org>
 * en: https://mischianti.org/category/tutorial/stm32-tutorial/
 * it: https://mischianti.org/it/category/guide/guida-alla-linea-di-microcontrollori-stm32/
 */

#include "STM32LowPower.h"
#include <STM32RTC.h>

/* Get the rtc object */
STM32RTC& rtc = STM32RTC::getInstance();

/* Change these values to set the current initial time */
const byte seconds = 0;
const byte minutes = 0;
const byte hours = 16;

/* Change these values to set the current initial date */
const byte day = 20;
const byte month = 4;
const byte year = 22;

void alarmMatch(void *data);

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

  // Select RTC clock source: LSI_CLOCK, LSE_CLOCK or HSE_CLOCK.
  // By default the LSI is selected as source.
//  rtc.setClockSource(STM32RTC::LSI_CLOCK);

  rtc.begin(); // initialize RTC 24H format
  // we set the time at 2022-04-20 at 16:00:00
  rtc.setTime(hours, minutes, seconds);
  rtc.setDate(day, month, year);

  delay(1000);


  String someRandomData = "www.mischianti.org";

  // Configure low power
  LowPower.begin();
  LowPower.enableWakeupFrom(&rtc, alarmMatch, &someRandomData);

  // Now we set an alert at 16:00:10
  // pratically 10 secs after the start
  // (check the initialization of clock)
  rtc.setAlarmDay(day);
  rtc.setAlarmTime(16, 0, 10, 0);
  rtc.enableAlarm(rtc.MATCH_DHHMMSS);

  // Print date...
  Serial.printf("Now is %02d/%02d/%02d %02d:%02d:%02d.%03d and we set the wake at 16:10! So wait 10secs! \n",
		  rtc.getDay(), rtc.getMonth(), rtc.getYear(),
		  rtc.getHours(), rtc.getMinutes(), rtc.getSeconds(), rtc.getSubSeconds());
  Serial.println("Deep Sleep!");
  delay(1000);

  LowPower.deepSleep();
}

void loop()
{
  // Print date...
  Serial.printf("%02d/%02d/%02d ", rtc.getDay(), rtc.getMonth(), rtc.getYear());

  // ...and time
  Serial.printf("%02d:%02d:%02d.%03d\n", rtc.getHours(), rtc.getMinutes(), rtc.getSeconds(), rtc.getSubSeconds());
  delay(1000);
}

void alarmMatch(void *data)
{
	String myData = *(String*)data;
	Serial.println("Alarm Match!");
	Serial.println(myData);
}

I highlight the dependence code we need to wake up from deep sleep (but work with all low-power modes). After importing the library, we are going to enable LowPower mode and attach the alarm interrupt.

  // Configure low power
  LowPower.begin();
  LowPower.enableWakeupFrom(&rtc, alarmMatch, &someRandomData);

Then, after setting all data to the alarm, we put in deepSleep the device.

  LowPower.deepSleep();

You can check the result in the serial output.

Now is 20/04/22 16:00:00.944 and we set the wake at 16:10! So wait 10secs! 
Deep Sleep!
Alarm Match!
www.mischianti.org
20/04/22 16:00:10.008
20/04/22 16:00:10.952
20/04/22 16:00:11.900
20/04/22 16:00:12.848
20/04/22 16:00:13.792
20/04/22 16:00:14.740

The sketch is very simple but offers functionality that can be very useful.

Wake up from Serial

Another interesting feature is the wake-up from the Serial device. It’s interesting, especially if you have an autonomous Serial device.

Here the STM32 and ST-Link V2 used in this test STM32F103C8T6 STM32F401 STM32F411 ST-Link v2 ST-Link v2 official

Here the FTDI USB to TTL CH340G - USB to TTL FT232RL


Here my multimeter Aneng SZ18

The USB Serial wake-up is not supported so we are going to enhance the basic wiring schema used for this test by adding also the wiring from STM32 Rx to Tx FTDI pin.

STM32: program via ST-Link and Serial via FDTI to wake-up from Sleep
STM32: program via ST-Link and Serial via FDTI to wake-up from Sleep
STM32FTDI
PA9Tx
PA10Rx
GNDGND

Here the FTDI USB to TTL CH340G - USB to TTL FT232RL


The sketch is also very simple.

/**
 * STM32 wake up from Serial, you must use and external FTDI connected
 *
 * STM32		FTDI
 * PA9			Tx
 * PA10			Rx
 *
 * then with a serial console try to write some text, the STM32 wake-up
 * read the Serial buffer and return in sleep.
 *
 * by Renzo Mischianti <www.mischianti.org>
 * en: https://mischianti.org/category/tutorial/stm32-tutorial/
 * it: https://mischianti.org/it/category/guide/guida-alla-linea-di-microcontrollori-stm32/
*/

#include "STM32LowPower.h"

// Declare it volatile since it's incremented inside an interrupt
volatile int wakeup_counter = 0;
void serialWakeup();

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("START PROGRAM!");

  // Configure low power
  LowPower.begin();
  // Enable UART in Low Power mode wakeup source
  LowPower.enableWakeupFrom(&Serial, serialWakeup);
}

void loop() {
  Serial.print("Start Sleep mode in ");
  for (int i = 5;i>0;i--) { Serial.print(i); Serial.print(" "); delay(1000); } Serial.println( "OK!" ); delay(1000);

  // Go to sleep
  LowPower.sleep();

  // Waked
  Serial.print(wakeup_counter);
  Serial.println(" wake up");

  // Give time to Serial bus to be ready
  delay(10);
  // Read all serial buffer
  while(Serial.available()) {
    char c = Serial.read();
    Serial.print(c);
  }
  Serial.println();
}

void serialWakeup() {
  // 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
  wakeup_counter++;
}

The serial output, in my case, is:

START PROGRAM!
Start Sleep mode in 5 4 3 2 1 OK!

>>Send to COM16: "pippo"<<
1 wake up
pippo

Start Sleep mode in 5 4 3 2 1 OK!

>>Send to COM16: "pluto"<<
2 wake up
pluto

Start Sleep mode in 5 4 3 2 1 OK!

>>Send to COM16: "paperino"<<
3 wake up
paperino

Start Sleep mode in 5 4 3 2 1 OK!

Thanks

  1. STM32F1 Blue-Pill: pinout, specs, and Arduino IDE configuration (STM32duino and STMicroelectronics)
  2. STM32: program (STM32F1) via USB with STM32duino bootloader
  3. STM32: programming (STM32F1 STM32F4) via USB with HID boot-loader
  4. STM32F4 Black-Pill: pinout, specs, and Arduino IDE configuration
  5. STM32: ethernet w5500 with plain HTTP and SSL (HTTPS)
  6. STM32: ethernet enc28j60 with plain HTTP and SSL (HTTPS)
  7. STM32: WiFiNINA with ESP32 WiFi Co-Processor
    1. STM32F1 Blue-pill: WiFi shield (WiFiNINA)
    2. STM32F4 Black-pill: WiFi shield (WiFiNINA)
  8. How to use SD card with stm32 and SdFat library
  9. \STM32: SPI flash memory FAT FS
  10. STM32: internal RTC, clock, and battery backup (VBAT)
  11. STM32 LoRa
    1. Unleashing IoT Potential: Integrating STM32F1 Blue-Pill with EByte LoRa E32, E22, and E220 Shields
    2. Unleashing IoT Potential: Integrating STM32F4 Black-Pill with EByte LoRa E32, E22, and E220 Shields
  1. STM32 Power saving
    1. STM32F1 Blue-Pill clock and frequency management
    2. STM32F4 Black-Pill clock and frequency management
    3. Intro and Arduino vs STM framework
    4. Library LowPower, wiring, and Idle (STM Sleep) mode
    5. Sleep, deep sleep, shutdown, and power consumption
    6. Wake up from RTC alarm and Serial
    7. Wake up from the external source
    8. Backup domain intro and variable preservation across reset
    9. RTC backup register and SRAM preservation
  1. STM32 send emails with attachments and SSL (like Gmail): w5500, enc28j60, SD, and SPI Fash
  2. FTP server on STM32 with w5500, enc28j60, SD Card, and SPI Flash
  3. Connecting the EByte E70 to STM32 (black/blue pill) devices and a simple sketch example

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *