Photon (0.4.5 & 0.4.6) not waking up after sleep with interrupt

Hi,

I have a 9 V signal which is most of the time low. My aim is to use this signal to wake the photon up from sleep with an interrupt. So I have built a voltage divider to reduce the voltage. My DMM shows 2,93 V so I think that this should work.

unsigned long waitOTA;
    
volatile bool isEvent = false;
    
void ISR() {
        isEvent = true; 
}
    
void setup() {
    
    attachInterrupt(D1, ISR, RISING);
    
    Spark.publish("Setup", "Waiting for OTA!");
    
    waitOTA = millis();
    while (millis() - waitOTA < 20000) {
        Spark.process();
    }    
}
  
void loop() {
        System.sleep(D1, RISING);
    
        
        if(isEvent == true) {
            Serial.println("TRUE");
            isEvent = false;
       
            Spark.publish("EV", "EVENT!");
    
        } else {
            Serial.println("FALSE");
            delay(100);
        }
}

The problem is my Photon never wakes up and I don't know why?

The Documentation says:

Since 0.4.5. The state of WiFi and Cloud connections is restored when the system wakes up from sleep. So if the device was connected to the cloud before sleeping, then the cloud connection is automatically resumed on waking up.

Firmware 0.4.5 is on my Photon.

I would be very grateful if you could help me!

One thing I’d do before attachInterrupt() is to set pinMode(D1, INPUT).

Another thing would be to swap the voltage divider for an opto isolator (or another means to decoupe voltage levels). If your voltage regulator looses its GND you might end up with 9V on your pin.

What resistors are you using for your VD?
Since System.sleep(D1, RISING) implicitly activates the internal pull-down resistor, you’ll end up with a parallel of the two down resistors [ (1/yourDown + 1/40k) vs. (1/yourUp) ].

Thank you very much for your advice! I added pinMode(D1, INPUT); before attachInterrupt()
An opto isolator is on my list to order :smile:

For my VD I am using two 150 Ohm resistors. I removed them:

+9V Signal -----------+----- D1 (Photon)
                      |
                      R2
                      |
     GND -------------+

       R1 = removed because of pullup, R2 = 20K

Is this correct?

Nope, this would definetly fry your pin :weary:
I hope you’ve not tested this already.

With two 150Ohms you should measure 4.5V at the mid point, but you said about 2.9V so your 9V might not be 9V or your resistors have an incredibly bad tolerance rating :wink:


At the moment I’m running some tests about wake - which seems to not work as documented.
But since we are at the verge to FW version 0.4.6 this might have been fixed already - I’ll come back to you once I know more

No, I just tried to correct the VD, but it doesn’t seem clear to me how the wiring with the internal pullup looks :frowning:

You can’t see the internal pull-resistors as part of your circuit but you have to consider its impact on it.
And the datasheet of the µC on the Photon demands that you have to detach internal pull-resistors when intending to apply more than Vdd+0.3V (aprox. 3.6V).
In this case using System.sleep(pin, RISING/FALLING) would be a no go - despite most pins being 5V tolerant.

thats all really confusing for a beginner like me, So if I detach the internal pull-resistor my first attempt with the 150 Ohm resistors would be correct?

I have tested my Photon with a Sharp Sensor. Everything works if I do not use sleep. When I use sleep it does not wake up :frowning:

Here’s my theory, which could be completely wrong…

  • You power up, and after 20 seconds, the Photon goes to sleep.
  • In low power mode, the serial connection goes inactive.
  • You’re sleeping, and then the interrupt wakes the Photon up with isEvent == true.
  • Because the serial connection was lost, you get no serial output.
  • You set isEvent back to false.
  • You try to call Spark.publish(), but it fails. (because…)
  • You reach the end of the loop() and the Spark tries to re-establish Wifi.
  • You hit the top of the loop, and immediately go back to sleep.

As I said, this could be completely wrong. But my variation on this theory is that timing of the WiFi/Cloud reconnection is out of sync with your code exection, even if it isn’t exactly as I outlined here?

Try verifying the state of your Serial connection, and re-call Serial.begin() if necessary. Also test the return value of Spark.publish(). Maybe use an LED to help you verify what’s going on in various states.

1 Like

Hey firmware people, what’s up with this? Is it overridden somewhere? Or is this a red herring, and I’m just misinterpreting its application here?

thank you very much for your suggestions! I tried to use the LED on D7 with a delay to be able to see it and moved the sleep code to the end of my code. But it happens nothing.
Your findings in the firmware would explain why there is nothing happening :frowning:

Just to clarify some things - this part of the docs only refers to System.sleep() without parameters and with a wake on timeout but not for the System.sleep(pin, ...) or System.sleep(SLEEP_MODE_DEEP, ...).
For these versions of System.sleep() you'd have to consider this part of the docs

When the specific interrupt arrives, the device awakens from stop mode, it will behave as if the device is reset and run all user code from the beginning with no values being maintained in memory from before the stop mode.

So your anything after System.sleep() in loop() will never be executed.

But this is planned

(Note: The new Particle Photon firmware will not reset before going into stop mode so all the application variables are preserved after waking up from this mode. The voltage regulator is put in low-power mode. This mode achieves the lowest power consumption while retaining the contents of SRAM and registers.)

Admittedly the docs lag behind the actual firmware state, but things are being worked on on several fronts :sunglasses:

But in each case (sleep at the end or at the beginning of loop) the Photon should start with setup und breath cyan. But it does not do anything. Maybe this is a bug or I have damaged my Photon. Without sleep I can see the interrupt in the Serial Monitor so I assume it is a bug.

I’ve just filed an issue about this problem, since it still exists in 0.4.6 (I’ll alter the topic accordingly too).

@dougal you are looking at GCC platform implementation that’s why?

Could you try

System.sleep(D1, RISING, 0);

hi @mdma,

I have tried System.sleep(D1, RISING, 0); but it did not change anything. Maybe another user can verify this.

Doesn't change a thing since the 0 is there by default

spark_wiring_system.h

 static void sleep(uint16_t wakeUpPin, InterruptMode edgeTriggerMode, long seconds=0);

Thanks for confirming. I was worried the compiler might have been resolving to one of the other 2-argument sleep() functions. But that’s not the case since the first argument for the other 2 argument function is an enum.

1 Like

… and takes a long as 2nd parameter (called seconds) while the wake-on-pin overload takes an InterruptMode enum as second parameter :wink: