I’m writing a program to count rain gage pulses, and using sleep mode to save power when it isn’t raining. Ideally I’d like to use the same pin to count rain gage pulses and wake the device from sleep mode (can’t count pulses if you aren’t awake. ) Here’s the test code I wrote:
What happens is, everything works fine for the first run through, but after waking the device from sleep mode with a pulse, interrupts stop getting fired on subsequent pulses. If I reattach the interrupt after waking from sleep mode it works again. Serial output below
The count is: 0
Interrupt Triggered!
Interrupt Triggered!
Interrupt Triggered!
The count is: 3
The count is: 3
C:\Users\beck>particle serial monitor
Opening serial monitor for com port: "COM3"
The count is: 3
The count is: 3
Why is this behavior occurring? Is the interrupt attached for waking the device displacing the handler to count pulses? Is there any way to get these two events (waking and pulse counting) on the same pin, or will I have to move the wake function to an interrupt on a different pin? Any ideas?
This used to be an issue but was fixed some time ago.
What platform and what system version are you targeting?
One thing that would not play well tho’ is the inverse edge for wake and interrupt. Why not use the same for both?
Then you could just count one pulse on wake already.
BTW, pulses and interruptTriggered should be declared volatile.
Aha! Yeah I’m on 0.5.2, and looks like this is fixed in 0.5.3. Thanks @ScruffR! Gave it a go and works great! BTW the inverse edges was a typo, thanks for the heads up.
Actually looking at this a little more, I think I want the sleep trigger to be CHANGE - I have an external pullup circuit and was having trouble getting the device to wake sometimes (not passing the trigger voltage), then found this old post: Having trouble using Sleep() with wakeUpPin where @peekay123 mentions that pinMode is set to PULLDOWN for RISING, PULLUP for FALLING, and INPUT for change. Where is this kind of stuff documented? Should I put in a PR to the firmware docs?
Alright one last question for you @ScruffR - if I set the trigger for the count interrupt to RISING, and the sleep interrupt to CHANGE, the count goes up by two when the device is woken with one pulse. However, if the count interrupt is falling while the sleep interrupt is CHANGE, this doesn’t happen.
My hypothesis is that when the sleep wake interrupt is attached, it changes the trigger for the count interrupt to also be change. Thus when D6 goes low by the rain gage (held high normally) it wakes the device and counts a pulse, then counts another on the rising edge as the count interrupt goes back to a RISING trigger. This doesn’t happen when the count interrupt is FALLING because there’s not another FALLING edge after the initial one that wakes the device and counts a pulse.
Am I correct in saying that the sleep interrupt trigger gets applied to user interrupts attached to a pin? If so, is this intentional or a bug? Its not a big deal, I have a workable solution, I’d just love to document or fix this for other folks.
There always only is one type of interrupt as there is only one EXTI line with its one and only set of settings for any pin - System.sleep() just hooks up another ISR.
So yes when you have a CHANGE interrupt the whole ISR chain will be triggered with either edge of the pulse … till the sleep ISR has been able to revert to the state active before the System.sleep() call. But by that time the second trigger might already have been registered.