i am looking for the simplest way to put the autonomo to sleep for 5 - 10 seconds, wake up, check some sensors, output information via SerialUSB then go back to sleep etc in continuous loop. I have seen a few examples e.g https://support.sodaq.com/sodaq-one/sara/ (adapted for autonomo) and AUTONOMO RTCZero wake-up/sleep cycles and another making use of rtc.standby() from the RTCzero library but they all seem to disable the USB which means they seem to fail when output data to SerialUSB.
I do not require huge power saving, just drop the power consumption a bit but i need access to SerialUSB.
Any help is much appreciated.
For the timing element, you need something which will generate an interrupt to wake the board from sleep after the desired amount of time the device will sleep for. You can use the RTCZero library, but that will limit you to minute resolution.
Alternatively, I recently released this library which allows for second level resolution: https://github.com/GabrielNotman/RTCCounter
USB output and sleep don’t mix well on the SAMD21. The USB element requires a high frequency clock which in turns uses a lot of power. I’m not sure how or if it is possible to run the USB in a lower powered mode.
It is possible to properly disconnect the USB from the host, and then reconnect after waking up, however, this results in the device ending any open session with the host. e.g. If you have a COM / TTY port open and you are logging the output from the device, the port will be closed every time device enters sleep mode. This is unusable for logging unless the logging software has a method of auto reconnecting.
A better alternative would be to redirect the output from SerialUSB to one of the UARTs. Then connect that UART to the host via a UART to USB device such as the UARTSbee. https://shop.sodaq.com/uartsbee.html
This is also desirable as it is possible to log when the device is reset for any reason.
The data sheet indicates that as well as the standby mode there are also three idle modes; the idle modes seem to allow the main clocks to keep running so the USB shouldnt be affected? Is it possible that your new RTCCounter library could be used to put the sand21 into idle mode?
Also, is it possible to reduce the core freq of the cpu (“on the fly”) as a means of reducing power consumption? For example when a logger goes in to non-burst mode.
Can Your RTCCounter library enable USB after wakeup?
Any help is much apreciated.
There is a lot you can do with the clocks on a Cortex M0+ MCU, however, this is far from trivial. Additionally, I have not seen any example where the main clock is adjusted on the fly (other than stopping it to enter sleep).
The RTCCounter library does not provide any power management functionality. That is outside the scope of the library which is design to provide a timing functionality.
On p124-125 of the datasheet, Tables 15.3 and 15.4 provide the information about the idle modes.
You can control the idle level or deep sleep with the following:
You will need to set the following bit to enable deepsleep, and clear it for any of the idle modes:
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
Additionally, the idle level can be set using:
PM->SLEEP.bit.IDLE = PM_SLEEP_IDLE(2); // Idle 2
I’m not sure if what effect these modes will have on the USB component. Also even if the device resumes the USB connection after waking up from an idle state, you will likely lose connection to the device unless you are running software (terminal or logger) which can auto-reconnect.
You can switch off the USB before entering sleep with this:
Just be careful as you may have to do other tests to see if the USB is currently attached/connected.
Additionally, you can for a resume after waking up with:
USB->DEVICE.CTRLB.bit.UPRSM = 0x01u;
Again this might cause issues if you aren’t connected as I believe it will wait until a connection with a host is established.