arduino-nRF5
arduino-nRF5 copied to clipboard
High Current sleep due to millis() after ~8.5mins
Note: This issue was found in my modification of this package which added a low power timer and other low power methods see https://www.forward.com.au/pfod/BLE/LowPower/index.html. In those mods RTC1 is used for the lp_timer and RTC2 is used for millis()
The following trivial sketch would hang after ~8.5mins and go into a high current mode ~5mA to 8mA.
const int IND = 3; // for nanoV2
boolean check = false;
lp_timer seqTimer;
const unsigned long SEQ_TIME = 10; // min time interval is 2mS
void setup() {
pinMode(IND, OUTPUT);
digitalWrite(IND, check);
seqTimer.startTimer(SEQ_TIME, stateMachineInit);
}
void loop() {
sleep(); //<< calls sd_app_evt_wait();
}
void stateMachineInit() {
check = !check;
digitalWrite(IND, check);
}
The initial 'fix' was to disable millis(), the RTC2 (in wiring.c) Then every thing worked.
The final 'fix' was to move the millis() counter to the lp_timer counter RTC1.
The problem seems to be that the overflow flag is not being cleared resulting in a tight loop repeatedly calling the RTC2 interrupt handler.
The problem does not occurre in more complex programs. I have a temperature humidity sensor that has been running for weeks without issue.
The existing RTC1 interrupt handler (actually RTC2 in my mods) code includes the suggested NORDIC fix for delayed data writes
void RTC2_IRQHandler(void) {
NRF_RTC1->EVENTS_OVRFLW = 0;
#if __CORTEX_M == 0x04
volatile uint32_t dummy = NRF_RTC1->EVENTS_OVRFLW;
(void)dummy;
#endif
overflows = (overflows + 1) & 0xff;
}
But for whatever reason this NORDIC fix did not work in this simple program. I tried adding a simple delay_us(50) to the end of RTC2_IRQHandler but this did not fix the problem. It seems there needs to be some other data accesses to force the update. The lp_timer interrupt has a function call at the end that accesses more data structures.