Particle.disconnect()... gracefully or not?

Hi -

Referring to my brief ‘sleep function’ below"

void Sleep() {

Particle.disconnect(CloudDisconnectOptions().graceful(true).timeout(5000));       // Use only in SEMI_AUTOMATIC mode
digitalWrite(GSM_Reg_EN, LOW);
delay(50);

SystemSleepConfiguration config;
config.mode(SystemSleepMode::ULTRA_LOW_POWER)
    .duration(10min);
      
System.sleep(config);
}

I am running in Semi-Automatic mode as I only want to connect to cellular when data has changed. After data has been published I want to disconnect and turn of the regulator powering the B524 cellular modem (GSM_Reg_EN in code)

The code above does the job, BUT… after disconnecting and turning off the regulator, it takes quite a long time (maybe 1-2 minutes) to enter sleep mode. Would appreciate it someone can point out what I am doing wrong?

Regards,
Friedl.

You definitely do not want to turn off the power to the modem that way.

You should just let the sleep code power off the modem gracefully. It’s likely that the reason it takes so long is that sleep is trying to communicate with the the modem and it’s timing out because you turned it off.

Abruptly turning off the power to the modem is likely to eventually cause it to be permanently damaged, particularly with devices with SARA-R410M modems. If you remove the power when the modem is doing housekeeping it can permanently corrupt the modem internal flash and there is no way to recover the device.

1 Like

Hi @rickkas7

Thank you for the response. I know I was doing something stupid :sweat_smile: As I want to turn the power to the regulator off as well (trying to preserve as much battery life as possible) can I set the pin to low AFTER the sleep function then?

void Sleep() {

Particle.disconnect(CloudDisconnectOptions().graceful(true).timeout(5000));       // Use only in SEMI_AUTOMATIC mode
delay(50);

SystemSleepConfiguration config;
config.mode(SystemSleepMode::ULTRA_LOW_POWER)
    .duration(10min);
      
System.sleep(config);

digitalWrite(GSM_Reg_EN, LOW);
}

Regards, Friedl.

Unfortunately no, because the the line after System.sleep won’t be executed until after you wake.

In your case you’ll need to do something like:

  • After Particle.disconnect() wait until Particle.disconnected() is true. The call is asynchronous, so you can’t just wait a fixed amount of time.
  • Then use Cellular.off() and wait for Cellular.isOff().
  • Then you can turn off your regulator
  • Then sleep normally

After waking up from sleep, the line after System.sleep(), reverse the process:

  • Turn on the regulator
  • Call Cellular.on() and wait for Cellular.isOn()
  • Call Particle.connect()
3 Likes

Hi @rickkas7

Ih my.... of course :face_in_clouds:

Thanks, I will change the code and test. If it works I will publish it here in case anyone else is having a slow day :grin:

Many thanks!

Regards,
Friedl.

@friedl_1977 ,

Over the years, this issue has been a constant source of issues for my sleepy devices. I have an over-engineered but effective function to absolutely positively make sure the device is disconnected from Particle and Cellular and that the cellular modem is off. Happy to share if you like.

Chip

3 Likes

Hi @chipmc -

Always happy to receive help! I have some code that seems to be working, but as these devices will be going into remote areas (and I hate call-outs and comebacks) it would be good to have reliable code. especially since I am very new to coding - still get excited blinking a LED :sweat_smile: -

Regards, Friedl.

@friedl_1977 ,

Yes, my devices are in remote places as well. I don’t have the option of physically resetting them so, over time and with a lot of help from this community, I have been improving their resiliency. One other thing that has been a big help is Particles Long Term Support (currently 4.x.x) releases. As tempting as the new features in the 5.x.x releases are, I have prioritized stability and have not been disappointed.

Here is the (somewhat over engineered) call I make when I disconnect from particle. I place a premium on ensuring a complete disconnect as the next step is typically to sleep and you won’t get the lowest energy consumption if this process is not complete. If the function returns false, consider resetting (or ideally power-cycling the device) before sleep.

bool disconnectFromParticle()                      							// Ensures we disconnect cleanly from Particle
                                                                       		// Updated based on this thread: https://community.particle.io/t/waitfor-particle-connected-timeout-does-not-time-out/59181
{
  time_t startTime = Time.now();
  Log.info("In the disconnect from Particle function");
  Particle.disconnect();                                               		// Disconnect from Particle
  waitForNot(Particle.connected, 15000);                               		// Up to a 15 second delay() 
  Particle.process();
  if (Particle.connected()) {                      							// As this disconnect from Particle thing can be a·syn·chro·nous, we need to take an extra step to wait, 
    Log.info("Failed to disconnect from Particle");
    return(false);
  }
  else Log.info("Disconnected from Particle in %i seconds", (int)(Time.now() - startTime));
  // Then we need to disconnect from Cellular and power down the cellular modem
  startTime = Time.now();
  Cellular.disconnect();                                               // Disconnect from the cellular network
  Cellular.off();                                                      // Turn off the cellular modem
  waitFor(Cellular.isOff, 30000);                                      // As per TAN004: https://support.particle.io/hc/en-us/articles/1260802113569-TAN004-Power-off-Recommendations-for-SARA-R410M-Equipped-Devices
  Particle.process();
  if (Cellular.isOn()) {                                               // At this point, if cellular is not off, we have a problem
    Log.info("Failed to turn off the Cellular modem");
    return(false);                                                     // Let the calling function know that we were not able to turn off the cellular modem
  }
  else {
    Log.info("Turned off the cellular modem in %i seconds", (int)(Time.now() - startTime));
    return true;
  }
}

If anyone has ideas on how to make this better - please chime in.

Hope this helps,

Chip

2 Likes

Chip, it’s always nice to see code from other people, thank you for sharing stuff with the community.

2 Likes

Hi @chipmc -

Thank you for the comprehensive feedback and the code. I will be sure to implement it and let you know wether I was successful :slight_smile:

I am just finishing a design for a client, should get this over the weekend and will be good time to put it to the test then. I implemented the code to only publish when criteria is met and that seems to work, so adding should give me a good basis.

I am running 4.0.2 on this device if I recall correctly.

thanks again, really appreciate it!!
Friedl.

1 Like

Indeed!

I just think Particle should highlight mine BRIGHT RED label clearly DO NOT USE :sweat_smile: :sweat_smile: :sweat_smile:

3 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.