0

I used to have a project on arduino using the atmega328p chip with this code:

// used for deep sleep
#include <avr/wdt.h>

static void go_to_sleep_and_power_down_and_wake_up_again_in_2_seconds()
{
    // wake up again in 4 seconds
    wdt_enable(WDTO_4S);

    // go to deep sleep    
    {
        // BIG difference when in sleep
        // Diable ADC (analog to digital converter)
        ADCSRA &= ~(1 << 7);

        SMCR |= (1 << 2); // power down mode
        SMCR |= 1;        // enable sleep;

        // BOD DISABLE (big difference when in sleep only)
        MCUCR |= (3 << 5);                      // set both BODS and BODSE at the same time
        MCUCR = (MCUCR & ~(1 << 5)) | (1 << 6); // then set the BODS bit and clear the BOSE bit at the same time

        __asm__ __volatile__("sleep");
    }

    // this line should not execute
}

void setup()
{
    // init code...

    // read sensor value
    // pseudo code:
    if(valueReadFromSensor == 0)
    {
        turnOnAlarm();
        return;
    }

    go_to_sleep_and_power_down_and_wake_up_again_in_2_seconds()
}

void loop(){
   // not used
}

The code is very simple, once it wakes up it reads data from a sensor and goes back to sleep. After 2 seconds it wakes up again and repeats the same process.

How can I do the same thing on stm32 on the bluepill for example? I have managed to go to standby mode using this function HAL_PWR_EnterSTANDBYMode();. But how can I enable waking up again in 2 seconds for example?

Edit

I have tried this sources:

uses an old version of stm32 cube ide and different board. I tried the video doing the same steps and some defines make the code unable to compile. https://www.youtube.com/watch?v=zQ1sT9fjd3E

does not have code https://www.stm32duino.com/viewtopic.php?t=922

does not have code STM32 wake up from standby by RTC

I am not using freeRtos https://electronics.stackexchange.com/a/562120/56969

Tono Nam
  • 34,064
  • 78
  • 298
  • 470
  • Possibly helpful discussion: https://www.stm32duino.com/viewtopic.php?t=922 – enhzflep Sep 08 '21 at 01:25
  • I'm not sure if there is a 1:1 match in capability, but what I do with TI MCUs is save the current active power state before entering the program loop. At the end of the program loop I put the MCU to sleep. To trigger a wakeup, I set an interrupt to trigger on 10 secons and in the interrupt handler restore the MCU to the prior active power state which forces the program loop to execute again (going to sleep again at the end of the program loop). This is a common strategy that allows keeping the ISR functions small, essentially just setting flags to trigger processing in the main loop. – David C. Rankin Sep 08 '21 at 01:36
  • This looks like what you want [STM32 wake up from standby by RTC](https://stackoverflow.com/q/42205997/3422102) -- or close. – David C. Rankin Sep 08 '21 at 01:48

1 Answers1

1

Finally found a solution using IWDG. This code works for PlatformIO using the arduino framework

#include <Arduino.h>
#include <IWatchdog.h> // <----------- needed

void setup(void)
{
    // start serial
    Serial.begin(115200);

    // set pins
    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(A0, INPUT_PULLUP); // connect button to this pin to simulate a sensor for purposes of this example.

    // flash led to indicate board is starting
    Serial.println("starting...");
    digitalWrite(LED_BUILTIN, HIGH);
    delay(250);
    digitalWrite(LED_BUILTIN, LOW);

    // read value from sensor. In this case just tell if button is presses
    // connect one side of button to pin A0 and the other to ground
    int sensorValue = digitalRead(A0);

    // if button is not pressed
    if (sensorValue == 1)
    {
        // go to sleep and try again in 4 seconds
        Serial.println("going to sleep and trying again in 4 seconds...");

        // Initialize the IWDG with 4 seconds timeout.
        // This would cause a CPU reset if the IWDG timer
        // is not reloaded in approximately 4 seconds.
        IWatchdog.begin(4000000);

        // go to sleep
        HAL_PWR_EnterSTANDBYMode();

        Serial.println("This line should NOT print!!!!!");
    }


    // at this point it means the button is was pressed
    Serial.println("staying awake!");
    // stay awake flashing led
    while (true)
    {
        digitalWrite(LED_BUILTIN, HIGH);
        delay(50);
        digitalWrite(LED_BUILTIN, LOW);
        delay(50);
    }
}

void loop()
{
}

This video explains how to have the same using stm32CubeIDE: https://www.youtube.com/watch?v=AelNsnpfbcM&t=472s

Tono Nam
  • 34,064
  • 78
  • 298
  • 470