Put Argon to Sleep and Wake up with wifi

Hi,

I’m having trouble figuring out how to properly put my argon to sleep but receive get requests. Essentially, I want to save as much battery as possible and when needed to, wake up and power and led from a request (in the form of a GET currently) to turn the led on or off. I cant seem to see any examples/docs on how to do this? Below is my code, but I get a request timeout as it seems the request isn’t waking up the argon

int led1 = D6;
bool is_on = false;

void setup() {
    // turn off the main led to save battery
    RGB.brightness(0);
    
    pinMode(led1, OUTPUT);
    Particle.function("led", ledToggle);
}

void loop() {
    SystemSleepConfiguration config;
    config.mode(SystemSleepMode::STOP)
          .network(NETWORK_INTERFACE_WIFI_AP)
          .flag(SystemSleepFlag::WAIT_CLOUD);
    System.sleep(config);
}


int ledToggle(String command) {
    is_on ^= 1;
    
    digitalWrite(led1, is_on);
    return is_on ;
}

I believe you need to use NETWORK_INTERFACE_WIFI_STA (station) not AP (SoftAP, access point mode). The AP mode isn’t supported on the Argon at this time.

hey ricckas thanks for your reply. It seems like when I do that, the light on my argon flashes as if its sleeping and waking constantly. Also it continues to publish every second to the console. So it seems like its not sleeping at all. Here is my new code

int led1 = D6;
bool is_on = false;

void setup() {
    pinMode(led1, OUTPUT);
    Particle.function("led", ledToggle);
}

int counter = 0;
void loop() {
    SystemSleepConfiguration config;
    config.mode(SystemSleepMode::STOP)
        .duration(15min)
        .network(NETWORK_INTERFACE_WIFI_STA);

    System.sleep(config);
	Particle.publish("awake");
	delay(1000);
}


int ledToggle(String command) {
    is_on ^= 1;
    
    digitalWrite(led1, is_on);
    return is_on;
}

EDIT: also if i try to hit that endpoint to toggle the light after a few times, the light on the argon will go out and the led will be stuck on the position it was set to. All further requests will timeout

So I’ve tried this with 2 different boards and it won’t stay asleep. If I do a normal stop mode or use BLE it stays asleep. Otherwise it keeps waking instantly. Are these just bad boards?

EDIT: it looks like os 2.0 and up theres a bug with this…

On 1.5.0 using Particle.function() will not immediately wake the device, but will at least stay asleep and sometimes alter the values (but always timeout from the client side). I flashed a second argon with the same os and firmware and behaves differently. This seems inconsistent and buggy. The fact that I need to downgrade to os 1.5 is strange considering were at 3.0…

Also I assumed it would wake up after calling Particle.Function() does not happen. After a duration timeout it will update the values I changed in said function, which also seems weird according to the docs

Hopefully I’m just missing something here

For that assessment we'd need to see what your Particle.function() does.
Since it's a two-way communication it's not unusual that the function call succeeds but the response from the device to inform the cloud of the outcome of that request may be too slow and you get the respective timeout error.
It's not a timeout of the actual request but just the missing response for that request (the only thing the cloud side can check for).
For instance, when you have a delay(5000) in your function you'll always get a timeout as you only have about 3 seconds (including transport latencies either way) for the response to arrive at the calling server.
Hence
https://docs.particle.io/reference/device-os/firmware/argon/#particle-function-

Hi ScruffR,

Thanks for taking the time to help me here. So my function is lightweight, it actually runs perfectly when I’m not sleeping every time. I don’t think you can get much faster than these two examples (ive tried a POST and GET)
Example 1:

bool ledToggle()
{
  is_on ^= 1;
  digitalWrite(led, is_on);
  return is_on;
}

Example 2:

bool ledToggle()
{
  is_on ^= 1;
  return is_on;
}

on OS 1.5.2:
I went ahead and decided to see what was the wake reason and every time in STOP it is RTC as my duration times out and never NETWORK.

I also tried ULTRA_LOW_POWER and it can’t even stay asleep with just an UNKNOWN as its wake reason

It seems like it won’t even respond to anything network related as a wake reason

on OS 2.0.1:
STOP and ULTRA_LOW_POWER keep waking up and going back to sleep constantly as a network wake up reason and I’m not sending anything to it. It simply won’t stay asleep at all

|Status|network|lite-2|3/14/21 at 12:08:52 pm|
|Status|network|lite-2|3/14/21 at 12:08:51 pm|
|Status|network|lite-2|3/14/21 at 12:08:51 pm|
|Status|network|lite-2|3/14/21 at 12:08:51 pm|

You can see how fast these logs are coming in for network wake reason. My sleep looks like this:

  SystemSleepConfiguration config;
  config.mode(SystemSleepMode::STOP)
      .network(NETWORK_INTERFACE_WIFI_STA)
      .flag(SystemSleepFlag::WAIT_CLOUD)
      .duration(15min);

  SystemSleepResult res = System.sleep(config);

Hmm, this does not look like a Particle.function() callback.

For Particle.function() you'd either use a int foo(String arg) or int bar(const char* arg) function.
Or are you using your functions rather for Particle.variable()?

The sleep topic I'd rather leave with Rick as I'm personally not convinced it's fully matured yet :see_no_evil:

Hello ScruffR,

I am having the same issue josephp27 was having. Some months passed but the new releases does not fix this problem. I have tested it with 3.1.0 and 3.2.0-rc.1, but I still have the device sleeping and waking up constantly. It stays in sleep mode for less than a second before it wakes up for no reason. Of course I am not calling any function, reading any variable or doing anything to wake it up.

    SystemSleepConfiguration config;
    config.mode(SystemSleepMode::ULTRA_LOW_POWER)
        .network(NETWORK_INTERFACE_WIFI_STA)
        .flag(SystemSleepFlag::WAIT_CLOUD);

    System.sleep(config);

I’m not as proficient in the new sleep features of Gen3 so I’d rather leave this to @rickkas7 to address.

Hello @tiznadoo and @josephp27,
I have been battling with exactly this issue too. I have been using code which is in effect the same as that posted by tiznadoo. I have discovered that the WiFi is kept awake by general chatter/trafffic on the network. I have not tried to analyse exactly what is being sent on the network (for example with Wireshark).

However I have found that if I set up a dedicated WiFi network with only my Argon connected to it, then the sleep successfully works - it will stay asleep (ULP with status LED off) and I can reawaken the device by calling any Particle.function from the cloud Console which sends a packet to trigger the wake.

Could Particle look at ways to filter the network wake to only respond to certain packets, addresses, etc.? Possibly with an API extension to let developers configure the filter parameters.

I hope this helps.

1 Like