Mangy_Dog wrote: Wed Jul 31, 2024 9:23 am
Hmm good point, I've already tried shutting clocks down, but it seems deepsleep is already doing that anyway so it didnt make any difference.
Most of the pins are floating in this test code.
When you say shut down the GPIOs, what way do you mean? Setting to OUTPUT (non sinking mode) and pulling low? Set to float?
shutdown gpios has 2 possible steps, setting them to pinMode(pin, INPUT) is one, setting it to OUTPUT, if it is low it is sinking currents and if it is high it is sourcing currents, e.g. if you happened to have a resistor connecting VDD to the pin and it is OUTPUT (e.g. a pull up resistor) chances are that current is flowing. (e.g. the I2C pull up resistor)
The more extreme step is to un-clock the gpio subsystem, effectively shutting it down, this would be a bit extreme unless every microamp matters.
Also wouldnt disabling the various clocks effectively shutdown SPI i2c and uart? IE this code...
Code: Select all
void DeeperSleep (uint32_t timeMS)
{
//turning off as many clocks as possible before going to deep sleep. Needs reenabling when woken.
//Should help reduce sleep power consumption to the uA
__HAL_RCC_USART1_CLK_DISABLE();
__HAL_RCC_USART2_CLK_DISABLE();
__HAL_RCC_USART3_CLK_DISABLE();
__HAL_RCC_USART4_CLK_DISABLE();
__HAL_RCC_USART5_CLK_DISABLE();
__HAL_RCC_USART6_CLK_DISABLE();
__HAL_RCC_SPI1_CLK_DISABLE();
__HAL_RCC_SPI2_CLK_DISABLE();
__HAL_RCC_I2C1_CLK_DISABLE();
__HAL_RCC_I2C2_CLK_DISABLE();
__HAL_RCC_ADC1_CLK_DISABLE();
__HAL_RCC_TIM1_CLK_DISABLE();
__HAL_RCC_TIM3_CLK_DISABLE();
__HAL_RCC_TIM6_CLK_DISABLE();
__HAL_RCC_TIM7_CLK_DISABLE();
__HAL_RCC_TIM14_CLK_DISABLE();
__HAL_RCC_TIM15_CLK_DISABLE();
__HAL_RCC_TIM16_CLK_DISABLE();
__HAL_RCC_TIM17_CLK_DISABLE();
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE(); // might still be able to wake on EXT1 if switched off.
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOD_CLK_DISABLE();
__HAL_RCC_CRC_CLK_DISABLE();
__HAL_RCC_DMA1_CLK_DISABLE();
// Enter low-power sleep mode using LowPower library
LowPower.deepSleep (timeMS);
}
yes disabling the various clocks effectively *switch off* the entire subsystem, and you would need to setup clocks again and re-initialise every peripheral on resume / wakeup. It is practically *switch off* the whole system. This would help if your intended 'deep sleep' is practically *switch off* and a toggle e.g. 'switch on' is good as a full power cycle and initialize everything from scratch.
I'd use this if I intended to do 'soft' power off, i.e. press a toggle tactile button to power off, and toggle again to power on.
But that this can be useful in automation scenarios if that 'toggle on' has enough time for you to bootstrap from completely off to on and perhaps handle the event.
I'd guess a short cut to doing this is when waking up from deep sleep is to do a NVIC_System_reset() and practically 'reboot'
There is one thing you can use to keep state across resets, they are the backup registers, sram is cleared but that backup registers keep values.
some stm32 socs has backup memory which can store even more data.
my own habit with power is that if possible keep it running connected to power e.g. a usb phone charger.
if not use a large battery e.g. a usb power bank or lipo batteries
and to 'save power', I tend to place
at the bottom of loop(), that makes loop() run every millisecond and I've observed that the cpu/soc runs at a lower temperature, thus saving power, by simply doing this.
I tend to think 'deep sleep' etc is 'too much hassle' as one'd need to think about 'keeping state between standby/resets', it is easier to cause bugs that way.