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

WhiteHare

  • Hero Member
  • *****
  • Posts: 1296
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #105 on: September 08, 2015, 08:31:40 AM »
On the other hand, suppose at some point RSSI >  It's certainly not what one would want as listen mode user since with a long burst of packets destined for another node you'd never go back to idle.



I was trying to give it the benefit of the doubt, but if it turns out there's not even any preamble detection going on, then it might be even worse than that: perhaps a simple noise source might keep the RFM69 in Rx mode indefinitely.   :'(

I haven't yet tried the address matching part, to see if a mismatch would knock it out of the loop or at least prevent a reset of the countdown.  Does it do anything at all?

It might help if there were a way to see the same RF signal that the chip is seeing, or at least some kind of real-time RSSI, while all this is going on. 

Of course, it would help even more if there were better documentation than the few crumbs of information that are in the datasheet!
« Last Edit: December 07, 2015, 07:18:32 PM by WhiteHare »

joelucid

  • Hero Member
  • *****
  • Posts: 867
Re: Ultra low power listening mode for battery nodes
« Reply #106 on: September 08, 2015, 08:43:00 AM »
But that can't be true given your scope traces and also what I have seen: if RSSI threshold is too low you will jump into phase 3 but it will abort after timeout 2 strikes. So at worst there are specific scenarios under which the timeout doesn't trigger - one of which may be that there is a continuous burst of real rfm69 originating packets for another node. Whether that's driven by preamble or something else.

Noise by itself does not trigger this behavior.

xavier

  • Jr. Member
  • **
  • Posts: 65
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #107 on: December 07, 2015, 05:28:48 PM »
hey Joe - I'm trying to use the sample code you posted (page 3) with my moteino+RFM915 but somehow the client never wakes up.

I modified send and startListening so they use the 915 register values (RF_FRFMSB_915, RF_FRFMID_915 and RF_FRFLSB_915 in startListening and in send) but no luck so far.

Any suggestions on how to debug to see what is going on or if I missed anything obvious?

Thanks!

X

Update 1: updated code to show I'm using latest version as posted on previous page

I init my radio as follow just fyi:
Code: [Select]
void xRadioLib::initWithDefaults() {
    _radio.initialize(_frequency,_nodeId,_networkId);
    if (_is_Rfm69Hw) {
        Serial.println("Setting up high power");
        _radio.setHighPower();
    }
    _radio.encrypt(_ENCRYPTKEY);

    _radio.readAllRegs();
   
    _radio.sleep(); //sleep right away to save power

    Serial.print( "Initializing Radio NodeId:" );Serial.print( _nodeId );Serial.print(" and NetworkId: "); Serial.println(_networkId);
}

//to set client in Listen mode
void xRadioLib::setRadioInListenMode(bool on){
    if (on)
        RFM69Listener::startListening( _radio, _buffer, _bufferSize);
    else {
        RFM69Listener::clearBuffer();     //this just sets the size to 0, buffer is still available and is null terminated
        RFM69Listener::endListening(_radio);
        //reset our settings:
        this->initWithDefaults();
    }
   
}

void xRadioLib::wakeUpNode( uint8_t targetNode, uint16_t boostPeriod, bool highspeed)
{
  detachInterrupt( RF69_IRQ_NUM );
  radio.encrypt( 0 );
  radio.setMode( RF69_MODE_STANDBY );

  radio.writeReg( REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_WHITENING | RF_PACKET1_CRC_ON | RF_PACKET1_CRCAUTOCLEAR_ON  );
  radio.writeReg( REG_SYNCVALUE1, 0x5A );
  radio.writeReg( REG_SYNCVALUE2, 0x5A );

  radio.writeReg( REG_FRFMSB, RF_FRFMSB_915 + 1 );
  radio.writeReg( REG_FRFMID, RF_FRFMID_915  );
  radio.writeReg( REG_FRFLSB, RF_FRFLSB_915 );

  if( highspeed ) {
    radio.writeReg( REG_BITRATEMSB, RF_BITRATEMSB_200000);
    radio.writeReg( REG_BITRATELSB, RF_BITRATELSB_200000);
    radio.writeReg( REG_FDEVMSB, RF_FDEVMSB_100000 );
    radio.writeReg( REG_FDEVLSB, RF_FDEVLSB_100000 );
    radio.writeReg( REG_RXBW, RF_RXBW_DCCFREQ_000 | RF_RXBW_MANT_16 | RF_RXBW_EXP_0 );
  }

 
 
  radio.setMode( RF69_MODE_TX );
 
  uint32_t time = millis();
  uint32_t m;
  while( (m = millis()) - time <= boostPeriod ) {

    noInterrupts();
    // write to FIFO
    radio.select();
    SPI.transfer(REG_FIFO | 0x80);

    SPI.transfer( size + 3);

    SPI.transfer( targetNode );

    uint16_t diff = m - time;
    SPI.transfer( diff & 0xff );
    SPI.transfer( (diff & 0xff00) >> 8 );

    for (uint8_t i = 0; i < size; i++)
        SPI.transfer(((uint8_t*) buffer)[i]);
    radio.unselect();
    interrupts();
//    uint32_t txStart = millis();
//    while (digitalRead(RF69_IRQ_NUM) == 0 && millis() - txStart < RF69_TX_LIMIT_MS); // wait for DIO0 to turn HIGH signalling transmission finish
//    radio.setMode( RF69_MODE_STANDBY );
   
    delayMicroseconds( 2000 );
   
   
  }
  radio.setMode( RF69_MODE_STANDBY );
}

« Last Edit: December 07, 2015, 05:45:39 PM by xavier »

joelucid

  • Hero Member
  • *****
  • Posts: 867
Re: Ultra low power listening mode for battery nodes
« Reply #108 on: December 08, 2015, 04:16:28 AM »
Quote
Any suggestions on how to debug to see what is going on or if I missed anything obvious?

If you want to work with the sample code I posted, please build a simple example that only changes the frequency in my code and otherwise doesn't copy or change anything. Then post the full client and server code you wrote so I can see what you're doing.

If you want to pick up smth that just works with 915Mhz radios you might want to try Tom's RFM69 replacement library which as I recall already implements listen mode and works with 915mhz radios.

xavier

  • Jr. Member
  • **
  • Posts: 65
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #109 on: December 08, 2015, 12:05:28 PM »
thanks. Will try. I must have screwed up something obvious though since even the basic sample code (gateway et node) don't seem to work - I get only a few packets received and the RSSI is 0...I'll try to get the basic sample code working first  or change boards... thanks!

xavier

  • Jr. Member
  • **
  • Posts: 65
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #110 on: December 08, 2015, 03:00:24 PM »
ok so for now I got my moteinos to talk to each other (seems I was using 2 different versions of the RFM69 library) - the Listen code is still not working but would like to try Tom's code - Anyone knows where the updated RFM69 lib with Tom's changes for the listen mode are posted?

I found this from Felix: https://lowpowerlab.com/forum/index.php/topic,775.0.html but can't seem to find any RFM69Ext.h on the net...

TomWS

  • Hero Member
  • *****
  • Posts: 1924
Re: Ultra low power listening mode for battery nodes
« Reply #111 on: December 08, 2015, 08:06:37 PM »
ok so for now I got my moteinos to talk to each other (seems I was using 2 different versions of the RFM69 library) - the Listen code is still not working but would like to try Tom's code - Anyone knows where the updated RFM69 lib with Tom's changes for the listen mode are posted?

I found this from Felix: https://lowpowerlab.com/forum/index.php/topic,775.0.html but can't seem to find any RFM69Ext.h on the net...
You want this branch (https://github.com/TomWS1/RFM69_ATC/tree/ListenModeExtensions) along with Felix's latest RFM69 library (which provides the necessary virtualization).  There are example files in the ATC library that use ListenMode (see the examples with the _WL extension -ie, "With Listenmode")

Tom

xavier

  • Jr. Member
  • **
  • Posts: 65
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #112 on: December 09, 2015, 12:45:24 PM »
thanks Tom - I had a quick look but the sample code does not seem to compile using the latest from Felix and your branch for the ATC files. I'm using IDE 1.6.6 and getting the following errors:

/Users/xavier/Documents/Arduino/libraries/RFM69/RFM69_ATC.cpp: In member function 'virtual void RFM69_ATC::select()':
/Users/xavier/Documents/Arduino/libraries/RFM69/RFM69_ATC.cpp:117:3: error: '_SREG' was not declared in this scope
   _SREG = SREG;
   ^
/Users/xavier/Documents/Arduino/libraries/RFM69/RFM69_ATC.cpp: In member function 'void RFM69_ATC::sendFrame(uint8_t, const void*, uint8_t, bool, bool, bool, int16_t)':
/Users/xavier/Documents/Arduino/libraries/RFM69/RFM69_ATC.cpp:223:48: error: 'RFM69_CTL_RESERVE1' was not declared in this scope
     SPI.transfer(RFM69_CTL_SENDACK | (sendRSSI?RFM69_CTL_RESERVE1:0));  // TWS  TODO: Replace with EXT1
                                                ^
/Users/xavier/Documents/Arduino/libraries/RFM69/RFM69_ATC.cpp:232:39: error: 'RFM69_CTL_RESERVE1' was not declared in this scope
       SPI.transfer(RFM69_CTL_REQACK | RFM69_CTL_RESERVE1);     // TWS: ASK for ACK + ASK for RSSI
                                       ^
/Users/xavier/Documents/Arduino/libraries/RFM69/RFM69_ATC.cpp: In member function 'virtual void RFM69_ATC::interruptHook(uint8_t)':
/Users/xavier/Documents/Arduino/libraries/RFM69/RFM69_ATC.cpp:284:34: error: 'RFM69_CTL_RESERVE1' was not declared in this scope
   ACK_RSSI_REQUESTED = CTLbyte & RFM69_CTL_RESERVE1; // TWS: extract the ACK RSSI request bit (could potentially merge with ACK_REQUESTED)

To fix the _SREG I added a definition in RFM69.h since this is where the __SPSR is defined

For the RFM69_CTL_RESERVE1 issue it seems your branch does not have it defined in RFM69_ATC but the file in the RFM69 branch does have it so I just copied it from there.

Things seem to work alright now although it seems sometimes the node gets stuck in sleeping mode and never wakes up after a while. If I restart a node I do get the wakeup for the gateway somehow does not receive any data after the first wakeup burst and then it seems to work after the second wake up.

Anyhow, I'm still looking at the code but this is a very neat feature! Hopefully you'll add it to the RFM69 library. Thanks again for sharing!

xavier

  • Jr. Member
  • **
  • Posts: 65
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #113 on: December 09, 2015, 01:22:45 PM »
it seems radio.listenReceivedOffset() returns an overflow after a while - havent had a chance to check out why but that's why the loop gets stuck. Once you comment that out and add a delay of 500ms in sleepUntilPacket after the wakeup to give the radio.init on the gateway to recover everything works like a charm! Really neat indeed. 

TomWS

  • Hero Member
  • *****
  • Posts: 1924
Re: Ultra low power listening mode for battery nodes
« Reply #114 on: December 09, 2015, 02:28:06 PM »
it seems radio.listenReceivedOffset() returns an overflow after a while - havent had a chance to check out why but that's why the loop gets stuck. Once you comment that out and add a delay of 500ms in sleepUntilPacket after the wakeup to give the radio.init on the gateway to recover everything works like a charm! Really neat indeed.
I'll take a look at the problems you've reported but I won't be able to get to it for a while.  I'm glad that you've figured it out and have it running!  Good job!

Tom

snorp

  • Jr. Member
  • **
  • Posts: 62
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #115 on: February 12, 2016, 10:04:37 PM »
Things are all hosed up now with the ListenModeExtensions branch because Felix's RFM69 master has a RFM69_ATC class as well. I guess there aren't plans to put the listen mode stuff there, so maybe we need a RFM69_WL (LM?)...

TomWS

  • Hero Member
  • *****
  • Posts: 1924
Re: Ultra low power listening mode for battery nodes
« Reply #116 on: February 13, 2016, 09:11:00 AM »
Things are all hosed up now with the ListenModeExtensions branch because Felix's RFM69 master has a RFM69_ATC class as well. I guess there aren't plans to put the listen mode stuff there, so maybe we need a RFM69_WL (LM?)...
Your choices appear to be:
1. Install the RFM69_ATC library with ListenMode extensions and copy the RFM69_ATC cpp & h files to the RFM69 library folder or...
2. Install the RFM69_ATC library with ListenMode extensions and remove the RFM69_ATC cpp & h files from the RFM69 library folder

Note that the ListenMode extension library also contains the SPI Transaction extensions and will soon be updated with the latest listen mode 'timer' capability (where 'soon' is a nebulous term without any official commit date).

Tom

xavier

  • Jr. Member
  • **
  • Posts: 65
  • Country: us
Re: Ultra low power listening mode for battery nodes
« Reply #117 on: February 13, 2016, 01:44:08 PM »
snorp : you can try the attached version, it worked for me (#1 from Tom's reply) - do note though i could not make the wireless programming work w that version - haven't had a chance to look into it though

Tom: what's the timer capabilities you're talking about? :-)

TomWS

  • Hero Member
  • *****
  • Posts: 1924
Re: Ultra low power listening mode for battery nodes
« Reply #118 on: February 13, 2016, 02:49:34 PM »
Tom: what's the timer capabilities you're talking about? :-)
See thread: https://lowpowerlab.com/forum/index.php/topic,1325.0.html which describes the method and implied power savings.

Basically you setup the RFM69 in ListenMode with a super sensitive RSSI trigger so the RFM69 generates an RX interrupt as soon as the Listen Idle Timer times out.  Joe has thoroughly tested it, but I haven't integrated it into the RFM69_ATC library yet.   I have parts due in on Tuesday that will allow me to test it (assuming I get the code modified  ;)

Tom
« Last Edit: February 13, 2016, 02:54:50 PM by TomWS »

Tomme

  • Newbie
  • *
  • Posts: 24
Re: Ultra low power listening mode for battery nodes
« Reply #119 on: February 20, 2016, 08:04:32 AM »
I'm wondering if anyone can shed any light on a interesting... quirk I've found while working with low power listening.

I'll start, quickly with my setup:
  • Rx Time: 256 us
  • Idle Time: 4096 us
  • Signal Acceptance Criteria: RSSI >= threshold
  • End of cycle action: Stay in Rx until Timeout or PayloadReady, resume listen mode in idle.
  • RSSI Threshold: -75dBm (wanted to avoid interference while development)
  • Timeout2 value: 51
  • Bitrate: 55,555

The above set up works well; packets are received and power consumption is fairly low. However if I increase the idle time from 4.096 ms to say 8.192 ms it stops working, the RSSI is never detected as going above the threshold. If I increase the RX time a little, from 256 us to 384 us, it starts working again. Is there some relationship between the two that I am missing?