We have a device that every 2-ish minutes wakes up, listens for a bluetooth beacon (using the BeaconScanner library) and goes into sleep again using ULP.
However, we see that on wakeup (no function after System.sleep is executed), the device hangs in an idle state until the HW watchdog restarts the device. It can be seen on the power consumption below:
All the small peaks are when the devices wakes up, measures for a couple of seconds and goes to sleep again. However, you can see that the device wakes up, never does anything until the hardware watchdog resets and it starts connecting again (the big power consumption peak)
We are using
SYSTEM_MODE(SEMI_AUTOMATIC); // Semi-automatic mode for controlling connectivity manually
SYSTEM_THREAD(ENABLED); // Separate System Thread Enabled
The sleep function is as below:
void Class::measurementSleep(int measurementDelay, std::chrono::seconds measurementSleepTime, bool hallEnabled)
{
Class::instance().setPanicCode(234);
// Initialize Power Configuration
SystemSleepConfiguration measurementSleepConfig;
// Power Configuration using ULTRA_LOW_POWER, HALL_PIN for restart and compensated sleep duration - SystemSleepMode::ULTRA_LOW_POWER
measurementSleepConfig.mode(SystemSleepMode::ULTRA_LOW_POWER).duration(Class::instance().getCompensatedSleepTime(measurementDelay, measurementSleepTime));
// Set error code
Class::instance().setPanicCode(216);
if (hallEnabled)
{
measurementSleepConfig.gpio(IOConstants::HALL_PIN, CHANGE);
}
Class::instance().setPanicCode(217);
// Handle network standby for cellular interface based on constants or time limit
if (Class::instance().getNetworkStandby()) // (measurementSleepTime.count() * Class::instance().getNumberOfMeasurements()) < CloudConstants::NETWORK_STANDBY_LIMIT)
{
classLogger.info("Setting network to standby");
measurementSleepConfig.network(NETWORK_INTERFACE_CELLULAR, SystemSleepNetworkFlag::INACTIVE_STANDBY);
}
// Ensure onboard peripherals are put to sleep before sleeping device
ClassPower::instance().sleepFuelGauge();
Class::instance().setPanicCode(218);
// Do one last system/watchdog checkin
Class::instance().systemCheckin();
classLogger.info("Going to sleep...");
// Execute SystemSleepConfiguration and enter sleep
Class::instance().setPanicCode(219);
SystemSleepResult result = System.sleep(measurementSleepConfig);
Class::instance().setPanicCode(220);
// If device was woken up due to hall effect being triggered
if (result.wakeupReason() == SystemSleepWakeupReason::BY_GPIO)
{
Class::instance().setPanicCode(268);
classLogger.info("Device was woken up by hall effect sensor");
// Hall sensor was triggered during sleep, so let's restart! or should we use resetPending and compile all measurements beforehand?
System.reset(RESET_APP_ENUM::HALL_MEASUREMENT_SLEEP, RESET_NO_WAIT);
// set pending, transmit measurements and restart?
}
Class::instance().setPanicCode(273);
}
We recieve the panic/error code 219, which means it never gets to after the System.sleep (i.e. error code 220).
Any idea on what goes wrong?