Author Topic: Using ListenMode as Wakeup timer  (Read 27177 times)

WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: Using ListenMode as Wakeup timer
« Reply #45 on: January 30, 2017, 03:09:43 PM »
If I set ListenCoefRx=1 and ListenResolRx=64uSec, then (see attached) Frequency Synthesis seems to run for about 128uSec before turning off.

I think these settings are "good enough," and here's why: the DS says the current drain from keeping the RC oscillator active is typically 1.2uA.  I calculate that if one to were to program Listen mode so that it woke up the atmega328p once every 66.3secs (which is the longest interval that can be specified), then the equivalent incremental drain from the RFM69 is about 31nanoamps.  That's to say, the total drain from the RFM69 would be 1.231uA.  In other words, at least in this scenario,  further optimization wouldn't make much difference.

[Edit1:  Correction:  Actually, the ~16ma of current would run for about 185uSec, not 128uSec, because that's about how long it takes from the start for PllLock to go low.  That adjustment doesn't change the conclusion though.]

[Edit2: In addition, setting a higher bitrate and disabling AGC and AFC will make it shorter.  Interestingly, I just now tried increasing the bitrate to 300kbps and disabling both AGC and AFC, but doing so resulted in no reduction of the 185uSec time.  Apparently one can't get any shorter than that.]

Finished!   :)
« Last Edit: January 30, 2017, 08:22:00 PM by WhiteHare »

joelucid

  • Hero Member
  • *****
  • Posts: 869
Re: Using ListenMode as Wakeup timer
« Reply #46 on: January 31, 2017, 01:10:38 PM »
Cool! I use Listen mode with thresh of 0 for all my not actively listening nodes that don't have clock XTALs. Works very well and is a great improvement over the 4uA WDT.

WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: Using ListenMode as Wakeup timer
« Reply #47 on: February 06, 2017, 11:33:09 PM »
Unfortunately, I encountered a setback on implementing it for the atmega328p.  I'm finding that if ListenResolRx=64usec, then ListenCoefRx needs to be 2 or greater because otherwise the atmega328p doesn't seem to detect the interrupt.  So, unless someone knows of a workaround to that, it appears that in actual practice that is the shortest Rx window that can still trigger an interrupt with PllLock mapped to D2.

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: Using ListenMode as Wakeup timer
« Reply #48 on: February 07, 2017, 07:30:42 AM »
Are you getting a pulse on the interrupt line longer than 1 MCU clock that the 328P is missing, and can you program the interrupt on the 328P to be edge sensitive rather than level sensitive? If it's programmed for level the interrupt might get missed. From the manual (p. 89):

"If edge or toggle interrupt is selected, pulses that last longer than one clock period will generate an interrupt. Shorter pulses are not guaranteed to generate an interrupt. If low level interrupt is selected, the low level must be held until the completion of the currently executing instruction to generate an interrupt."

Mark.

WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: Using ListenMode as Wakeup timer
« Reply #49 on: February 07, 2017, 08:50:46 AM »
For the code I'm using:
Code: [Select]
  attachInterrupt (0, wake, RISING); 
  EIFR = bit (INTF0);  // clear flag for interrupt 0

The MCU is running off the 8Mhz internal resonator, so that may be a factor as well.

The pulse is what's shown in the scope shot above.

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: Using ListenMode as Wakeup timer
« Reply #50 on: February 07, 2017, 10:08:28 AM »
Interesting. I've seen behaviour on an xmega that was a bit curious, it claimed the pin change detection mechanism was asynchronous but it didn't work when selecting specific rising or falling edge mode, however it did work when I selected both edges and read the state of the pin in the ISR to determine which one it was. It was an oddity that I couldn't explain. Maybe try detecting both edges?

Mark.

WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: Using ListenMode as Wakeup timer
« Reply #51 on: February 09, 2017, 02:13:42 PM »
I think I'll try feeding it into the atmega328p's timer.  I would think that if atmega328p's timer can accurately count pulses from a 32,768 crystal oscillator, then it should also able to capture a  64usec PllLock pulse, since that lasts longer.

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: Using ListenMode as Wakeup timer
« Reply #52 on: February 09, 2017, 04:07:54 PM »
I assume the both edges test didn't work then?
Mark.

WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: Using ListenMode as Wakeup timer
« Reply #53 on: February 09, 2017, 04:26:53 PM »
Wasn't sure how to do it.  Is it possible to assign two different ISR's (one for FALLING and one for RISING) to the same pin?  Is that how it's done?  Or do I use separate pins (one for RISING and the other for FALLING), but wire the two pins together?  Or something else?

Regardless, I'm thinking the timer approach might also be helpful for a somewhat different reason: when I'm setting the Listen Mode for fairly short cycles (64usec for Rx and about 100ms for idle), as I will for the low latency remote control listening, it might be tidier not to wake up the atmega328p on every cycle if nothing is happening just to have it increment a counter and go back to sleep.  Rather, maybe use the asynchronous timer's counting ability to wait 1000 or 10000 cycles or so before waking up the atmega328p with a timer interrupt so that it can measure the voltage and phone home.
« Last Edit: February 09, 2017, 04:32:17 PM by WhiteHare »

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: Using ListenMode as Wakeup timer
« Reply #54 on: February 09, 2017, 05:45:19 PM »
You can set the pin to interrupt on either edge:

attachInterrupt (0, wake, CHANGE);

I found with my xmega part this actually worked, but rising or falling modes didn't (still don't know why). If the logic is common maybe it will work for this too, it's a simple enough test as you're only trying to detect a transition.

Mark.

Edit: found the reason, the pin I was using has "limited asynchronous sense support", and that allows level and pin change interrupts but not rising or falling edge. Still confuses me though because the device did not wake up which it was supposed to do even if no interrupt was actually generated.

And more info, the 328P says that for the external interrupts "recognition of falling or rising edge interrupts on INT requires the presence of an I/O clock. Low level interrupt on INT is detected asynchronously". It doesn't mention pin change in that section, but the option is in the EICRA register section. If you are deep sleeping the device it'll have to wake up and start the IO clock first with rising or falling edges. Since it doesn't mention the change condition maybe that doesn't require the IO clock (?).
« Last Edit: February 09, 2017, 07:18:05 PM by perky »

WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: Using ListenMode as Wakeup timer
« Reply #55 on: February 09, 2017, 08:17:33 PM »
You can set the pin to interrupt on either edge:

attachInterrupt (0, wake, CHANGE);


Thanks for clarifying that.  I tried it just now, but unfortunately CHANGE doesn't work any better than RISING or FALLING.  With any of them, it does occasionally, and seemingly at random, pick up the PllLock interrupt when ListenCoefRx=1 and ListenResolRx=64us.   However, it definitely misses the vast majority of them.  When I switch to ListenCoefRx=2, though, then it picks up every interrupt just as it should.

The issue is more significant if attempting a low latency listen mode, because there are simply many, many more ListenRx's happening (I'm hoping for 1 every 100ms), and it all adds up.  Reducing all those ListenRx's to ListenCoefRx=1 should reduce current consumption by somwhere up to half.

So, plan B is to hope that Listen Mode really does work as it should with ListenCoefRx=1.  However, because I can't utilize PllLock pulses which are that brief to wake the atmega328p, I'm hoping that feeding those PllLock interrupt pulses into the atmega328p's asynchronous timer will yet catch them, and thus indirectly wake the atmega328p after a programmed number of pulses are received if atmega328p hasn't already been awoken by receiving a packet while in Listen Mode.  Well, that's the theory anyway.   ::)

[Edit:  Actually, come to think of it, there is one other possibility as to why it's missing most of the PllLock interrupts when ListenCoefRx=1:  I have a lot of debug println statements that I haven't commented out yet.  Perhaps one of those is getting serviced when the PllLock interrupt briefly fires, and the interrupt flag clears before it finishes with the println's.  I'll do some housecleaning and see if that makes a difference.  Chances are it might!]
« Last Edit: February 09, 2017, 09:37:08 PM by WhiteHare »

WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: Using ListenMode as Wakeup timer
« Reply #56 on: February 12, 2017, 10:04:41 PM »
Back to square one.  It turns out that commenting out the debug code didn't solve the problem after all.  So, I put pin 2 on a scope to see what's going on.  When ListenCoefRx=2, the pulse width on DIO0 is about 13uSec. 

When ListenCoefRx=1, there is no pulse at all.

[Edit: therefore, it would appear that the shortest (most energy efficient) setting for PllLock that still works is when ListenCoefRx=2.  It just is what it is.  ::)]

« Last Edit: February 13, 2017, 08:36:25 AM by WhiteHare »

WhiteHare

  • Hero Member
  • *****
  • Posts: 1298
  • Country: us
Re: Using ListenMode as Wakeup timer
« Reply #57 on: February 13, 2017, 12:21:08 PM »
I just now mapped DIO4 to PllLock to see what would happen.  When ListenCoefRx=2, I get a repeating pulse that's 62uSec wide.  However, when ListenCoefRx=1, I get no pulses.

I think that confirms it.  ListenCoefRx=2 is the shortest setting when ListenResolX is 64uSec.   :(

perky

  • Hero Member
  • *****
  • Posts: 873
  • Country: gb
Re: Using ListenMode as Wakeup timer
« Reply #58 on: February 13, 2017, 12:56:29 PM »
OK, it wasn't missing pulses then - they just weren't there ;) This is useful work WhiteHare.
Mark.

joelucid

  • Hero Member
  • *****
  • Posts: 869
Re: Using ListenMode as Wakeup timer
« Reply #59 on: February 13, 2017, 05:34:50 PM »
Yeah, it typically takes 80 uS to get pll locked according to the datasheet. So this isn't too surprising. Still very good to have it experimentally confirmed!