Can a photon boot without WiFi?

Just moved to a new place today, but the at&t won’t be hooked up until next week. My dryer isn’t working, the photon keeps blinking green (that’s looking for WiFi, right?). Will it eventually boot without WiFi or am I stuck without a clothes dryer until att hooks us up?

Thanks,
JR

In the default mode (AUTOMATIC), the user code will only run when wifi is connected.

You can attempt to create the same Wifi SSID and password using your mobile hotspot and then modify the code to work without wifi first.

Let us know if you need help!

I have an example here: https://github.com/kennethlimcp/particle-examples/blob/master/wifi-auto-reconnect/wifi-auto-reconnect.ino

2 Likes

Hey kenneth, I tried adding your code to my own, but now it takes several seconds -minutes to register button presses. Will the photon run with just WiFi.off()? If so, how do I update it later?

If you use WiFi.off() you will have to manually place it in dfu mode to flash firmware.

Can you paste your code in a gist and share the link so that we can see why the button presses are taking so long to register?

First time using a gist, let me know if it works/doesn’t

Also Safe Mode and OTA flash would be possible (if a WiFi network is available and credentials are set too).

Try using Piettetech_DHT library instead of Adafruit_DHT (which sometimes blocks).

You should also add a “one-shot” flag for your WiFi.connect() and Particle.connect() (Spark.connect() should be replaced by the new wording ;-)) attempts, to not interfere with a running attempt by retriggering the connect.

Hi ScruffR,
I have still been having issues with my photon ‘locking up’. A quick reset usually sets things right. I’ve updated the DHT library to the PietteTech lib. However, I’m wondering if the wifi connection may also play a role… If nothing else, I want to handle dropped wifi connections a little more gracefully. Ideally, the photon will start up, look for wifi, and if the network is there, connect and start running code. If no connection is available, it should go about running it’s code, but every 5 or so minutes, try to connect to wifi.

One thing that I’m struggling with is the notion of wifi.connect() and particle.connect(). What is the difference between the two? When does one get used over the other?

Thanks,
JR

The locking up, might be an issue difficult to track down with this many libraries playing together (or not).
Maybe you need to step back a bit and add one component after the other, starting with the one most likely to be the foe. I’ve used the DHT sensors without pull-up resistors, but I think the recommendation is to use one.

But for your WiFi issue there definetly is a cure.
First thing is to change from default SYSTEM_MODE(AUTOMATIC) to SYSTEM_MODE(SEMI_AUTOMATIC) which allows your code to run even without cloud and/or WiFi connection - and possibly also use SYSTEM_THREAD(ENABLED).
This then brings us to the difference between WiFi.connect() and Particle.connect() (which actually would be explained in the docs ;-)).
The former only connects your device to your local WiFi network, so you could use TCP/UDP communication but would not have the Particle.xxxx() cloud functions working. For these to work you also need to call Particle.connect() (which implicitly would call the former, if there is no WiFi connection already).

So a possible use case for you might look like this

SYSTEM_MODE(SEMI_AUTOMATIC)
SYSTEM_THREAD(ENABLED)

const uint32_t msRetryDelay = 5*60000; // retry every 5min
const uint32_t msRetryTime  =   30000; // stop trying after 30sec

bool   retryRunning = false;
Timer retryTimer(msRetryDelay, retryConnect);  // timer to retry connecting
Timer stopTimer(msRetryTime, stopConnect);     // timer to stop a long running try

void setup()
{
  Serial.begin(115200);
  pinMode(D7, OUTPUT);
  Particle.connect();
  if (!waitFor(Particle.connected, msRetryTime))
    WiFi.off();                // no luck, no need for WiFi
}

void loop()
{
  // do your stuff
  digitalWrite(D7, !digitalRead(D7));
  
  if (!retryRunning && !Particle.connected())
  { // if we have not already scheduled a retry and are not connected
    Serial.println("schedule");
    stopTimer.start();         // set timeout for auto-retry by system
    retryRunning = true;
    retryTimer.start();        // schedula a retry
  }
  delay(500);
}

void retryConnect()
{
  if (!Particle.connected())   // if not connected to cloud
  {
    Serial.println("reconnect");
    stopTimer.start();         // set of the timout time
    WiFi.on();
    Particle.connect();        // start a reconnectino attempt
  }
  else                         // if already connected
  {
    Serial.println("connected");
    retryTimer.stop();         // no further attempts required
    retryRunning = false;
  }
}

void stopConnect()
{
    Serial.println("stopped");

    if (!Particle.connected()) // if after retryTime no connection
      WiFi.off();              // stop trying and swith off WiFi
    stopTimer.stop();
}
5 Likes

[rant redacted—see below]

Why are @kennethlimcp’s and @ScruffR’s solutions so different???

I’d really like an official example on how to make the user code always run and the WiFi connection interfere as little as possible, even when no signal and/or no Internet is present.

Apparently :wink: in order to have waitFor() work properly you'd need SYSTEM_THREAD(ENABLED) anyway.

I'm not convinced that there will/should be an "official" example since both ways do their job but act slightly different - neither is better than the other IMHO.
So it's up to the user to select the best fitting for his purpose or even come up with an own solution.
These should not be taken as boilerplate code but only show what can be done, to make an informed decision.

2 Likes

After some experimentation, I found that the simplest and most effective way to make WiFi-proof Photon applications is to leave everything in the default configuration and just enable the system thread:

SYSTEM_THREAD(ENABLED);

No mucking around with timers, countdowns, WiFi.on(), and so on.

This makes setup() and loop() run as soon as the power is connected—literally, even while the LED is still white—and keep running while the system thread looks for a WiFi, tries to get online, looks for the Particle servers, handshakes, etc.

Edit: the only exception seems to be if you need to register cloud variables or functions: in that case, you also need to set SYSTEM_MODE(SEMI_AUTOMATIC) and to register all the variables and functions before calling Particle.connect(). The docs explain this well.

Thanks a lot to the system engineers that worked on this feature. It’s awesome!

4 Likes

@tobia Thanks for your message; it helped me greatly and pointed me to what I needed to research in the reference documentation. On that topic, I wanted to post an update to what you wrote because the bit you added about cloud variables and functions seems to have changed—from the System Thread section in the reference docs:

Particle.function(), Particle.variable() and Particle.subscribe() will function as intended whether the cloud is connected or not.

How do you access setup mode to change wifi credentials while in Semi-Auto mode? I have a Photon running in Semi-Auto mode and when you hold setup, the light will flash blue for a little while, but not really long enough to connect to it and setup new credentials.

@PopQuiz, I was able to solve that problem like this.

It looks for known WiFi networks on boot up and if it doesn't find one starts the softap and starts listening for new credentials, after which it performs a system reset. In the meanwhile it continues to run loop code in parallel.

If WiFi info ever changed (router was reconfigured) I guess I'd have to reboot it to give new credentials. Maybe you can improve on that part.