Photon WKP Pin Interupt Flag Question

Hi,

I have a Photon that sleeps most of time and checks in twice a day to let me know it’s all right. To accomplish this I use System.sleep(SLEEP_MODE_DEEP,SleepTime); SleepTime is set to 18000 so it wakes up every 5 hrs and checks in over Wifi. SleepTime can be set as high as a week (604800) between check ins.

I also have a motion sensor connected to the WKP pin which wakes the Photon up when motion happens. I would like to just count the number of times the motion sensor detects motion and report that number only during check-in. Right now I don’t know if the Photon woke up from the sensor or the timer. I am assuming the long duration sleep makes use of the RTC.

The question I have is when the WKP is triggered, is there a way I can tell the difference between the Photon waking from the SLEEP_MODE_DEEP timer and the Photon waking from the WKP pin being triggered? Is there a flag that gets set that I can read to tell the difference?

The project is a monitor for an animal feeding station which only needs to report the number of times the station has been visited between check in intervals. This project will eventually be ported to the Electron.

Thanks in advance for your help

The short answer is: No.

There were some threads with a similar question and possible workarounds for this shortcoming.

Hey @Jseiler,

There are some problems with the wake up pins. Last week I finally succeed to wake up the Photon with Motion sensor and Time. You can get the code from here.

To check if the wake up is from the pin or the time you can do 2 things:

  1. Connect the Motion sensor output to 2 pins in parallel - WKP and D3 for example and if the Photon wake up and D3 is HIGH then it woke up from the Motion.
  2. You can also make the Photon send the results exactly on specific time by getting the time now and calculate the seconds till what you want (you won’t be sure it’s not the motion sensor but if it’s in the middle of the night, maybe it’s good enough).

Good Luck.

You could save the expected wakeup time in eeprom, and then read that when waking up, if theres more than a few seconds diff, then its problaly motion sensor, then add one and sleep to the next expected wakeup (or plan for a new one and write the new time).

However it will add wear to the flash, so depending on how often you have events, that may not be ideal.
If its not battery operated, you could turn off wifi but keep the cpu alive, that will cut the current draw in half or so.

@ScruffR, thank you for the short and concise answer. Don’t need to waste much time reading. :smiley: I had already figured the workarounds suggested by @itayd100 and @MORA but thought there might be a more elegant way since my programming skills are not what one would consider “proficient”. Still learning.

@itayd100, I have played with both options and for my purposes # 2 works the best. The two needed variables are stored in EEPROM as suggested by @MORA. I’m not too concerned about burning out the EEPROM as I know there is some super coolness coming in the Photon update surrounding the VBAT pin that I am patiently waiting for.

Thanks again, and I’ll keep plugging away.

1 Like

I did a lot of reading of the stm32 datasheets and tried many experiments. It seems that at the chip level the 2 types of events are combined into a single flag at the chip level. It seems there might be the ability to detect this immediately on wakeup by looking at the Rtc backup registers but I think the system firmware is reseting clearing some of the required registers way before our user code gets to run.

The workaround of saving of the expected wakeup time worked very well for me.

@Jseiler, wouldn’t this work for you?

void loop()
{    WiFi.disconnect();
    WiFi.off(); 
    System.sleep(D3, RISING, 10); 
    if (digitalRead(D3)) {digitalWrite(D6,HIGH);delay(200);digitalWrite(D6,LOW);}//or set flag here
    WiFi.on();
    if (!WiFi.ready()) {
      client.stop();
      WiFi.connect();
      while(WiFi.connecting()){Spark.process();}
    }//if (!WiFi.ready())
    client.connect( server, 6123);            
    if (client.connected()) {  ....    etc etc

Thank you for your reply @bpr , unfortunately I need to used deep sleep to save as much battery as possible and interrupts don’t function in deep sleep except the WKP pin.

Using expected wake up time is still the best option. If woken up by the sensor well before the expected wake up time I simply calculate a new sleep value to the expected wake up time, increment the counter and go back to sleep. If close enough, say shy by a few minutes, I simply use the opportunity to upload the collected data and set a new expected wake up time, go to sleep, and repeat as necessary. If the feeder is visited at exactly the same time as the expected wakeup I would still get a signal on D3 while awake and deal with it accordingly.