Turning off the photon if WiFi is not available

Hello,

I’ve looked over all of the reference documents but I have not been able to find this information anywhere.

I’m working on a project deploying over 100 photons and their operation is very simple.

Once a day they wake up from Deep Sleep and send out a bunch of information to a server and then go back to deep sleep for another day. Now sometimes i have noticed that when the photon wakes up it is not able to find the WiFi it is supposed to connect to and blinks green until it dies(It is connected to a battery - FYI). I was wondering if it is possible for me to set the photon back to deep sleep mode if the photon is not able to connect to the WiFi after a certain amount of time has passed ?

Thanks guys

Then you might want to look again :wink:

https://docs.particle.io/reference/firmware/photon/#waiting-for-the-system

1 Like

Here’s a sample program that uses SYSTEM_THREAD(ENABLED) to do that:

#include "Particle.h"

// Simple test of using System.sleep(SLEEP_MODE_DEEP, 30). This halts execution of your code, and when it
// wakes up again, it goes through setup() again with all variables cleared.

const unsigned long MAX_TIME_TO_CONNECT_MS = 30000;

// This is required, otherwise loop() won't run until you're connected to the cloud
SYSTEM_THREAD(ENABLED);

void setup() {
	Serial.begin(9600);
}

void loop() {
	// If you only need wifi, use WiFi.ready() instead of Particle.connected()
	bool ready = Particle.connected();

	bool sleepNow = false;

	if (ready) {
		// This delay is to allow the connection to fully get established and stable.
		// If you going to do some calculations first, you can probably omit this.
		delay(2000);

		// Put actual code here for what you want to do when waking up
		Serial.println("publishing awake event");
		Particle.publish("sleeptest", "awake", PRIVATE);

		// This delay is to give time for the publish to go out. This can probably be shorter.
		delay(1000);
		sleepNow = true;
	}
	else {
		// Have not connected to the cloud yet
		if (millis() > MAX_TIME_TO_CONNECT_MS) {
			Serial.println("took too long to connect to WiFi, going back to sleep");
			sleepNow = true;
		}
	}

	if (sleepNow) {
		Serial.println("calling System.sleep(SLEEP_MODE_DEEP, 30)");
		delay(2);

		System.sleep(SLEEP_MODE_DEEP, 30);

		// This code will never be reached, after waking up, setup() will be called then loop()
	}
}


@rickkas7, that seems overly complicated when waifFor() could be used instead as @Moors7 pointed out :

const unsigned long MAX_TIME_TO_CONNECT_MS = 30000;


void loop() {
  if (!waitFor(Particle.connnected, MAX_TIME_TO_CONNECT_MS) {
    // timeout occured go back to deep sleep
    System.sleep(SLEEP_MODE_DEEP, 30);
  }

  // Connection established 
  // ...
}

I use SYSTEM_MODE(SEMI_AUTOMATIC) so I control the connection. In some cases, if Particle.connect() fails, I run Particle.disconnect(), wait a small delay then run Particle.connect() and test for the connection again. If that retry fails, then I go back to sleep.

I do all data collection BEFORE trying to establish the connection, storing data on an SD or in retained RAM. That way if a timeout occurs, I can send it on the next successful connection. :wink:

1 Like

Just a side note on waitFor() (which got pointed out to myself a while back):
In order to get a reliable timeout time you should use SYSTEM_THREAD(ENABLED).

1 Like

Hi. I have the SAME use case. Have some Photons deployed in a location where sometimes they can connect to wifi and sometimes, intermittently, they just can’t. they are just at the edge of the range. Trying to get this code working, but have some problems/questions.

  1. Does Particle.connected() try to connect if the initial answer is false?

here’s why I ask. It appears that Particle.connect() does not return a value. And WaitFor wants a function that returns a value (that’s what I’m surmising from my results).

Here’s the stripped down code I’m trying:

SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

void setup() {
}

void loop() {
    while ( !Particle.connected() ) {
        waitFor(Particle.connect(), 10000);
        if (! Particle.connected) {
            System.sleep(SLEEP_MODE_DEEP, 30);
        }
    }
}

The waitFor lines generates error:

/workspace/manual_wifi.cpp:9:34: error: void value not ignored as it ought to be
 void setup() {

I’ve tried a few versions of the code. I want to set up a timeout so that the device can go to sleep if it can’t connect. Any help? Thanks in advance

You should not be passing the function result but the function pointer like this

Particle.connect();
waitFor(Particle.connected, 10000);

But in this case, you must check the function result

if (! Particle.connected()) 

But actually I'd rewrite your code like that

void loop() {
  if( !Particle.connected() ) {
    Particle.connect();
    if ( !waitFor(Particle.connected, 10000) ) {
      System.sleep(SLEEP_MODE_DEEP, 30);
    }
  }
}

BTW, the error message you got means, that you are using the return value of a void function (void connect()) which is non-existent and hence forbidden.

2 Likes

Thank you. That works for me.