LowPowerLab Forum

Hardware support => Moteino => Topic started by: snorp on September 01, 2016, 11:22:00 AM

Title: Radio interrupt doesn't always wake CPU?
Post by: snorp on September 01, 2016, 11:22:00 AM
My blinds (http://snorp.net/2016/05/20/blinds-controller.html) have been running for about three months now, and I've only experienced one major issue which I'm trying to debug now. I'm sending a broadcast message (address 255) to command a group of blinds all at once. Occassionally, some or all of them will act like they don't receive the message. However, if I send a 'ping' to any node (not a broadcast), all the affected blinds will then process the command. I was able to reproduce this with a bench device and some logging hooked up, and the CPU does not wake up when this occurs. My guess is that the second message triggers the radio interrupt again, it sees that it has already read a message and bails out, but now this time the CPU gets woken up and the message gets processed.

So my question is: what could cause an interrupt to not wake the CPU?
Title: Re: Radio interrupt doesn't always wake CPU?
Post by: snorp on September 01, 2016, 11:51:14 AM
Hmmm, some of the Arduino low-power examples have the ISR calling sleep_disable(). I don't do that in RFM69_WL (and neither does RFM69). Worth a shot, I guess?
Title: Re: Radio interrupt doesn't always wake CPU?
Post by: Felix on September 01, 2016, 05:11:46 PM
Weird. Not sure how to process this without setting up the same conditions.

Quote from: snorp on September 01, 2016, 11:51:14 AM
Hmmm, some of the Arduino low-power examples have the ISR calling sleep_disable(). I don't do that in RFM69_WL (and neither does RFM69). Worth a shot, I guess?

Which examples do you refer to?
Title: Re: Radio interrupt doesn't always wake CPU?
Post by: perky on September 01, 2016, 06:46:25 PM
Normally you would disable interrupts then check the conditions for sleeping, such as any state machines still running and any interrupt sources active. I had some code once that called a routine after clearing the interrupts that was supposed to turn interrupts off during its execution, unfortunately it was a simple cli() and sei() pair and the result was interrupts were turned back on yielding a very small window where an interrupt could be serviced before calling sleep_cpu(). If that was the wakeup interrupt it remains asleep. Take a good look at the code to see whether interrupts are being turned back on again prematurely (that is, after the interrupts are disabled but before the sleep instruction is executed).
Mark.
Title: Re: Radio interrupt doesn't always wake CPU?
Post by: snorp on September 02, 2016, 10:09:55 AM
Quote from: Felix on September 01, 2016, 05:11:46 PM
Weird. Not sure how to process this without setting up the same conditions.

Quote from: snorp on September 01, 2016, 11:51:14 AM
Hmmm, some of the Arduino low-power examples have the ISR calling sleep_disable(). I don't do that in RFM69_WL (and neither does RFM69). Worth a shot, I guess?

Which examples do you refer to?

http://playground.arduino.cc/Learning/ArduinoSleepCode

They are describing exactly the situation perky brought up, but here they try to prevent sleep by calling sleep_disable() in the ISR.

If it is some interrupt race, it would have to be something like the following:

1) CPU/radio are sleeping (well, listen mode)
2) Broadcast message is sent from gateway
3) Radio hits the RSSI threshold but is unable to decode the message for any number of reasons
4) Interrupt is fired anyway due to 3) (need to check datasheet on this but I think that can happen?)
5) Wake up, check and see there has been no message received, decide to back to sleep, but not before...
6) Receive another interrupt, this time ISR retrieves actual message
7) Go to sleep. Oops.

I think my logging would've caught the empty message wakeup, but maybe not. Worth checking out, though, thanks!
Title: Re: Radio interrupt doesn't always wake CPU?
Post by: perky on September 02, 2016, 04:11:51 PM
I'm a bit confused why the attachInterrupt() is called with global interrupts enabled, if the cli() was before the attach the race condition wouldn't exist.
Mark.
Title: Re: Radio interrupt doesn't always wake CPU?
Post by: snorp on September 22, 2016, 09:16:54 PM
Well I figured this out (mostly). I had left some Serial.println() stuff in for debugging. Removing that fixed the problem. I guess Serial.println() uses interrupts, so presumably something was getting out of whack there (though I don't know exactly why/how).
Title: Re: Radio interrupt doesn't always wake CPU?
Post by: syrinxtech on September 22, 2016, 10:55:26 PM
Snorp,

Another option I use instead of the broadcast address is configuring multiple nodes with the same ID.  I have a basestation that receives sensor data from a number of sources and then relays that information to display units.  Currently I'm using two display stations with the same ID.  The updates from the basestation are a constant stream of data and I didn't want to have to send multiple copies of data.  The basestation sends out one copy of the data and each of the display stations receive them.  I don't use ACK's so it's not a problem.  The only problem I've found so far is that I can't do OTA updates because the ACK's from two different stations confuses the OTA gateway.

I have only seen one instance in several months where both stations didn't receive an update.  For the amount of data that I'm pushing from the basestation out to the display units I think it's a fair trade-off.  Probably not the best solution for every situation but it works for me in this case.