adafruit / Adafruit_nRF52_Arduino

Adafruit code for the Nordic nRF52 BLE SoC on Arduino
Other
610 stars 494 forks source link

waitForEvent() not working as expected #637

Open czuvich opened 3 years ago

czuvich commented 3 years ago

Describe the bug I'm trying to put the nRF52840 to sleep in the SYSTEM_ON state using the waitForEvent() method. When I call the waitForEvent(), the sketch just keeps running.

As an alternative, I looked at suspendLoop() and resumeLoop(); however, those calls have no effect on the power consumption of the uC. I do see a SYSTEM_OFF api which would work, but I was looking for something that would work in SYSTEM_ON state.

Set up (mandatory)

I included a small sketch showing different paths I've tried, but to no avail.

#include <bluefruit.h>

SoftwareTimer _timer;

void setup() {
  Serial.begin(115200);
  Bluefruit.begin();

  _timer.begin(3000, wakeup_timer_callback, NULL, false);
}

uint32_t count = 0;
void loop() {
  digitalWrite(LED_RED, HIGH);
  delay(1000);
  digitalWrite(LED_RED, LOW);
  delay(1000);
  ++count;
  if (count >= 3) {
    _timer.start();
    count = 0;
    suspendLoop();
    //suspendLoop();
    //waitForEvent();

    //count = 0;
    //suspendLoop();
  }

}

void wakeup_timer_callback(TimerHandle_t xTimerID) {
  resumeLoop();
}
JustDoinGodsWork commented 1 year ago

Hello, any update on how to keep nRF52 SoC on System-on sleep mode? I need to do the same.

84ace commented 1 year ago

This script below, based on yours, works as I would expect:

#include <bluefruit.h>
#include <Adafruit_TinyUSB.h> // required for USB Serial

SoftwareTimer _timer;

void setup() {
  Serial.begin(115200);
  Bluefruit.begin();

  _timer.begin(3000, wakeup_timer_callback, NULL, false);
}

uint32_t count = 0;
void loop() {
  digitalWrite(4, HIGH);
  delay(1000);
  digitalWrite(4, LOW);
  delay(1000);
  ++count;
  Serial.print("count: "); Serial.println(count);
  Serial.print("milllis1: "); Serial.println(millis());
  if (count >= 3) {
    _timer.start();
    Serial.print("milllis2: "); Serial.println(millis());
    suspendLoop();
    Serial.print("milllis3: "); Serial.println(millis());
    Serial.println();
  }
}

void wakeup_timer_callback(TimerHandle_t xTimerID) {
  resumeLoop();
  count = 0;
  Serial.print("milllis4: "); Serial.println(millis());
}

output:

count: 1
milllis1: 2562
count: 2
milllis1: 4562
count: 3
milllis1: 6562
milllis2: 6562  << 
milllis4: 9562  << 3 seconds between
milllis3: 9562

count: 1
milllis1: 11562
count: 2
milllis1: 13562
count: 3
milllis1: 15562
milllis2: 15562
milllis4: 18562
milllis3: 18562

and then by changing

_timer.begin(3000, wakeup_timer_callback, NULL, false);

to

_timer.begin(10000, wakeup_timer_callback, NULL, false);

I get this output:

count: 1
milllis1: 2559
count: 2
milllis1: 4559
count: 3
milllis1: 6559
milllis2: 6559
milllis4: 16559
milllis3: 16559

count: 1
milllis1: 18559
count: 2
milllis1: 20559
count: 3
milllis1: 22559
milllis2: 22559  <<
milllis4: 32559  << 10 seconds between
milllis3: 32559
jibarra64 commented 9 months ago

Any resolution? The only way I have been able to use the waitForEvent() function is by disabling all interrupts with either __sd_nvic_irq_enable() or __disable_irq().

I need an external interrupt to wake from the waitForEvent() and manually disabling the interrupts individually with sd_nvic_DisableIRQ(IrqNumx) appears to have no effect.