cancel
Showing results for 
Search instead for 
Did you mean: 

Waking the Nucleo L432KC Board from Shutdown mode using the Arduino IDE

hysha2000
Associate

Hi everyone,

I'm working on a project with the STM32 Nucleo L432KC, where I need the microcontroller to enter shutdown mode to save power. The board is connected to an external RTC that triggers an interrupt every 30 seconds to wake the microcontroller. Upon waking, I want it to measure the temperature once using a BME280 sensor.

I've successfully implemented the RTC interrupt, and it works fine. However, when I attempt to put the microcontroller into shutdown mode, nothing happens—it's not waking up as expected.

I'm programming everything using the Arduino IDE and would really appreciate some guidance on how to correctly implement shutdown mode. Has anyone experienced a similar issue or knows how to solve this?

Thanks in advance!

 

This is the current code without shutdown which works:

 

 

#include "RV-3028-C7.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <STM32LowPower.h>

RV3028 rtc;
Adafruit_BME280 bme; // BME280-Sensor
STM32LowPower lowPower; // Instanz von STM32LowPower

void setup() {
  Serial.begin(115200);
  while (!Serial); // Warte, bis die serielle Verbindung hergestellt ist
  Serial.println("Setup gestartet...");

  // I2C initialisieren
  Wire.begin();
  Wire.setClock(50000); // Frequenz auf 50 kHz setzen

  // RTC initialisieren
  if (!rtc.begin()) {
    Serial.println("RTC nicht gefunden!");
    while (1); // Halte an, falls RTC nicht gefunden
  }

  // RTC-Timer konfigurieren (z.B. nach 30 Sekunden)
  rtc.setTimer(true, 1, 30, true, true, false); // Timer für 30 Sekunden setzen

  // BME280 initialisieren
  if (!bme.begin(0x76)) {  // 0x76 ist die I2C-Adresse des BME280
    Serial.println("BME280 nicht gefunden!");
    while (1); // Halte an, falls BME280 nicht gefunden
  }

  rtc.setBackupSwitchoverMode(0); // Switchover disabled
  rtc.disableTrickleCharge(); // Trickle Charge deaktivieren
  rtc.disableClockOut(); // CLKOUT deaktivieren

  // Externen Interrupt an PA0 setzen
  pinMode(PA0, INPUT_PULLUP); // PA0 als Eingang mit Pull-Up-Widerstand
  attachInterrupt(digitalPinToInterrupt(PA0), rtcInterrupt, FALLING); // Interrupt bei fallendem Signal

  Serial.println("Setup abgeschlossen, warte auf RTC-Interrupt.");
}

void loop() {
  //Serial.println("Gehe in den Deep Sleep-Modus...");
  //lowPower.deepSleep(0); // Doesnt work
}

// Interrupt-Service-Routine (ISR)
void rtcInterrupt() {
  Serial.println("RTC-Interrupt ausgelöst, wecke Mikrocontroller...");

  // I2C wieder aktivieren
  Wire.begin(); // I2C reaktivieren

  if (rtc.readTimerInterruptFlag()) { // Prüfen, ob der Timer-Interrupt ausgelöst wurde
    rtc.clearTimerInterruptFlag(); // Interrupt-Flag sofort zurücksetzen

    // Sensor aus dem Sleep-Modus aufwecken und Temperatur messen
    bme.takeForcedMeasurement(); // Einmalige Messung im Forced-Mode
    float temperature = bme.readTemperature(); // Lese die Temperatur vom BME280-Sensor

    // Ausgabe der gemessenen Temperatur über die serielle Verbindung
    Serial.print("Gemessene Temperatur: ");
    Serial.print(temperature);
    Serial.println(" °C");

    Serial.println("Gehe in den Deep Sleep-Modus...");
    //lowPower.deepSleep(0); // Gehe in den Deep Sleep-Modus, bis ein Interrupt den Mikrocontroller weckt
  }

  Wire.end(); // I2C wieder deaktivieren
}

 

 

This is the function:

 

void STM32LowPower::shutdown(uint32_t ms)
{
if ((ms != 0) || _rtc_wakeup) {
programRtcWakeUp(ms, SHUTDOWN_MODE);
}
/* Get the rtc object to know if it is configured */
STM32RTC &rtc = STM32RTC::getInstance();
LowPower_shutdown(rtc.isConfigured());
}

/**
* @brief Enable GPIO pin in interrupt mode. If the pin is a wakeup pin, it is
* configured as wakeup source.
* @PAram pin: pin number
* @PAram callback: pointer to callback function.
* @PAram mode: pin interrupt mode (HIGH, LOW, RISING, FALLING or CHANGE)
* @PAram LowPowerMode: Low power mode which will be used
* (IDLE_MODE, SLEEP_MODE, DEEP_SLEEP_MODE, SHUTDOWN_MODE)
* In case of SHUTDOWN_MODE only, Wakeup pin capability is activated
* @retval None
*/

void LowPower_shutdown(bool isRTC)
{
__disable_irq();

/* Clear wakeup flags */
#if defined(PWR_FLAG_WU)
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
#elif defined(PWR_CPUCR_CSSF)
__HAL_PWR_CLEAR_FLAG(PWR_CPUCR_CSSF);
#elif defined(PWR_MPUCR_CSSF)
__HAL_PWR_CLEAR_FLAG(PWR_MPUCR_CSSF);
#endif
#if defined(STM32WBxx)
/* Set low-power mode of CPU2 */
/* Note: Typically, action performed by CPU2 on a dual core application.
Since this example is single core, perform it by CPU1. */
/* Note: On STM32WB, both CPU1 and CPU2 must be in low-power mode
to set the entire System in low-power mode, corresponding to
the deepest low-power mode possible.
For example, CPU1 in Stop2 mode and CPU2 in Shutdown mode
will make system enter in Stop2 mode. */
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
#endif
#if defined(LL_PWR_SHUTDOWN_MODE) || defined(LL_PWR_MODE_SHUTDOWN)
/* LSE must be on to use shutdown mode within RTC else fallback to standby */
if ((!isRTC) || (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == SET)) {
#if defined(STM32U0xx)
HAL_PWR_EnterSHUTDOWNMode();
#else
HAL_PWREx_EnterSHUTDOWNMode();
#endif
} else
#else
UNUSED(isRTC);
#endif
{
LowPower_standby();
}
}

 

1 REPLY 1
Karl Yamashita
Lead III

Since this is Arduino drivers, you should be asking for help in the Arduino forum. 

In ST forums, you can ask for help on HAL and LL drivers.

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.