[SOLVED] Unintended Connection to Particle When Waking From Sleep

All,

I have been struggling with this bug for a while so, I tool @ScruffR 's advice and pared down my application to a minimum to isolate the issue.

The full code is here: https://go.particle.io/shared_apps/5b76df09aebf32b40900091e

Context for the issue:

  • Electron with Firmware 0.8.0-rc4
  • System Mode is MANUAL
  • There is only one instance of Particle.connect() in my code
  • I am using finite state machine approach so I know where my code is running
  • After a timeout period, the Particle is sent to sleep and the Cellular modem is turned off - this works
  • Upon seeing an interrupt from the PIR sensor, the Particle wakes up - then the issue occurs

Even though there is only one instance of Particle.connect() AND that I am in MANUAL mode, the Particle does this weird thing:

  • The RGB led goes through this sequence: breathing white, flashing green, rapid cyan, breathing cyan, flashing green, solid blue and then off
  • I do not see anything transmitted on the console

Why is this happening? Any help would be appreciated.

Thanks, Chip

Do you disconnect from the cloud prior going to sleep?

If not, that's the expected behaviour. After wake the system is expected to put the device back into the connection state that was active before going to sleep.

I guess you are talking about a Photon (would be good to know tho')

While this shouldn't happen on Electrons, the immediate return to sleep state without any publishing is probably due to the lack of time between publish and sleep command.

@ScruffR,

Sorry, it is the Electron - should have mentioned that.

I have not been using the Particle.disconnect() command, just Cellular.off() I thought I saw a note from @rickkas7 that tearing town the whole stack was not needed. I will test this now.

Thanks for looking,

Chip

I see, I missed the setPowerState(2) calling Cellular.off()
However, can you try with 0.8.0.rc.9? If you are testing RC, you should do with the most recent.

@ScruffR,

OK, so I updated to 0.8.0rc-9 and added the Particle.disconnect() before Cellular.off()

I am still running into an issue with unexpected connections. Why is this doing when in MANUAL mode?

Here is the latest rev: https://go.particle.io/shared_apps/5b76efe6aebf32b409000bd5

One more thing, this unexpected connection is also blocking execution of the main loop. I don’t understand why we can’t ensure that the main loop will be serviced while the Electron goes through the 30+ second process of connecting to Particle.

Any help is appreciated.

Thanks,

Chip

Make sure you check Particle.connected() before you call Particle.publish(). If you call Particle.publish() while the cloud is enabled but not connected, the function will block until the cloud is actually connected.

1 Like

@rickkas7,

First of all, thank you for the article. I realized that I was indeed publishing before I checked Particle.connected()

However, even with this fix, I still see the same behavior:

  • despite being in manual mode and there only being one instance of Particle.connect() in the code, it still connects when a pin interrupt wakes it from sleep
  • It still goes though that weird sequence of LED flashes - blocking the code while it does

So, I don’t know why it is doing this and, since it blocks and expends significant energy in the process, this is a show stopper for my solar powered application.

Again, any help is appreciated. Current code here: https://go.particle.io/shared_apps/5b774176aebf321755001492

Thanks,

Chip

I think you need a delay(1000); after Cellular.off(). The problem is that in threaded mode Cellular.off() is non-blocking but there's no way to tell when it's actually done. If you go to sleep immediately the cellular state is recorded as on, because it hasn't been turned off yet, so it wakes, it goes back into on state.

This post is for SLEEP_MODE_DEEP but it shows some of the places you'll run into the same problems:

1 Like

@rickkas7,

The good news is that I am learning a lot today. The bad news is that adding the Cellular.on() and delays actually made the problem worse.

Could it have something to do with using a Particle.function() to set the lowPowerMode. This function returns an ERROR on the mobile app since it disconnects before it gets to return 1; .

I am grasping at straws here. This code is not doing what I would expect and I am not sure what to change.

Current version: https://go.particle.io/shared_apps/5b7748bdaebf3233ad0015eb

Thanks as always for your help!

Chip

You don’t need to add the Cellular.on() in your code. Just add the delay after the Cellular.off().

Also, yes, you should not go to sleep from a function handler. Set a flag in your function handler and go to sleep from loop().

3 Likes

@rickkas7,

OK, so I fixed that issue as you suggested. Still no joy.

I wanted to make it easier to get the the root of the problem so, I have reduced the code significantly and, over the weekend, did a number of tests to narrow the problem.

Here is the new reduced code: https://go.particle.io/shared_apps/5b79a47a8297fcf5f1000886

I have now identified the issue - it is the way that the Electron is handing sleep. In the code below, if I use System.sleep(int seconds); the code functions as expected. Once disconnected, it will not reconnect until you clear the lowPowerMode flag. However, if you use System.sleep(intPin, RISING, int seconds); you get the unexpected behavior: the Electron will attempt to connect to Particle without any instructions in code to do so.

Based on a suggestion from @ScruffR, I also tried detaching the interrupt before sleep and reattaching after, this had no effect so I took it out of the code to keep it down to a one line change.

I think this may be a flaw in the firmware.

Please take a look. I will open a help desk ticket on this issue Monday.

Thank you and @ScruffR for taking a look.

Chip

1 Like

All,

Thanks to @rickkas7, this issue has been solved. It turns out that, even in MANUAL mode, the Electron will attempt to restore the connection state when it wakes from Sleep. So, the fix is to insert a Particle.disconnect() line before Cellular.off() so the Electron knows it will be in disconnected mode. Please see example code below, commenting out the Particle.disconnect() line will demonstrate the issue.

@rickkas7 is going to ensure that the documentation is updated to better explain this behavior.

Here is the final sample code - no hardware or sensors required:slight_smile:

// Minimal code to display weird connection behaviour

// By weird behaviour, I mean the Electron connecting to the Particle cloud when there is 
// no reason to do so.  I have isolated this issue to the Sleep command

// Prototypes and System Mode calls
SYSTEM_MODE(MANUAL);                                            // This will enable user code to start executing automatically - OR SO WE ARE TOLD! ;-)
SYSTEM_THREAD(ENABLED);                                         // Means my code will not be held up by Particle processes.

const int blueLED = D7;

void setup()                                                    // Note: Disconnected Setup()
{
  pinMode(blueLED,OUTPUT);    
  pinMode(D3,INPUT_PULLDOWN);
    
  Particle.connect();                                           // Connects to Particle
  waitUntil(Particle.connected);
  Particle.process();                                           // Since we are in Manual mode, we need to process
  
  Particle.disconnect();                                        // This is the fix - Electron wants to restore connected state after waking
}

void loop()
{
  pinSetFast(blueLED);
  delay(1000);                                                  // Delay to rate limit loop and publishes
  
  Cellular.off();
  delay(1000);                                                // Advice from Rickkas - https://community.particle.io/t/electron-sleep-problems-yet-again/42230/11
  System.sleep(D3,RISING,30);                             // If we use this line instead, the Electron will attempt to connect to Particle on every interrupt 

  pinResetFast(blueLED);
  delay(1000);
}

Chip

2 Likes

@chipmc, I think the other way of looking at it is that the Electron will restore the state of the Cloud connection prior to it going to sleep, regardless of the SYSTEM_MODE. In your case, since the Cloud connection was still active, it restored it upon rebooting. @rickkas7, can confirm this.

2 Likes