Not sure how to use sleep mode

Hi,

I recently received a couple of Photons, (great improvement over my trusty Cores!), and I’m trying to learn how to use Sleep mode, primarily the basic sleep mode that just turns off WiFi for a specified length of time while the user code continues running.

Thing is, once it goes to sleep, it doesn’t seem to wake up/reconnect.

Below is the code I’m using to test sleep mode, it just randomly blinks the LEDs, and then I try to see if I can flash new firmware over WiFi. I’ve also tried a variation of my firmware that turns on the D7 LED whenever WiFi.ready() returns TRUE and off whenever it returns FALSE; once I go to sleep mode, that LED never turns back on.

uint8_t a=0;
uint8_t c=0;
uint8_t on=0;
uint8_t r = 0;
uint8_t g = 0;
uint8_t b = 0;
uint8_t bright = 0;

unsigned long elapsed = 0;
unsigned long interval = 10000;

void setup(){
  pinMode(D7,OUTPUT);
  RGB.control(true);
}

void loop(){
  if (!Spark.connected() && WiFi.ready()){
    Spark.connect();
  }
  a=random(255);
  c=random(255);
  r=random(255);
  g=random(255);
  b=random(255);
  bright =random(255);
  if(a>=c){
    if(on){
      digitalWrite(D7,LOW);
      on = 0;
    }
    else{
      digitalWrite(D7,HIGH);
      on = 1;
    }
  }
  else if(a<c){
      digitalWrite(D7,LOW);
  }
  delay(200);
  RGB.color(r,g,b);
  RGB.brightness(bright);
  if(millis()-elapsed >= interval){
      System.sleep(5);
      elapsed = millis();
  }
}

Have you tried this code on a Core?

AFAIK it wouldn’t run on a Core in SEMI_AUTOMATIC either (Photon background WiFi might behave similar in this regard), but not because of an issue with sleep() but rather the rapid occurence of multipe Spark.connect() attempts.

Calling Spark.connect() during an early stage of the last attempt seems to trip and put you back to start.
Just try to add a 1-2 sec tight loop with SPARK_WLAN_Loop() after the call and see if this helps.

I’d also guess that your interval = 10000 might be too short to successfully reconnect and flash OTA.

But if you only want to turn off WiFi, I’d go for SEMI_AUTOMATIC and WiFi.off() anyhow.
To “wake” again, you only need to call Spark.connect() and make sure to only call it once per “wake” attempt.
This way you got full control of what happens when.

Can’t say I have, the ones I have on hand here at the office are currently being used for other things. My unused Cores are at home so I may look when I get home.

@twalsh @ScruffR I’ve verified this issue and created an app to help show the problem and a work around. This app turns off Wi-Fi via the System.sleep(5); command, and reconnects automatically just by turning the WiFi back on and connecting. I’ll log a github issue about this, thanks guys!

unsigned long lastTOGGLE;
unsigned long lastSLEEP;
#define now() millis()
#define elapsedLED() (now()-lastTOGGLE)
#define elapsedSLEEP() (now()-lastSLEEP)
#define toggleLED() (digitalWrite(D7, !digitalRead(D7)))

void setup(){
    pinMode(D7,OUTPUT);
    lastTOGGLE = now();
    lastSLEEP = now();
}

void loop(){

    // Toggle LED every 1 Second
    if( elapsedLED() >= 1000UL ) {
        lastTOGGLE = now();
        toggleLED();
    }
    
    // Sleep (turn off Wi-Fi) after every 20 seconds of runtime
    if( elapsedSLEEP() >= 20000UL ) {
#if PLATFORM_ID == 0 // CORE        
        Spark.sleep(5);
#elif PLATFORM_ID == 6 // PHOTON
        System.sleep(5);
#endif
        lastSLEEP = now();
    }
    
    /*
     * IT IS EXPECTED HERE AFTER 5 MORE SECONDS OF 
     * RUNTIME THAT WE WILL WAKE FROM SLEEP AND
     * TURN WI-FI BACK ON, BUT IT DOESN'T HAPPEN
     */
    
    // After 5 more seconds of runtime past when we 
    // were supposed to reconnect, force a reconnect.
    if( now()-lastSLEEP > 10000UL ) {
#if PLATFORM_ID == 6 // PHOTON
        if (!WiFi.ready()) {
            WiFi.connect();
            while (WiFi.connecting())
            {
                toggleLED();
                delay(100);
                Spark.process();
            }
        }
#elif PLATFORM_ID == 0 // CORE
        if (!Spark.connected()) {
            Spark.connect();
            while (!Spark.connected())
            {
                toggleLED();
                delay(50);
                Spark.process();
            }
        }
#endif
    }
}
2 Likes

Thanks! Is this specific to the Photon or does it affect the Core, too? I still don’t have a Core handy at the moment to test.

@BDub, how were you able to redefine now(), which is a Time class function, without an error?

@peekay123 Different scope I guess… Time.now() vs now(). I’ve really been loving that now() macro for millis(), since that’s exactly what it is.

@twalsh I updated the test app to show how to compile for both Photon and Core. It does work on Core, but even though the WiFi comes back on it does not reconnect to the Cloud automatically (thus some different code to force WiFi and Cloud reconnect, i.e. Spark.connect()). I tried using Spark.connect() in the case of the Photon as well and that did not force it to connect to WiFi first. I’ll add this to the issue.

@BDub, DOH! I am way too distracted!