Waking up photon from deep sleep and doing tasks

photon
Tags: #<Tag:0x00007fe22b146fd0>

#1

Hi,

I am new to photon,
I realize photon can be put on sleep mode using System.sleep function,
How do I wake it up from deep sleep mode at specific time of day and do tasks
e.g.
I want to wake it up at 8am 1pm 5pm 10pm daily and do certain action

-NJ


#2

Both - stop mode sleep and standby (aka deep sleep) - allow for a timed wake by providing a sleep duration parameter (in seconds).
If you want your device to wake at a specific time, you need to calculate the difference between your targeted wake time and the current time and pass that to the System.sleep() function.

There are several threads in this forum that show ways to do that.
My commom approach is using Time.local() and a % 86400 (modulo) calculation.


#3

Building on what ScruffR has said. If your requirement is to wake at very specific times (i.e accuracy is important) then another approach is to using an external RTC (Real time clock) with an alarm function. When the time arrives the RTC will throw an interrupt (typically pull a pin low) - the Photon can be setup to use the WKP pin - this is the only one which will wake/restart it when in deep sleep. Having said this, the RTC on the Photon pretty good and therefore you can use System.sleep(SLEEP_MODE_DEEP, seconds_to_your_next_wake_time); Where seconds_to_your_next_wake_time has been calculated as indicated. Remember that after a wake from deep sleep the system will restart, so you may want to store some context in EEPROM before going to sleep.


#4

… or as retained data in Backup RAM


#5

I have wrote this function but I am not sure it will work on next day, help apreciated.

int hours[23] = {8, 13, 17, 22};
void sleepUntilNext(){
    //get current time and calculate next seconds for wakeup
    int curHour = Time.hour();
    Particle.publish("curHour", String(curHour), PRIVATE);
    int nextHours = getNextHours(curHour);
    int secNow = Time.local() % 86400; 
    // for 18:23:25
    int secThen = nextHours*3600;//18*3600 + 23*60 + 25;  
    int secDifference = secThen - secNow;
    if(secDifference<=0){
        //currentTime upto 23 + secDifferent from 0
        secThen = 23*3600 + nextHours*3600;
        secDifference = secThen - secNow;
    }
    
    Particle.publish("nextHours", String(nextHours), PRIVATE);
    digitalWrite(powerUp, LOW);//cut off power
    Particle.publish("deepSleep", String(secDifference), PRIVATE);
    delay(5000);//delay for previous actions
    System.sleep(SLEEP_MODE_DEEP, secDifference);
    digitalWrite(powerUp, HIGH);//power on
}

int getNextHours(int hour){
    for(int i=0;i<sizeof(hours);i++){
        if(hours[i]>hour){
            return hours[i];
        }
    }
    return hours[0];
}

firmware-full.txt


#6

Not sure why you declare your hours array with 23 entries when you only use 4.
I’d also stay clear of String and rather use snprintf() to convert numerics into strings.
This way you can also unify your three events into one single one.

When you detect a negative difference a simple addition of 86400 (24 not 23 times 3600) should do the trick.
Or alternatively you can just unify the whole calculation into one single statement.

  secDifference = (86400 + nextHours*3600 - secNow) % 86400;

Finally, in getNextHours() sizeof(hours) would only return the correct value if you declared your array like this

uint8_t hours[] = { 8, 13, 17, 22 };

sizeof() returns the number of bytes (one int is four bytes), not the number of elements and as said above you’d have 23 elements with only 4 populated.
As you have got it your for() would run up to 92 times only rendering valid entries on the first four iterations, then 19 times zero and after that some random values (i.e. after 22:00).