Sleep wakeup on Photon fully available now? SOLVED

Lucky to have received my photons already but I’m not able to get sleep wake up to work via the WKP pin, and I haven’t yet found any simple code yet to pt photon to sleep and only wake up up via WKP to publish and go back to sleep for maximum power savings. Are all those functions available now?

Hi @bpr,

Can you paste your code here where the sleep didn’t work so I can reproduce the issue here at my end.

Inbetween I tried this simple loop() code which worked on my photon:

void loop()
{
    //This will run in a loop
    delay(5000);
    System.sleep(D3, RISING); //Sleep indefinitely till HIGH logic is applied on D3
    delay(5000);
    System.sleep(WKP, RISING);//Sleep indefinitely till HIGH logic is applied on WKP
}

Thanks for looking at this. There seems to be some strange (to me) interaction with Spark.process(); Is there something simple I'm missing?

//WORKS!!
void setup()
{
}

void loop()
{
System.sleep(WKP, RISING);//Sleep indefinitely till HIGH logic is applied on WKP
delay(10000);
}

BUT

//DOESN'T WAKEUP AT ALL ON RISING
const uint32_t SOFTDELAY = 10000UL;
uint32_t lastTime;

void setup()
{
}

void loop()
{
System.sleep(WKP, RISING);//Sleep indefinitely till HIGH logic is applied on WKP

// 10 seconds to allow verification of awakening
 lastTime = millis();
 while(millis() - lastTime < SOFTDELAY)
    Spark.process();

}

AND

//DOESN'T WAKEUP AT ALL ON RISING
void setup()
{
Spark.process();
}

void loop()
{
System.sleep(WKP, RISING);//Sleep indefinitely till HIGH logic is applied on WKP
delay(10000);
}

AND

//ONLY ALLOWS ONE WAKEUP
const uint32_t SOFTDELAY = 10000UL;

uint32_t lastTime;

void setup() {
// 10 seconds to allow a new code flash (can take up to 30sec))
lastTime = millis();
while(millis() - lastTime < SOFTDELAY)
Spark.process();
}

void loop()
{
System.sleep(WKP, RISING);//Sleep indefinitely till HIGH logic is applied on WKP
delay(10000);
}

Also, on my photon at least, WKP pin seems flakey/unreliable/stops responding after 3-5 rising cycles whereas D3 seems very reliable. I did firmware resets between flashing.

Have discovered sleep wakeup works as expected on two other photons after the first photon that had the problem died (might try jtag reprogramming this weekend to try to resurrect it but that looks tricky)

In case it might be useful to someone, here’s the seemingly reliable code I finally came up with, after much trial and error, to get a battery suitable/low power means of publishing to another photon with confirmation:

//deepsleepphoton5.cpp
//can be used with PHOTONSUBSCRIBE5
//sends msg to another core and gets confirmation. 
//If no confirmation of receipt after 1 min it gives up (to save power)
char publishString[64];
const uint32_t SOFTDELAY10s = 10000UL;
const uint32_t SOFTDELAY3s   = 3000UL;
const uint32_t SOFTDELAY60s = 60000UL;
uint32_t trystartTime;
uint32_t lastTime;
bool receivedflag;

void uponWake() 
{
    Time.zone(-7);
    sprintf(publishString,"{\"y\": %u, \"m\": %u, \"d\": %u, \"h\": %u, "
         "\"mi\": %u, \"s\": %u}",Time.year(),Time.month(),Time.day(),
         Time.hour(),Time.minute(),Time.second());
    Spark.publish("MotionTime",publishString,60,PRIVATE); 
}//uponWake

void setup() 
{
    // 10 sec delay to permit reflashing
    lastTime = millis();
    while(millis() - lastTime < SOFTDELAY10s) { Spark.process();}

    Spark.subscribe("MotionTimeReceived", myHandler, MY_DEVICES); 
}//setup

void loop()
{
    WiFi.off(); //power saving
    System.sleep(D3, RISING); //Sleep indefinitely till HIGH logic is applied

    Spark.connect(); 
    while(!Spark.connected()) 
    {
        Spark.process();
        delay(100);
    }

    receivedflag = FALSE;        
    uponWake(); //the action to take when awakened from sleep

    trystartTime = millis(); 

    while (!receivedflag)
    {
    //  delay here 
    lastTime = millis();
    while (millis() - lastTime < SOFTDELAY3s) 
    {
        Spark.process();
    }
     if (!receivedflag) {   uponWake();  }
    //give up trying to communicate after 1 min
     if ((millis() - trystartTime) > SOFTDELAY60s) {receivedflag = TRUE;} 
    }//while (!receivedflag)
}//loop

void myHandler(const char *event, const char *data)
{
    receivedflag = TRUE;
}//myhandler


//photonsubscribe5.cpp
char publishString[64];
const uint32_t SOFTDELAY1s   = 1000UL;
const uint32_t SOFTDELAY2s   = 2000UL;
const uint32_t SOFTDELAY3s   = 3000UL;
const uint32_t SOFTDELAY200ms   = 200UL;
uint32_t lastTime;
bool msgreceived;

void setup(){
    pinMode(D7,OUTPUT);
    msgreceived = FALSE;
    Spark.subscribe("MotionTime", myHandler, MY_DEVICES);
}//setup
    
void myHandler(const char *event, const char *data)
{
    msgreceived = TRUE;
}//myhandler

void loop() {
if (msgreceived)
{
    digitalWrite(D7,HIGH); //confirm receipt of msg by subscriber
    delay(50);
    digitalWrite(D7,LOW);
    delay(50);
    //tell originator (publisher) that msg received
    Spark.publish("MotionTimeReceived",NULL,60,PRIVATE);
    lastTime = millis();
    while(millis() - lastTime < SOFTDELAY3s)
        Spark.process();
}//if (msgreceived)

    msgreceived = FALSE; 

}//loop
1 Like

Hey @bpr,

I’m trying to do the same: make the photon wake up after RISING pin, but no success.
Maybe you can help me with your experience…

@itayd100 , I’ve changed my code a bit but still very similar. I’ll give it below, but tell me what problem you’re having. I don’t use the web IDE; instead I use local compile using the “latest” branch on github. I’m no coder, there are probably much better implementations, but here it is:

#include "application.h"
SYSTEM_MODE(SEMI_AUTOMATIC);
char publishString[63];
uint32_t lastTime;
bool receivedflag;

void doConnect() {
    WiFi.on();
     if (!WiFi.ready()) {
        WiFi.connect();
    while(WiFi.connecting())
    {
        Spark.process(); //SPARK_WLAN_Loop();
        delay(1000);
       }//while(WiFi.connecting())
    }//if (!WiFi.ready())

    if(!Spark.connected()){
    Spark.connect();
    while(!Spark.connected()){
        Spark.process(); //SPARK_WLAN_Loop();
        delay(1000);
        }//while(!Spark.connected())
    }//if(!Spark.connected())       
}//doConnect

void myHandler(const char *event, const char *data){
    receivedflag = TRUE;
}//myhandler

void setup() {
    doConnect();
    pinMode(D7,OUTPUT);
    Time.zone(-7);
    Spark.subscribe("ReceivedMotionTime", myHandler, MY_DEVICES); 
    lastTime = millis();
    while(millis() - lastTime < 3000) {Spark.process();}
    receivedflag = FALSE;   
}//setup

void loop(){

    Spark.disconnect();
    WiFi.disconnect();
    WiFi.off(); 
    System.sleep(D3, RISING); //,30); //Sleep indefinitely till D3 HIGH    
    doConnect();
    if (Spark.connected()) {     
        sprintf(publishString,"%04d/%02d/%02d %02d:%02d:%02d",Time.year(),Time.month(),
           Time.day(),Time.hour(),Time.minute(),Time.second());
        Spark.publish("MotionTime",publishString,60,PRIVATE);     
        lastTime = millis();
        while( (!receivedflag)  && (millis() - lastTime < 10000) ) { // 10s allows catching receipt msg
            Spark.process();
            if (receivedflag == TRUE) { //confirm receipt msg          
               digitalWrite(D7, HIGH);
                lastTime = millis();
                while(millis() - lastTime < 200) {Spark.process();}        
                digitalWrite(D7, LOW);     
           }//if (receivedflag == TRUE)
         }//while((!receivedflag) && (millis() - lastTime < SOFTDELAY3s)) 
    }//if (Spark.connected())
    receivedflag = FALSE;   
}//loop

I have had good luck waking from deep sleep with a rising signal on the WKP pin.

Hey @bpr,

Your code is working perfectly!
I’m not sure what I did different before (after all my tries). Thanks.

@kennethlimcp - FYI - you said there are problems with System.sleep, but this code works well (with and without wake up time).