Author Topic: Ultra low power listening mode for battery nodes  (Read 62605 times)

TomWS

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1853
Re: Ultra low power listening mode for battery nodes
« Reply #150 on: April 07, 2016, 08:21:28 AM »
I've separated Tom's listen mode from his ListenModeExtensions0 branch of RFM69_ATC (such that it inherits directly from RFM69). I added the ability to change the rx and idle durations for listen mode, disabled the AGC as Joe suggests, and changed the burst to send the time remaining instead of how far into the burst you are. There are also two simple wake/listen examples. I don't think the listen mode changes are nearly as invasive as the ATC ones, so maybe Felix would allow this (or similar) to be merged to RFM69?

https://github.com/snorp/RFM69_WL

(0) https://github.com/TomWS1/RFM69_ATC/tree/ListenModeExtensions
Good job on the integration!  One flaw in the current ATC code and carried into your is the RSSI_Threshold value:

Line 298  in the .cpp file has:
Code: [Select]
  writeReg(REG_RSSITHRESH, 200);
200 is WAY too high and you will be waking all the time due to spurious noise (DAMHIKT!).   I'm currently using a value of 160-170 depending on the environment.  This should probably be a settable parameter.

Keep this up and I can remove it from the ATC code!

Tom

snorp

  • Jr. Member
  • **
  • Posts: 62
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #151 on: April 07, 2016, 10:10:02 AM »
Good job on the integration!  One flaw in the current ATC code and carried into your is the RSSI_Threshold value:

Line 298  in the .cpp file has:
Code: [Select]
  writeReg(REG_RSSITHRESH, 200);
200 is WAY too high and you will be waking all the time due to spurious noise (DAMHIKT!).   I'm currently using a value of 160-170 depending on the environment.  This should probably be a settable parameter.

Thanks for the tip! I assume an interrupt will only be generated if the CRC check passes, so is there any way to know that these spurious wakeups are occurring? I guess disabling the CRC might wake me up for any random garbage?

Anyway, I'll make the RSSI threshold runtime-adustable. What about the RXTIMEOUT2 value? I don't know if I really understand what that one does. That's how long we wait for a full packet after the RSSI threshold is triggered? Seems like that one should be adjustable too.

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 5675
  • Country: us
    • LowPowerLab
Re: Ultra low power listening mode for battery nodes
« Reply #152 on: April 07, 2016, 11:29:52 AM »
@snorp:

Regarding RegRxTimeout2:
0x2B RegRxTimeout2 0x00 Timeout duration between RSSI detection and PayloadReady (DS page 61)
You can monitor the Timeout interrupt that occurs if the RSSI threshold is triggered but no payloadready interrupt is triggered (see page 70 last table row), I think that would be a good indication we're getting noise. I lowered it to 180 and it seems to work fine.
I would like to attempt to integrate your work directly into the RFM69 lib so we could use the ATC as well, otherwise not sure how that tandem could work.
« Last Edit: April 07, 2016, 11:31:35 AM by Felix »

joelucid

  • Hero Member
  • *****
  • Posts: 869
Re: Ultra low power listening mode for battery nodes
« Reply #153 on: April 07, 2016, 01:19:00 PM »
Snorp, thanks for racing ahead with this - that's great. The timeout2 is what one would ideally use to detect noise triggered RSSI awakenings. Be aware though that I never got that to fully work. Search this thread and I think another thread in this board for the infamous listen mode bug.

What happens is that prolonged periods of noise just keep the radio in rx even though timeout2 is set. I have a workaround that maps RSSI to dio0 and does its own timeout management. But it's much more involved than the simple listen mode code I used to have.

If you can figure out how to fix that problem without remapping dio0 you might be up for Joe's coveted Listen Mode Medal (tm). :-)

The bug can easily be triggered by sending a burst using a wrong bitrate.

snorp

  • Jr. Member
  • **
  • Posts: 62
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #154 on: April 07, 2016, 03:27:23 PM »
Indeed, monitoring the RSSI/RX state with the threshold set to 200db we are constantly woken up by noise (no moteino transmitting). With RXTIMEOUT2=75, I see RSSI last about ~35Ás (though sometimes almost a ms!), and RX is consistently around 340-370ÁS. I never see the timeout bit set in this scenario. If I set RXTIMEOUT2=0 (disable the timeout) the results are dramatically worse, and we spend about 24ms :o in RX. If I set RXTIMEOUT2=1, the results are similar to when it's set to 75, but I do get the timeout bit set. It seems like there is a minimum RX duration that cannot be shortened by using the timeout interrupt. That doesn't really explain why the timeout bit isn't set at higher values, though.

In any case, setting the RSSI threshold to 170db seems to avoid waking up from the noise in my office.

EDIT: I forgot to mention, if I listen at 5.5kbit there are significantly fewer wakeups at 200db. Same results otherwise.
« Last Edit: April 07, 2016, 03:33:31 PM by snorp »

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 5675
  • Country: us
    • LowPowerLab
Re: Ultra low power listening mode for battery nodes
« Reply #155 on: April 07, 2016, 04:52:39 PM »
@snorp,
I published a new RFM69 branch which includes the ListenMode based on your work. I merged your changes into the RFM69 library itself. Finally it looks like RFM69 is officially getting close to receiving ListenMode, yay, thanks again for sharing your work!

I wrapped all the ListenMode specifics into #defines. The purpose of the wrapping is the allow compiling sketches without ListenMode to save ~2k, not sure if there's a better way of doing that without using inheritance or a utility class (where you pass the radio object into it).

Please try my library and see how it works. I tried a bunch of different settings and I tweaked them to what worked best at 915mhz, I assume they will work even better at 433mhz.

joelucid

  • Hero Member
  • *****
  • Posts: 869
Re: Ultra low power listening mode for battery nodes
« Reply #156 on: April 07, 2016, 06:19:02 PM »
Quote
I wrapped all the ListenMode specifics into #defines. The purpose of the wrapping is the allow compiling sketches without ListenMode to save ~2k, not sure if there's a better way of doing that without using inheritance or a utility class (where you pass the radio object into it).

Arduino typically uses compiler/linker settings which put each function into its own section and eliminate all functions not referenced. Are you finding that code size increases even if you don't call any listen mode functions?

joelucid

  • Hero Member
  • *****
  • Posts: 869
Re: Ultra low power listening mode for battery nodes
« Reply #157 on: April 07, 2016, 07:31:10 PM »
Quote
In any case, setting the RSSI threshold to 170db seems to avoid waking up from the noise in my office.

More correct would likely be saying that you rarely wake up. It might be once a week or once a month but you will get signals strong enough to wake you. With a normal battery that's ok. With a coin cell it can easily kill your mote since vcc will be driven so low that the mote can't restart when the BOD kicks in. Hence my workaround.

Same issue as the low rssi threshold in rfm69 leading to incorrect automatic gain control and overly cranked up rx amplifier.

The best solution probably involves using timeouts provided they can be made to work and dynamically adjusting rssithresh.

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 5675
  • Country: us
    • LowPowerLab
Re: Ultra low power listening mode for battery nodes
« Reply #158 on: April 07, 2016, 10:45:26 PM »
Quote
I wrapped all the ListenMode specifics into #defines. The purpose of the wrapping is the allow compiling sketches without ListenMode to save ~2k, not sure if there's a better way of doing that without using inheritance or a utility class (where you pass the radio object into it).

Arduino typically uses compiler/linker settings which put each function into its own section and eliminate all functions not referenced. Are you finding that code size increases even if you don't call any listen mode functions?
I was expecting to see this too. Yes the code size is the same with or without calling ListenMode code. I am using 1.0.6.

snorp

  • Jr. Member
  • **
  • Posts: 62
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #159 on: April 08, 2016, 10:40:43 AM »
@Felix

The stuff in the ListenMode branch looks mostly ok to me. I made some other changes after you pulled my repo, maybe you would like to integrate those too? Or I can? I fixed the setting of REG_LNA (which you correctly commented out), and introduced a push/pop mechanism for setting the listen and burst configurations. That way we don't have to clumsily reinitialize the entire radio. This ends up simplifying re-enabling of the encryption too, since we don't have to save the key in order to set it after RFM69::initialize() clobbers it.

Also I can confirm the ~2k code size savings by not building the listen mode stuff. The build does use -ffunction-sections and --gc-sections, which is supposed to avoid this kind of nonsense, so I'm not sure what's going on. Ugh.

davegravy

  • Jr. Member
  • **
  • Posts: 56
  • Country: ca
Re: Ultra low power listening mode for battery nodes
« Reply #160 on: April 12, 2016, 09:51:16 AM »
In the listening mode node example on github there is:

Code: [Select]
 LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);

In my application I want the node to wakeup either when there's a transmission to it OR after 1 hour to take a measurement, and ideally I don't want to rely on the gateway to "wake" the node up with a transmission for those hourly wakeups.

Is there a way to do this? I can't put 8s sleeps in a loop, right? because (I'm assuming) there's no low-power means to determine after each 8s sleep if we've woken up due to received data or because 8s has elapsed...

TomWS

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1853
Re: Ultra low power listening mode for battery nodes
« Reply #161 on: April 12, 2016, 01:24:10 PM »
In the listening mode node example on github there is:

Code: [Select]
 LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);

In my application I want the node to wakeup either when there's a transmission to it OR after 1 hour to take a measurement, and ideally I don't want to rely on the gateway to "wake" the node up with a transmission for those hourly wakeups.

Is there a way to do this? I can't put 8s sleeps in a loop, right? because (I'm assuming) there's no low-power means to determine after each 8s sleep if we've woken up due to received data or because 8s has elapsed...
You can put in a WDT loop so, instead of SLEEP_FOREVER, you could sleep for n x 8Seconds while the radio is still in listen mode.  This works if you catch the wakeup packet in an interrupt handler for the radio (you'll have to temporarily replace the standard one) and use its existence to know that you woke up from a packet rather than the 8 second timeout.  Disable WDT on return.

The disadvantage of this is that you have WDT power consumption plus the brief processor run times every 8 seconds - this is probably much less than the power consumed by WDT.  You wouldn't have this power consumed in a pure ListenMode setup.

Tom


Tomme

  • Newbie
  • *
  • Posts: 24
Re: Ultra low power listening mode for battery nodes
« Reply #162 on: April 18, 2016, 08:45:55 AM »
I just took a look at the listen mode branch and I wondered why the burst transmission (to wake the node) uses multiple transmissions?

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 5675
  • Country: us
    • LowPowerLab
Re: Ultra low power listening mode for battery nodes
« Reply #163 on: April 18, 2016, 09:21:37 AM »
I just took a look at the listen mode branch and I wondered why the burst transmission (to wake the node) uses multiple transmissions?
Because the client has to be "latched" whenever it wakes up into RX mode. The master continuously transmits for at least the listen window (3s in this implementation). If the master only periodically transmits then client might not intercept it right in time. When the client wakes up for the RX part of the cycle, and a transmission is detected - the RSSI threshold is exceeded and it will trigger a longer RX period in which it expects a packet to be received. If it receives a valid packet it will trigger the packet received interrupt and wake the MCU. If it doesn't - then either it was just noise that woke it up (should be a very rare occurrence) or the packet could not be properly reiceved - in which case the RSSI timeout interrupt is triggered and the radio returns to it's normal listen cycle (sleep a long time in very low power mode, then wake up in RX mode for a very short time, then repeat).

Makes sense?

Tomme

  • Newbie
  • *
  • Posts: 24
Re: Ultra low power listening mode for battery nodes
« Reply #164 on: April 18, 2016, 11:57:34 AM »
Sorry, should have been clearer. Why not just use a larger preamble to extend the length of 1 packet rather than lots of packets? I use an idle time of 15.36 ms and an rx time of 0.384 as I need lower latency. At 55.5 kbps, 111 preamble bytes takes just under 16ms, ensuring that any receiving nodes will have woken up during preamble.

I guess with lots of small packets other nodes that are woken by packets that aren't addressed to them can return to sleep after the first packet.
« Last Edit: April 18, 2016, 11:59:59 AM by Tomme »