WiFi.off/WiFi.on, Core vs Photon [SOLVED]

I have a Core now, my Photon has not yet arrived, so I can’t do the test myself.
on my Core this code does not work, but I suspect that it will work on the Photon. Can anyone verify that?

---------------------------------------
long nowMilli = 1;
void setup() {
    Spark.publish("WiFi.off test", "start test. In setup()");
    delay(10000); // 10 seconds to allow a new code flash
}
void loop() {
    delay(5000);
    nowMilli=millis();
    WiFi.on();
    Spark.publish("Seconds since restart", String(nowMilli/1000)); 
    delay(5000);
    WiFi.off(); // on my Core, works if this line is commented out, else, not!
}

You need to give time for the core to connect to the :cloud: so your method might not be the best way to code it.

Can you explain what is your use case so that we can demonstrate how it can be done?

1 Like

@kennethlimcp, thanks for your fast reply.
I want to gather information, while wifi is offline (saving power) (I use solar panels a lot), then every few seconds, or minutes,hours, turn the wifi (power user) back on, and send the data.

How long does it take the Core to connect back up, how long does it take the Photon to connect back up. Are they the same?
Thanks, Jack

@Jack,

There is no way to get information while wifi is offline. Like your phone cannot receive messages in Airplane mode.

Core and Photon would differ depends on the environment and many other factors but there usually take a couple of seconds to do that.

I will write a working example for the core and post back here once i have it.

Are you trying to just send data every few seconds and turn off wifi after that?

By gathering information, I ment such as temperature, water pressure, gate opening, from the pins on the particle board. Then send that to the internet ever few seconds, or minutes. Yes, a working example would be great. Thanks.
For a test, you can just use the millis() I guess.

Yes, that is what I want to do. Thanks

@Jack, a few words to make your code run on the Core - this way it will run on the Photon too.

If you intend to switch WiFi off you’d better use SYSTEM_MODE(SEMI_AUTOMATIC) to prevent any issues in the Core “background” task.
To be able to read sensors while not online, you might like to avoid delay() and rather go for a “soft delay” by use of millis().
WiFi.on() is not enough to be able to Spark.publish(), you’d rather need to call Spark.connect() and maybe check the connection status along with your soft delay timer to do your publishing.
For nowMilli you should use unsigned long (or uint32_t) rather than long.

I sure could whip up some working code for you, but I’d guess, you’ll enjoy finding the solution yourself even more :wink:

1 Like

@ScruffR, thanks for the info. A working example would really be great.
I normally don’t use delay(), but did in this script to keep the code short, simple and easy to read by others.

If someone can whip up some working code, it would be a benefit to me, and I think several others that may want to use such a feature on the internet.
Thanks

You could try this

SYSTEM_MODE(SEMI_AUTOMATIC)

const uint32_t SOFTDELAY = 10000UL;
uint32_t nowMilli;

void setup() 
{
    Spark.connect();

    while(!Spark.connected())
    {
        SPARK_WLAN_Loop();
        delay(100);
    }
    // attempt to publish before cloud is connected causes hard fault SOS
    Spark.publish("JackTest", "StartTest - inside setup()");
        
    nowMilli = millis();
    

    // 10 seconds to allow a new code flash (can take up to 30sec)
    while(millis() - nowMilli < 3 * SOFTDELAY)
        SPARK_WLAN_Loop();
}

void loop() 
{
    if (Spark.connected())
    {
        delay(500);         // allow for cloud to settle in
        uint ms = millis() - nowMilli;
        Spark.publish("JackTest", String(ms / 1000));
        delay(500);         // allow some time to finish publishing
        WiFi.off();         // turns of WiFi and hence drops cloud connection
        nowMilli = millis();
    }
    else if (millis() - nowMilli > SOFTDELAY)
    {
        nowMilli = millis();
        Spark.connect();    // turns on WiFi and connects to cloud
    }
}

There is still a minor issue with the 10sec delay (it’s only 4sec for some reason???), but the rest works

I suspect that the Photon is faster, but I don't know of any official tests. Connecting to wifi seems to vary a little bit every time depending on distance, obstructions, planetary alignment, the Avengers, etc. Wifi on my home network is usually pretty quick to connect for any device, but every now and then it will take several seconds for any device (Core or even a fancy laptop). Unless it is taking a long time, I doubt the time it takes to connect will drain much from your battery. In most of my testing, the Core takes 15-25 seconds to connect to wifi and handshake with the cloud.

You may be interested in the Spark Battery Life Testing thread I posted a while back where I tested the Spark Core on lipo batteries with various sleep cycle durations. The sample code for those tests is in the paragraph below the picture. Your mileage may vary if you need to keep the Core/Photon awake to watch for gate openings, so the SYSTEM_MODE(SEMI_AUTOMATIC) that @ScruffR mentioned above may be your best bet.

1 Like

Thanks for trying, but this script is not working for me.
I wanted
Spark.publish(“Seconds since restart”, String(nowMilli/1000));
to show how long it has been since restart. If it has been running for 2 minutes, it should publish a value close to 120.
You changed my line of code from"
Spark.publish(“Seconds since restart”, String(nowMilli/1000));
TO:
Spark.publish(“JackTest”, String(ms / 1000));
So now the new line keeps publishing (showing) 4 or 8 seconds, even when my last restart was several minutes ago. So it looks like this example code must restart the processor every few seconds, with RTC and other variables being lost.

Oh, BTW, you took my line of code in the setup() out:
delay(10000); // 10 seconds to allow a new code flash,
so now I can’t flash the core again from build.particle.io
Thanks for trying tho. Jack

@ScruffR

My "soft delay" works a little different than yours. Is there a thread on the forum about "soft delays", If not you or I should start one. You first..

@Jack, sorry for misunderstanding your intention about the published time :blush:
I just didn’t read your comment thoroughly enough.

But that’s an easy fix, you could do yourself - but I’ll post an updated version ASAP.

For the reflashing

    // 10 seconds to allow a new code flash (can take up to 30sec)
    while(millis() - nowMilli < 3 * SOFTDELAY)
        SPARK_WLAN_Loop();

This part ensures - at least on my Cores - that you still can reflash.

Thanks.
about the delay to be able to reflash, does that need to be 4 seconds, 10 seconds, or 30 seconds do you think. I had good results with 10 seconds, but someone (maybe you) said 30 seconds. But I think 4 seconds is a bit short. What do you think.
Thanks for your help.

Just want to mention that the new firmware for the Photon has a safe mode where the user code will not run. The Photon will simply connect to the :cloud: and wait for commands/OTA with no code running.

This will help the with the issue of bad firmware causing issues but it is not a 100% fool-proof method if there’s some real issues with the code.

On the core, this feature will also be available once the V0.4.0 is deployed.

@mdma, under what conditions will the Photon/core decide to enter Safe mode? I would like to run some tests :smile:

I’ve found out that at least in SEMI_AUTOMATIC aprox. 30sec is required if your code intends to switch off WiFi after that time, to allow for the full download to complete.
After the download has finished, and the flashing process gets triggered your code will not run anymore anyhow, but downloading takes place in the background while your code still is allowed to run, and hence could cut its own umbilical cord while downloading and counteract any reflashing attempt.

If your code wouldn’t intend to drop cloud connection you just need enough time (a few seconds) for the Core to realize your intent to reflash. Because the rest can take place in the background.

Just thinking, if I write script (code), flash it, and then the processor decides to go to safe mode and not run my code. I must not understand this yet..

While I don’t know all possible reasons for “safe mode” to be entered, I’d not suspect it just to do it in any “harmful” way :wink:
One probable reason for entering this mode is, when the Photon (and in future Core & Electron too) realizes, that the user wants to flash new firmware. In this case it would be most unhelpful, if user code would still be allowed to turn the cloud connection off - as is the case with the Core at the moment.
Given this scenario, I’d not suspect that you would consider it “harmful” that your code got stopped running, since you are well aware that it has to stop running anyhow, to let a new firmware take its place :wink:

1 Like

As promised earlier, this should actually do what you originally intended

SYSTEM_MODE(SEMI_AUTOMATIC)

const uint32_t SOFTDELAY = 10000UL;

uint32_t lastTime;
uint32_t startTime;
bool     connecting = false;

void setup() 
{
    Spark.connect();

    while(!Spark.connected())
    {
        SPARK_WLAN_Loop();
        delay(100);
    }
    
    // attempt to publish before cloud is connected causes hard fault SOS
    Spark.publish("JackTest", "StartTest - inside setup()");
 
    startTime =       
    lastTime = millis();

    // 10 seconds to allow a new code flash (can take up to 30sec)
    while(millis() - lastTime < 3 * SOFTDELAY)
        SPARK_WLAN_Loop();
}

void loop() 
{
    if (Spark.connected())
    {
        uint32_t ms = millis() - startTime;

        connecting = false; // we are already connected
        delay(500);         // allow for cloud to settle in (may be reduced)
        Spark.publish("JackTest", String(ms / 1000));
        delay(500);         // allow some time to finish publishing (may be reduced)
        WiFi.off();         // turns of WiFi and hence drops cloud connection
        lastTime = millis();
    }
    else if (!connecting && millis() - lastTime > SOFTDELAY)
    {
        Spark.connect();    // turns on WiFi and connects to cloud
        connecting = true;
    }
}

On the photon, it is 100% fool proof. It simply doesn't run the user code, since this is entirely separate.

It's the core where we can't guarantee it always works in cases where you have a bug in a global constructor, since the user code and system code are not separate.

3 Likes