Turns out there is a bug in the RFM69HW listen mode which causes the radio to stay in RX even after timeout if address filtering is used and a packet is received that doesn't belong to the node. This caused power waste in non target nodes - all of them wake up when the 3s burst comes and stay in receive for about half of the time.I was wondering about this so I'm not surprised. What I am surprised about is why you haven't set up a 'SleepyTime' network Id. In this case there would be no traffic on that network except a wakeup call from the Gateway (nodes would only listen on it, and possibly Ack). Switching networks is trivial, uses hardware filtering, and the Gateway would only switch during the time that it had to wake up one of the nodes. It is true that all sleeping nodes would wake up, but it would only be for that short, 3 second transmission.
<snip>
@Tom, yes you're right, I could try using the network ID to work around this issue. That said the current workaround isn't any worse. I had thought about switching frequency which would keep the normal channel clean. But since I'm only using this when I need to take control of the clients it's really not such a big deal.Interesting that you think it wouldn't work any better. The sleeping node wouldn't even get a wake up signal if a different Network Id was used and the radio wouldn't stay in RX mode since there wouldn't be a SyncWord match on a 'normal' transmission. What am I missing? On a sparse network, you're probably right, but on a busy network with a lot of nodes, I have to believe letting the processor sleep until there is a 'real' wake up call has to be significant.
Note that the other nodes don't stay awake for the 3 seconds with the current setup. Only for the rx timeout period which is about 20ms.
The sleeping node wouldn't even get a wake up signal if a different Network Id was used and the radio wouldn't stay in RX mode since there wouldn't be a SyncWord match on a 'normal' transmission.
AHA! It didn't 'sync' in that the RX was only 0.64mS, somehow I was seeing this as 6.4mS, which should be enough time for SyncAddressMatch. Ok, now I 'get it'. Thanks for the explanation. It would be interesting to see just how often your node wakes up with an RSSI > -90 from transmissions on the main 'network'. Given the transmit power and receive sensitivity of these radios, I would expect high RSSI levels even if shifted 4MHz.QuoteThe sleeping node wouldn't even get a wake up signal if a different Network Id was used and the radio wouldn't stay in RX mode since there wouldn't be a SyncWord match on a 'normal' transmission.
Actually the way I'm using Listen mode is that the receiver detects only whether RSSI is > -90 for 0.64 ms and then either goes back to sleep or switches into RX for 20 ms to see if there's a packet for it. During that 0.64ms phase there is no sync word detection yet obviously and so the radio would stay in RX anyhow.
The radio stays in RX until either payload available or timeout occurs. If the radio immediately receives a packet on the right network with a wrong target node id that is actually quicker than seeing and ignoring a packet on the wrong network first and hanging around until timeout occurs.I'm still stuck in thinking that SyncAddressMatch provides some useful capability and, if I do try ListenMode, I'll experiment with that. This code provides a good starting point for those experiments. I think this is good work and will be useful to others, including me. Thanks for sharing.
Because of the very low duty cycle regular packet interference isn't much of an issue for sleepy nodes. More problematic is interference of regular traffic by the burst sequences. Both can be solved by moving to a different frequency.
Wrt the usefulness of listen mode: that really depends if you can wake up and read out RSSI manually as quickly as the chip does in listen mode. I haven't tried it - but I'm very happy with how reliably this extreme duty cycle works for me with listen mode.
Tom to test whether interference still exists I did a burst at the old frequency and checked whether the new sleepers would wake up. They didn't.To clarify, by 'wake up' do you mean the node thought it was getting a wake up message or did you probe the interrupt line to see if the burst was causing any interrupts?
if you want to use SyncAddressMatch your busy cycle needs to be an order of magnitude larger to allow the address to be read. Hence a no go for ultra low power environments.Yeah, that's how I first read it too, but then got to thinking that once a carrier is detected and the packet engine starts receiving, the radio will stay in RX mode as long as it takes to receive and check the packet for sync match (if that's the criteria). Unless you've done this experiment and know this is not the case, I think I'll still try it 'at some point' in the future. Still, as I said, this is very useful work!
* Did you also recognised the bug that the RFM do never set the "RF_IRQFLAGS2_PAYLOADREADY" flag in listen mode when a message was received.
I always have to check if a package is available with "RF_IRQFLAGS2_FIFONOTEMPTY"
* I did not understand why you do not want to switch after a TX back to STANDBY/ListenMode. What is the benefit of that?
I am always in ListenMode for the defined cycle except when the client were asked for informations or ACK.
* Regarding your encountered bug of the listen mode. Thats very interesting. How did you recogniced that? I want to check if that also happens in my configuration...
Is the bug also there when I use Adressfiltering and encription?
Tom, when I measure the current of the moteino I see two patterns depending on whether the listener decides to keep the radio on or not. If the radio is on for 20ms instead of .6ms that shows as higher reading on the ampere meter. This is what I did and I could verify that the sleepers did not detect a signal and switched the radio off after .6 ms.Thanks.
As for the chip prolonging the rx cycle even if the criteria hasn't been met in the hope that it might be later on - that behavior for me is inconsistent with the pretty precise wording of the spec. So I'll leave that experiment to you :)I'll accept the 'challenge'! I'll get to it when I finish up everything else... ::)
I do not understand why whitening can improve your listen mode??
Regarding the different sync words, I could imagine that you have another traffic on the frequency which uses the same sync words like you had configured before? That could increase your current consumption because the rfm module may reacts for foreign transmissions?
The minimum RX time in the listen mode is of course a function of your configured bitrate and the configured RX listen timeout time.
What bitrate and RX timeout time do you use?
I think we could decrease the current consumption more if we could get a PayloadReady flag after receiving messages, because otherwise the RFM will always stay in RX mode as long as the RX timeout is not exceed!
Turns out there is a bug in the RFM69HW listen mode which causes the radio to stay in RX even after timeout if address filtering is used and a packet is received that doesn't belong to the node. This caused power waste in non target nodes - all of them wake up when the 3s burst comes and stay in receive for about half of the time.If you have the label "RegRxTimeout1" set to 0, I think the descriped issue will occure. Did you doublecheck to set the label to 0x10 for example?
My rx timeout is so long that it will always include one full packet.
/* 0x03 */ { REG_BITRATEMSB, RF_BITRATEMSB_55555},
/* 0x04 */ { REG_BITRATELSB, RF_BITRATELSB_55555},
/* 0x0D */ { REG_LISTEN1, RF_LISTEN1_RESOL_IDLE_4100 | RF_LISTEN1_RESOL_RX_64 | RF_LISTEN1_CRITERIA_RSSI | RF_LISTEN1_END_10 },
/* 0x0E */ { REG_LISTEN2, 0x40 }, -> 262ms
/* 0x0F */ { REG_LISTEN3, 0x05 }, ->0,320ms
/* 0x2A */ { REG_RXTIMEOUT1, 0x11 }, -> 5ms
/* 0x2B */ { REG_RXTIMEOUT2, 0x20 }, -> 9,2 ms (max 32 bytes payload)
/* 0x37 */ { REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_WHITENING /*RF_PACKET1_DCFREE_OFF*/ |
RF_PACKET1_CRC_ON | RF_PACKET1_CRCAUTOCLEAR_ON |
RF_PACKET1_ADRSFILTERING_NODEBROADCAST },
/* 0x29 */ { REG_RSSITHRESH, 0xE4 /*MAX*/ }
Ulli the way I read the spec is that the listen exit actions only get considered once the listen criteria has been met. With our parameters that means once rssi has been detected. So no RSSI no rx after the .320ms ex period. Only then will the radio continue to receive until a timeout or payload ready occurs.Ah, got it! I tought when it is checking the RSSI value, the module already is in RX mode...
Ulli, I gave it one more shot with address filtering. I still get the same problem even with timeout1 set. You should really measure if you don't get the same problem.Did you measure the current with a simple multimeter? I will give it a try later and let you know...
BTW, I think your timeout2 is set way too tight. You don't know where in the packet your rx cycle hits - so you might need to wait for the next one. Then there are a couple of bytes of overhead (3x preamble, 2x network, size, node, crc). Finally there might be pauses between packets.You are right, I just did the calculation with the payload... :-/
Also your RSSI threshold is very low which will likely result in phantom signal detection and increased battery use.
BTW Ulli, if unlike me you have frequent traffic to the listening nodes you could consider a two step protocol where the listening node is only woken up and then pings the gateway for the next command.
This would drastically reduce the waking packet size (say fixed length packet, payload 1 byte, sync word 1 byte, preamble 1 byte etc) and therefore timeout2, hence reducing power consumption for other sleeping nodes.
listen.cpp:In static member function 'static void RFM69Listener::startListening(RFM69&, void*, uint8_t)'
listen.cpp:47:26: error: no matching function for call to 'RFM69::getAddress()'
listen.cpp:candidate is
RFM69ULP.h:getAddress(uint8_t)
RFM69ULP.h:candidate expects 1 argument, 0 provided
RFM69ULP.cpp:In member function 'void RFM69::getAddress(uint8_t)'
RFM69ULP.cpp:187:33: error: no matching function for call to 'RFM69::readReg(int, uint8_t&)'
RFM69ULP.cpp:candidate is
RFM69ULP.h:readReg(uint8_t)
RFM69ULP.h:candidate expects 1 argument, 2 provided
I ran a couple of tests prototyping this setup:Yes, pretty impressive. Good work! I did expect the opposite effect, waking the AVR via WDT periodically rather than the radio, but, I guess the 'secret sauce' is that you can achieve a much lower duty cycle with the radio than with an 8 second max WDT timeout...
When running without WDT but with radio in listen mode I measure a sleep current of 1.1uA. Running at 200kbaud I was able to cut down the listen period to 0.256 ms for an average power consumption for the receive spikes of 0.256ms / 2882ms * 16ma = 1.4uA. With that the total average sleep current is 2.5uA.
It's actually pretty amazing: I now have to short 3.3V against GND to get the Moteino to reset - the 10uF cap on the board powers the processor in sleep for what seems like an eternity ;)
Joe
I guess the 'secret sauce' is that you can achieve a much lower duty cycle with the radio than with an 8 second max WDT timeout...
I forget your wakeup protocol. Does the gateway send to a specific node? Presumably all nodes wake up but only the one that was addressed responds while the others go back to sleep?QuoteI guess the 'secret sauce' is that you can achieve a much lower duty cycle with the radio than with an 8 second max WDT timeout...
No that's not it - the WDT circuit on the atmega328p itself uses about 4uA at 3V. That's the problem. Without WDT the chip uses much less than 1uA, so the 1.1uA power consumption is primarily RFM69HW in listen mode (or basically just its RC Oscillator running).
I can reach almost all my nodes at 200kbaud using the RFM69HW at full transmit power (haven't tested this mode at lower transmit power settings yet). This is the weekend home, so the distances are not huge - maybe 60m for the longest distance to the gateway. The one exception is the moteino in the sewage pit which is about 40 cm below ground with a metal lid on top, so it has a right to be stubborn when the ground is wet. When it is the bootloader selects the 19200baud profile because nothing else works reliably.
I think all of this should work very nicely although there is still a lot of work to do. The nodes will get a command with the wakeup call - so there will be no ack required to receive commands. I'll have all the coin cell nodes work on a separate frequency and eliminate the carrier sense code in send frame. Since it will never be busy doing acks the receiving node should always be ready to receive and I expect very low packet loss. Without acks I won't have retransmits but since the server requested the node updates it will know which updates are missing (effectively the updates are acks from the clients to the server).
All of this should minimize active time for the nodes and thus maximize battery life.
The largest piece of work is the boot loader which is anything but low power at the moment. This will require a major redesign.
For the node in the pit, you can run some 50ohm typical coax to an antenna above grade and that should make that node very "loud".Yeah, you can use the u.fl connector that Felix provided the footprint for ;)
I forget your wakeup protocol. Does the gateway send to a specific node? Presumably all nodes wake up but only the one that was addressed responds while the others go back to sleep?
By the way, while you're redesigning your bootloader, see if there is a way to do it (in low power mode) without external flash ;D
Tom
const uint8_t profiles[][5] = {
#if 0
// CFG0: 28kb 1750 ms
{ RF_BITRATEMSB_300000, RF_BITRATELSB_300000,
RF_FDEVMSB_100000, RF_FDEVLSB_100000,
RF_RXBW_DCCFREQ_000 | RF_RXBW_MANT_16 | RF_RXBW_EXP_0 },
// sleep server 1800
// timeout client 10
#endif
// CFG1: 28kb 2200 ms
{ RF_BITRATEMSB_200000, RF_BITRATELSB_200000,
RF_FDEVMSB_100000, RF_FDEVLSB_100000,
RF_RXBW_DCCFREQ_000 | RF_RXBW_MANT_16 | RF_RXBW_EXP_0 },
// sleep server 2400
// timeout client 10
// CFG2: 28kb 7100 ms
{
RF_BITRATEMSB_55555, RF_BITRATELSB_55555,
RF_FDEVMSB_50000, RF_FDEVLSB_50000,
RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_16 | RF_RXBW_EXP_2 },
// sleep server 8500
// timeout client 30
// CFG3: 28kb 18500 ms
{
RF_BITRATEMSB_19200, RF_BITRATELSB_19200,
RF_FDEVMSB_50000, RF_FDEVLSB_50000,
RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_16 | RF_RXBW_EXP_2 } // (BitRate < 2 * RxBw)
// sleep server 23000
// timeout client 50
};
/*******************************************************************************
*
* Argument Description
* ========= ===========
*
* 2. adc ADC module disable control:
* (a) ADC_OFF - Turn off ADC module
* (b) ADC_ON - Leave ADC module in its default state
*
* 3. timer2 Timer 2 module disable control:
* (a) TIMER2_OFF - Turn off Timer 2 module
* (b) TIMER2_ON - Leave Timer 2 module in its default state
*
* 4. timer1 Timer 1 module disable control:
* (a) TIMER1_OFF - Turn off Timer 1 module
* (b) TIMER1_ON - Leave Timer 1 module in its default state
*
* 5. timer0 Timer 0 module disable control:
* (a) TIMER0_OFF - Turn off Timer 0 module
* (b) TIMER0_ON - Leave Timer 0 module in its default state
*
* 6. spi SPI module disable control:
* (a) SPI_OFF - Turn off SPI module
* (b) SPI_ON - Leave SPI module in its default state
*
* 7. usart0 USART0 module disable control:
* (a) USART0_OFF - Turn off USART0 module
* (b) USART0_ON - Leave USART0 module in its default state
*
* 8. twi TWI module disable control:
* (a) TWI_OFF - Turn off TWI module
* (b) TWI_ON - Leave TWI module in its default state
*
*******************************************************************************/
void TurnOffFunktions(bod_t bod, adc_t adc, ain_t ain, timer2_t timer2, timer1_t timer1, timer0_t timer0, spi_t spi, usart0_t usart0, twi_t twi, wdt_t wdt) {
// Temporary clock source variable
unsigned char clockSource = 0;
if(bod == BOD_OFF) {
// turn off brown-out enable in software
MCUCR = bit (BODS) | bit (BODSE); // turn on brown-out enable select
MCUCR = bit (BODS); // this must be done within 4 clock cycles of above
}
if (timer2 == TIMER2_OFF) {
if (TCCR2B & CS22) clockSource |= (1 << CS22);
if (TCCR2B & CS21) clockSource |= (1 << CS21);
if (TCCR2B & CS20) clockSource |= (1 << CS20);
// Remove the clock source to shutdown Timer2
TCCR2B &= ~(1 << CS22);
TCCR2B &= ~(1 << CS21);
TCCR2B &= ~(1 << CS20);
power_timer2_disable();
} else if(timer2 == TIMER2_ON) {
if (clockSource & CS22) TCCR2B |= (1 << CS22);
if (clockSource & CS21) TCCR2B |= (1 << CS21);
if (clockSource & CS20) TCCR2B |= (1 << CS20);
power_timer2_enable();
}
if (ain == AIN_OFF) {
DIDR1 |= (1 << AIN1D) | (1 << AIN0D);
} else if(ain == AIN_ON) {
DIDR1 &= ~((1 << AIN1D) | (1 << AIN0D));
}
switch(adc) {
case ADC_OFF:
ADCSRA &= ~(1 << ADEN);
DIDR0 |= (1 << ADC5D) | (1 << ADC4D) | (1 << ADC3D) | (1 << ADC2D) | (1 << ADC1D) | (1 << ADC0D);
power_adc_disable();
break;
case ADC_ON:
power_adc_enable();
DIDR0 &= ~((1 << ADC5D) | (1 << ADC4D) | (1 << ADC3D) | (1 << ADC2D) | (1 << ADC1D) | (1 << ADC0D));
ADCSRA |= (1 << ADEN);
break;
case ADC0_OFF:
DIDR0 |= (1 << ADC0D);
if((DIDR0 & 0x3F) == 0x3F) {
ADCSRA &= ~(1 << ADEN);
power_adc_disable();
}
break;
case ADC0_ON:
power_adc_enable();
DIDR0 &= ~(1 << ADC0D); //Just Turn ADC0 on
ADCSRA |= (1 << ADEN);
break;
case ADC2_OFF:
DIDR0 |= (1 << ADC2D);
if((DIDR0 & 0x3F) == 0x3F) {
ADCSRA &= ~(1 << ADEN);
power_adc_disable();
}
break;
case ADC2_ON:
power_adc_enable();
DIDR0 &= ~(1 << ADC2D); //Just Turn ADC0 on
ADCSRA |= (1 << ADEN);
break;
default: break;
}
if (timer1 == TIMER1_OFF) {
power_timer1_disable();
} else if(timer1 == TIMER1_ON) {
power_timer1_enable();
}
if (timer0 == TIMER0_OFF) {
power_timer0_disable();
} else if(timer0 == TIMER0_ON) {
power_timer0_enable();
}
if (spi == SPI_OFF) {
SPCR &= ~(1<<SPE);
power_spi_disable();
} else if(spi == SPI_ON) {
power_spi_enable();
SPCR |= (1<<SPE);
}
if (usart0 == USART0_OFF) {
UCSR0B &= ~((1<<RXEN0) | (1<<TXEN0));
power_usart0_disable();
} else if(usart0 == USART0_ON) {
power_usart0_enable();
UCSR0B |= (1<<RXEN0) | (1<<TXEN0);
}
if (twi == TWI_OFF) {
TWCR &= ~(1<<TWEN);
power_twi_disable();
} else if(twi == TWI_ON) {
power_twi_enable();
TWCR |= (1<<TWEN);
}
if (wdt == WDT_OFF) {
wdt_reset();
wdt_disable();
WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = 0x00;
/* } else {
wdt_enable();
WDTCSR |= (1 << WDIE);
*/
}
}
@joelucid: How do you proceed on your low power moteino when they are receiving a burst which has a duration of e.g. 3 seconds.
Is the low power moteino waiting for e.g. 3 sec as worst case (RX: 3sec->16mA) till it can send the ACK or the requested information back to your gateway?
Now that's interesting. Ulli, it was a good question and with your answer Joe, it seems as if you must go back to sleep but no longer in Listen Mode but this time with WDT wakeup a few seconds later? And how do multiple nodes avoid collision when they finally reply to the gateway?Quote@joelucid: How do you proceed on your low power moteino when they are receiving a burst which has a duration of e.g. 3 seconds.
Is the low power moteino waiting for e.g. 3 sec as worst case (RX: 3sec->16mA) till it can send the ACK or the requested information back to your gateway?
Well as soon as a Moteino wakes up it goes right back to sleep for 3s to ensure that the burst is over and then it reports back to the server. It certainly doesn't sit in receive @ 16 mA for 3s.
I actually do stay in listen mode - that's not a problem since the listen window won't be hit until the WDT hits.Why is that? ISTM that if a burst of packets produce a hit, then subsequent packets within the same burst may produce a hit also since the listen window is slightly narrower than the burst width (as I understand it).
I do have to use the WDT for that delay obviously. From an energy budget point of view that's not relevant since its 4uA with a duty cycle of say 3s : 180s.Understood, just confirming.
Collisions are unlikely to happen...Boy, if I only had a nickle... ;)
Why is that? ISTM that if a burst of packets produce a hit, then subsequent packets within the same burst may produce a hit also since the listen window is slightly narrower than the burst width (as I understand it).
Boy, if I only had a nickle... ;)
Ah just thought of the solution to the collision problem: I'll have a counter in each burst packet. That way a client knows when in the burst it woke up and can time it's response. I'll just cut the response window into n slices and have each node respond during one of them.Well, I was pulling your chain in the previous post, because, as you say, this is not mission critical stuff and you'll get the data on the next cycle. Having said that, yes, I do like this particular solution. Good job!
No collisions, no busy spinning, faster response after burst end - everybody happy :)
No collisions, no busy spinning, faster response after burst end - everybody happy :)I forgot to mention in my previous post, it's always good to keep your bathroom fan happy! DAMHIKT!
Well, I was pulling your chain in the previous post, because, as you say, this is not mission critical stuff and you'll get the data on the next cycle.
...I'll just cut the response window into n slices and have each node respond during one of them.Do you mean that each node will have a specific time slot to respond and they'll 'know' when to schedule the time slot based on when they detected the burst (from the counter you're adding)?
Do you mean that each node will have a specific time slot to respond and they'll 'know' when to schedule the time slot based on when they detected the burst (from the counter you're adding)?
What's the update frequency?TH sampling occurs once per 10 minutes (based on Mote internal RC 8MHz clock). Async push to the Gateway. Mote status update (battery and transmit levels) occurs every 6 samples (once per hour).
Hi,Assuming your power supply is at least 3V, then, yes, that MOSFET will be fine. It's too bad the data sheet doesn't show the drain current vs Vgs at lower currents, but it appears to be more than enough for this application.
I currently also work on a new circuit design to further reduce the power consumption of my battery powered moteino. I plan to do something similar with Toms circuit a few replies above.
I understood your posts in that why, that a more or less constant current consumption results in better battery life than current peaks caused by the Listening Mode or frequently transmissions.
--> So, the target is to make the current consumption as smooth as possible with a well defined cap, which buffers the transmissions and listening mode current peaks?
What do you think about using the IRLML6402 Mosfet instead of SI2365? (No supplier is available which makes sense for me)
It has a very low on resistance and should work with 3.3V on/off.
http://www.irf.com/product-info/datasheets/data/irlml6402.pdf
Am I right?
Thats a good point. I am using 2x AA batteries which should work down to 1.8V due to the limit of the RFM Module and the Atmega.Ulli, if you're using AA batteries then you don't need the switches. Your mote will power up without any problem. The switches and caps are there to limit the power surge to a coin cell battery which doesn't deal well with the high current surge. AA will literally last for years. Basically the shelf life of the battery.
Addi tonally the capacitor have to be way bigger than I thought before to also provide enough energy for the transmission. -> voltage drop must be minimized.
Do you think the Mosfet will also work with 1.8V. The Datasheet shows a VGS(max) of 1.2V...Doesn´t it mean that I can use it down to 1.2V control voltage of the Gate?
Looking forward to your final design and test results.
Thats a good point. I am using 2x AA batteries which should work down to 1.8V due to the limit of the RFM Module and the Atmega.Don't count on the RFM HW boards from HopeRF to go down to 1.8V as claimed in the datasheet. The fact is that the switcher they use is a 2.4V GaAs device (the SC70 chip). So only the RFM69-W which don't have that part will probably be reliable down to 1.8V. On the RFM69HW you probably don't care anyway since it's a 100mW TX device and you use it for the power not for saving the battery to the absolute maximum.
This is an interesting question since if the pulsed load hurts it would make sense to put a resistor in front of the load. This might make sense anyway since it would cause the system to restart if it gets stuck in receive etc instead of damaging the battery. I'm currently running a test to verify this.
current module lifetime of only 3 month in ListenMode
The cited quote is actually joelucid's, not mine, but, in any case, AA can handle much larger current surges than 25mA (probably in the order of hundreds of mA) keeping in mind that they are probably not as 'elastic' as coin cells WRT to using mAH precisely because the chemistry is 'consumed' quickly due to the AA's low ESR. It also depends on whether you're using Lithium or Alkaline AAs.This is an interesting question since if the pulsed load hurts it would make sense to put a resistor in front of the load. This might make sense anyway since it would cause the system to restart if it gets stuck in receive etc instead of damaging the battery. I'm currently running a test to verify this.
Sorry for the late feedback...
As already stated, I use 2xAA batteries. I further need to reduce the power consumption due to a current module lifetime of only 3 month in ListenMode with a few infrared transmissions.
You are right that I do not need the cap for limiting the power surge/voltage drop like it is on a coin cell battery.
I am thinking about your cap solution with an additional series resistor to reduce the current peaks. I think current peaks(Listen 4µA -> RX 25mA) reduces the lifetime of a AA battery, doesn´t it?
Thanks for the quick response.
I use Alkaline AAs and I attached my circuit maybe there is a design issue?
Thanks for the quick response.Ulli, I would add to Joe's comments with:
I use Alkaline AAs and I attached my circuit maybe there is a design issue?
For example I've been running a DHT22 based thermometer using 2x lithium aaa for at least a month. During that time vcc has dropped from 3.63V to 3.62V.@Ulli, I've gathered Battery data for a Mote I deployed in April. This Mote measures the water level in a man-made stream I have, uses two AAA Lithium batteries and, even running with WDT sleep (not Listen Mode) cycles, the voltage actually started lower (3.473 when deployed) and has worked its way up as high as 3.641, to 3.527 at 6:48 this morning (130 days later). The initial voltage was low due to start up configuration loading as I fiddled with it and most of the variation over time has been probably due to temperature variations as opposed to any real drain on the batteries.
Thanks for the quick response.Ulli, I would add to Joe's comments with:
I use Alkaline AAs and I attached my circuit maybe there is a design issue?
1. are you sure ALL inputs to the ULN2003 are pulled to ground when Idle?
2. Have you set the fuses to run on internal clock at 8MHz?
3. Is A0 programmed to be a Digital Input (not Output)?
4. How often and what duty cycle is the IR LED pulsed?
Tom
pinMode(A3, OUTPUT);
digitalWrite(A3, LOW);
low_fuses=0xE2
high_fuses=0xDA
extended_fuses=0x07
pinMode(RFM69_ResetPin, INPUT);
/* 0x0E */ { REG_LISTEN2, 0xFF },
/* 0x0F */ { REG_LISTEN3, 0x01 },
-> in idle mode I need 28µA (with WDT enabled)The 4uA delta makes sense with and without WDT. The real question is, where is the 24uA being consumed? But even this doesn't add up to the poor battery life you've gotten. One more question: When you send to the gateway, do you send with retry and, if so, how many tries? I've totally stopped sending with retry on the coin cell Mote (although I do request an Ack - I need this to be able to get the received RSSI back from the Gateway).
-> in idle mode I need 24µA (without WDT enabled)
On a somewhat related note, I have had my TTH Mote stop responding to wake up bursts on two occasions in the last week. I normally generate the wake up burst every ten minutes from my gateway but I can also generate a wake up burst from my Snooper. I tried this as well, but this also did not wake up the mote. I'll have to put a scope on it to see if its still going through listening cycles when it's not responding, but wondering if you've seen this at all.
I've only run motes in listen mode without WDT for testing. My current "Production" setup is still listen mode + WDT. Sometimes I can't manually reach listening motes - but it's always been motes that are hard to reach anyway. But I don't nearly have the same sample set as you with regular 10 minute listen wakeups.Ah, ok. Some of the code I saw in a recent file of yours makes sense now - basically a counting loop with WDT sleep. So if a wake up burst hasn't happened within the counting window, you treat it as a 'wake up' anyway, yes?
@felix, the key to making the low duty cycle work is the continuous transmission. I know the spec mentions something about a 1% duty cycle limitation but I've never seen this as a problem so I wonder if they are mentioning a regulatory constraint. Even with wireless boot and particularly if I need to downgrade to 19200 baud I have the gateway send for up to 30s at full power and it's never been a problem. During testing I've had nodes transmit at full power for minutes without ill effect.
Joe
Since bad news doesn't get better with time, I may as well just say it: I'm quite sure there is going to be a regulatory constraint on duty cycle, no matter where you live, and it would be because you're jamming the channel if operating in continuous mode for an extended period of time
As an alternative, for the RFM69, I was planning to use an accurate clock to try to send the packets only around the time when the radio might be ready to receive them
QuoteAs an alternative, for the RFM69, I was planning to use an accurate clock to try to send the packets only around the time when the radio might be ready to receive them
I've looked at a couple of HW options for this today. Maybe the most promising is this (http://abracon.com/Precisiontiming/AB08X5-RTC.PDF). If Tino had one of these on board and each node had an assigned second period each minute during which it should listen average battery would come down significantly below 1uA. Which would truly give you a decade even on cr2032.
QuoteAs an alternative, for the RFM69, I was planning to use an accurate clock to try to send the packets only around the time when the radio might be ready to receive them
I've looked at a couple of HW options for this today. Maybe the most promising is this (http://abracon.com/Precisiontiming/AB08X5-RTC.PDF). If Tino had one of these on board and each node had an assigned second period each minute during which it should listen average battery would come down significantly below 1uA. Which would truly give you a decade even on cr2032.
I can see on the oscilliscope that ListenResolIdle and ListenCoefIdle actually do control how long Listen-Mode's idle period lasts, but I'm starting to get the impression that the values set for ListenResolRx and ListenCoefRx are irrelevant.
QuoteI can see on the oscilliscope that ListenResolIdle and ListenCoefIdle actually do control how long Listen-Mode's idle period lasts, but I'm starting to get the impression that the values set for ListenResolRx and ListenCoefRx are irrelevant.
That's correct. It's the misunderstanding just about anybody using listen mode seems to run into. The RX parameters control how long the radio looks for a signal (RSSI > Threshold) before deciding whether to go into RX. They can be much smaller than the duration of a whole packet. When the radio has switched into RX the timeout parameters control the size of the window.
It's very repetitive and the 20.4ms seems to match. ListenRx seems to play no role that I can see.
No, no. There are three phases in listen mode. 1. Idle, 2. RX and 3. actually trying to receive data. The current consumption in 2. and 3. is both 16 mA. You can configure how much evidence for the existence of data listen mode needs to move from 2. to 3. - either RSSI exceeds threshold or node address matches (which causes the bug I had described). When in 3. the action is controlled by the timeouts. The RX listen parameters determine how long listen mode stays in stage 2 before moving back to 1. if no signal is found.
Clear now?
On the other hand, suppose at some point RSSI > threshhold during the Rx. Then, if and only if the pre-amble is detected (correct?) the tListenRx timer is aborted and the RegRxTimeout2 countdown timer is started. If it reaches zero before 1. data payload is ready, and 2. if no further preambles have been detected, then Rx is exited and TListenIdle is started. However, if another pre-amble is detected before the data payload is ready and before the countdown timer reaches zero, then the countdown timer is reset to RegRxTimeout2, and the countdown starts over again.
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.
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 );
}
Any suggestions on how to debug to see what is going on or if I missed anything obvious?
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?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")
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...
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!
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:
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.
I'm wondering if anyone can shed any light on a interesting... quirk I've found while working with low power listening.What are the exact values you're using in LISTEN1, LISTEN2, and LISTEN3 regs in both cases?
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?
8.192ms sounds suspiciously close to when the atmega328p might be in the middle of waking.....
What are the exact values you're using in LISTEN1, LISTEN2, and LISTEN3 regs in both cases?
Tom
Thanks for the info, but, sorry, I'm not seeing it. Joe is the maven on these settings but he's been tied up the last couple of days. Maybe he'll be around tomorrow and can comment on it.8.192ms sounds suspiciously close to when the atmega328p might be in the middle of waking.....
I should say that there is nothing special about the 8192 us number. If I change it by a few increments, it still doesn't work. I'm also looking at the power consumption of the radio on a scope so I can see it entering/exiting idle and rx modes so I can see that the timings for both idle and rx are correct.What are the exact values you're using in LISTEN1, LISTEN2, and LISTEN3 regs in both cases?
Tom
LISTEN1: 0x54 (0b01010100)
LISTEN2: 0x40 (4.1 ms) or 0x80 (8.2 ms)
LISTEN3: 0x04 (256 us) or 0x06 (384 us)
So:
256 us and 4.1 ms - works.
256 us and 8.2 ms - does not work.
384 us and 8.2 ms - works.
I've found that you need at least 384uS with a 55kbit data rate. 256uS only works with 200kbit in my setup. So I'm actually surprised that you could sporadically get 256uS to work at 55kbit. There should be no connection to the idle period unless your tx burst is shorter than the idle period.
So I'm actually surprised that you could sporadically get 256us to work at 55kbit.
TS_RE_AGC Receiver wake-up time, from PLL locked state, AGC enabled
RxBw = 10 kHz, BR = 4.8 kb/s, 3.0ms
RxBw = 200 kHz, BR = 100 kb/s, 163us
Receiver wake-up time, from PLL
locked state to RxReady
RxBw = 10 kHz, BR = 4.8 kb/s, 1.7ms
RxBw = 200 kHz, BR = 100 kb/s, 96us
There are also a couple of other nuggets in there. Observe for example that:I'm missing the AGC connection in this quote...QuoteReceiver wake-up time, from PLL
locked state to RxReady
RxBw = 10 kHz, BR = 4.8 kb/s, 1.7ms
RxBw = 200 kHz, BR = 100 kb/s, 96us
In other words RxReady is reached much quicker if automatic gain control is off.
I'm missing the AGC connection in this quote...
TS_RE_AGC Receiver wake-up time, from PLL locked state, AGC enabled
RxBw = 10 kHz, BR = 4.8 kb/s, 3.0ms
RxBw = 200 kHz, BR = 100 kb/s, 163us
In other words RxReady is reached much quicker if automatic gain control is off.
"RSSI sample time: Trssi = 2 x int(4.RxBw.Tbit)/(4.RxBw) (aka TS_RSSI)"
Will you also be keeping the AM1805 in close enough sync with the sender's RTC (or maybe visa versa), so that the the sender doesn't have to spray packets over the full 3 second interval, but instead over a much narrower window that the receiver is likely to be actually listening?
Listen mode nodes listen for wakeup signals using 300kbit and 500khz RxBw without AGC, resulting in total time in Rx to RSSI detection of less than 198us - potentially significantly less if receiver wake-up time reduces similarly from 200khz RxBW to 500khz RxBW as it does from lower RxBWs.
The expectation here is not to actually try to receive packets at these super aggressive settings (potentially underground). It's just to detect the gateways willingness to send packets. Once a node knows the gateway wants to send a packet it switches to rx using more conservative settings.
Just a thought, but you may want to run your RSSI detection in OOK Rx mode, as it appears there would be less chance of a false positive resulting from noise: https://lowpowerlab.com/forum/index.php/topic,1468.msg11931.html#msg11931
Puzzling, but real.
The comparison isn't entirely fair because this mote is powered from 9V via a buck converter. But anyway: I'm measuring 590nA total average current in this mode. That's for a mote that's reachable in 1.5s on average at any time. Including 328p and radio sleep current etc.
How exactly are you achieving a current draw that is less than the RFM's idle current draw (1.2 uA)? Is that 590 nA at 9 V or are you sleeping the radio module for some amount of time?
does this mean that theoretically we shouldn't be able to do better than 250 uS +80 uS + TS_RE?
Do you mean that we specify the RX period and the oscillator is automatically started 250 uS before the scheduled RX time?
I wanted to avoid gaps in the burst so that the rx window could be as small as possible. You can certainly switch to standby and back between packets so that encryption works. But then your rx window needs to be at least as long as the gap in the burst.
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?Good job on the integration! One flaw in the current ATC code and carried into your is the RSSI_Threshold value:
https://github.com/snorp/RFM69_WL (https://github.com/snorp/RFM69_WL)
(0) https://github.com/TomWS1/RFM69_ATC/tree/ListenModeExtensions
writeReg(REG_RSSITHRESH, 200);
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]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.writeReg(REG_RSSITHRESH, 200);
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).
In any case, setting the RSSI threshold to 170db seems to avoid waking up from the noise in my office.
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.QuoteI 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?
LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
In the listening mode node example on github there is: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.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...
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).
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.
I think the main problem here is that the listening nodes would have to be awake a lot longer (the entire duration of a listen cycle) when they are woken up. For most folks, that's going to be more like 1-2s rather than 15ms. With the message burst you can sleep the radio/cpu after receiving the packet.
I think the 3s burst is to give the client up to 3 chances to latch a burst packet and wake up. We could reduce the sleep time of the listen cycle, so that we could use a 1s instead of 3s burst.
I think the 3s burst is to give the client up to 3 chances to latch a burst packet and wake up. We could reduce the sleep time of the listen cycle, so that we could use a 1s instead of 3s burst.
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 (https://github.com/snorp/RFM69_WL)
(0) https://github.com/TomWS1/RFM69_ATC/tree/ListenModeExtensions
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 (https://github.com/snorp/RFM69_WL)
(0) https://github.com/TomWS1/RFM69_ATC/tree/ListenModeExtensions
Hello ,
I am interested in use the low power listening mode, so I decided to give a try to the snorp branch of the rfm69 library -->https://github.com/snorp/RFM69_WL (https://github.com/snorp/RFM69_WL), and it work fine.
I tried to do the same test with Felix examples provided in the development library https://github.com/LowPowerLab/RFM69/tree/ListenMode (https://github.com/LowPowerLab/RFM69/tree/ListenMode) but it won't work.. node go sleep ok.. I am monitoring the current while slepping.. it shows 1.6ua .. current start to increase in steps u to 94ua, then go down to 1.6ua .. the cycle is repeated, but the problem is the sleeping node wont wake up when burst is sent from the other node .
not sure what I am missing? I have repeated the test several times.. with no luck
is there any hardware connection that need to be set to get it working properly?
any program setting that need to be adjusted ??
I am using moteinos with RFM69w.
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 (https://github.com/snorp/RFM69_WL)
(0) https://github.com/TomWS1/RFM69_ATC/tree/ListenModeExtensions
Hello ,
I am interested in use the low power listening mode, so I decided to give a try to the snorp branch of the rfm69 library -->https://github.com/snorp/RFM69_WL (https://github.com/snorp/RFM69_WL), and it work fine.
I tried to do the same test with Felix examples provided in the development library https://github.com/LowPowerLab/RFM69/tree/ListenMode (https://github.com/LowPowerLab/RFM69/tree/ListenMode) but it won't work.. node go sleep ok.. I am monitoring the current while slepping.. it shows 1.6ua .. current start to increase in steps u to 94ua, then go down to 1.6ua .. the cycle is repeated, but the problem is the sleeping node wont wake up when burst is sent from the other node .
not sure what I am missing? I have repeated the test several times.. with no luck
is there any hardware connection that need to be set to get it working properly?
any program setting that need to be adjusted ??
I am using moteinos with RFM69w.
Not sure if it's related but mine only goes down to 6uA in listennode (running at 3v, regulator removed, 8mhz internal oscillator). I wasn't aware of the snorp branch, I'm using the listennode branch from Felix's github, and it works fine for me.
I have been testing with a RSSI threshold of 255 because I want to ensure that the device was attempting to receive the opportunity for now. The other issue I have with this radio is the lack of a relative RSSI threshold, I have no idea what a good absolute threshold is given that I don't control the environment the devices will be in. I also have no idea what the current sensitivity is given the bitrate and deviation, can anyone point me in the right direction?It may sound counter-intuitive, and it isn't what the library seems to recommend, but I think the current consensus opinion (well, three of us anyway) is to leave RSSI threshhold at 255. JoeLucid has written about why that works, and it's motivated by the reasons you say.
Regardless of the listen mode configuration I see a significant drops in range. I am using the low power version and I see around 120m when purely in RX mode, however when going into Listen I struggle to get above 70m.
So basically I could use listen mode as I have it setup now with a RSSI threshold of 255. I could even turn RSSI off if that is an option. This would of course mean the radio would wake up for the full duration of the timeout2 every time but at least that means the issue of needing to see the preamble for a good RSSI reading may not be an issue?
The fact that we wake up regularly I could check the radio state and potentially correct for it having gotten stuck in RX for example?
Instead of using listen mode, I create the same listen mode setup as I described in option 1 however manually.
Find a new micro like the SI4463 or the CMT2300AW.
The previous system used the MRF49XA which is what the RFM12B is cloned off. I would need to ensure that those devices are able to handle the long preamble given that they expect 3 byes currently and we are not able to reprogram them. Do you recommend increasing the normal preamble length for each packet or just to send a large preamble for wakeup purposes.
The issues are subtle - everything will seem fine but after a week your first node drops off. Or everything runs fine for months but when you have a loud noise signal your radios will wake up and never go to sleep again, draining the battery. It just depends on how many levels of workarounds you already have implemented.
Have you ruled out your power source (in your case, typically button cells if I'm not mistaken) as a contributing factor? Just wondering if you encountered the same problems with a more stable voltage source.
As usual, you have great information to share. Thanks!
I am very interested in implementing the RSSI check you have used however I am again unsure as to how to determine the threshold value. Is there no formula or something that defines the sensitivity? Is the only way to scale it by hand and in order to find the correct value? My concern is that the RF environment in the office is obviously very different to where our devices are used so is that a sensible method? I guess regardless of the environment there will be a point at which all of them will trigger falsely.
Have you ruled out your power source (in your case, typically button cells if I'm not mistaken) as a contributing factor? Just wondering if you encountered the same problems with a more stable voltage source.
I have had these issues with coin cells and also with 9V battery powered moteinos. I have one moteino with removed regulator running from 2x aaa lithium which has never had the issue.
That makes me think the LDO is the cause...
That makes me think the LDO is the cause...Doesn't follow. The coin cell units didn't have LDO VR either. However, both the coin cell and 9V unit with VR would have a higher ESR and the 2xAAA lithium would have a higher voltage (3.4-3.6 typ).
Actually, Joe's "manual" way of doing it shouldn't require a whole lot more current (percentage wise at least), and it has the benefit of making the code more portable to different radios that may not have a built-in listen mode.
Doesn't follow. The coin cell units didn't have LDO VR either. However, both the coin cell and 9V unit with VR would have a higher ESR and the 2xAAA lithium would have a higher voltage (3.4-3.6 typ).
Say, Tom, you have been using listen mode quite a bit and for quite a long time now, if I'm not mistaken. Have you too encountered the kind of issues with it that Joe has described?LOL! I gave up on Listen Mode before Joe did. He is a persistent bugger! I'm not. I got a few hangs that killed my motes and drained my batteries and that was enough for me. I'm a very dedicated fan of TPL5010s! KISS the Listen Mode goodbye!
Yeah you have to tune it dynamically. A predefined value can only be used if you have such a strong signal that you can set your thresh a massive distance from the sensitivity and have room for e.g. noise issues.
Something like this: whenever you get a ghost activation increase the threshold by one and wait a second. Whenever you haven't had a ghost activation in 10 minutes decrease the threshold by one. The waiting period prevents racking up the threshold too high for an intermittent noise source. And waiting 10 minutes to decrease means that you'll only get one ghost activation every 10 minutes in equilibrium.
But yeah it's a challenging problem. In my gateway I have a similar problem where I need to detect whether a signal exists at a given bitrate to enable multiple clients to send at differing bitrates. There I use address match instead of RSSI because the gateway is mains powered and I didn't want to manage RSSI for 50 channels x 5 bitrates.
Joe
The issues are subtle - everything will seem fine but after a week your first node drops off. Or everything runs fine for months but when you have a loud noise signal your radios will wake up and never go to sleep again, draining the battery. It just depends on how many levels of workarounds you already have implemented.
I have users who use ListenMode without a problem.
Also see the other blinds project with ListenMode (https://lowpowerlab.com/forum/projects/battery-powered-solar-recharged-automated-blinds/). Specs and details in his shop (https://www.tindie.com/products/blebson/blind-automation-moteino-shield-with-solar-charger/).
in the R5 and R6 with the extra cap.what extra cap?
The extra cap was added to the DTR/reset circuit and should not have anything to do or impact ListenMode.
Reports of freezing/not waking from ListenMode have been reported on R4 as well, so this is not related to the R6 hardware change.
LOL! I gave up on Listen Mode before Joe did. He is a persistent bugger! I'm not. I got a few hangs that killed my motes and drained my batteries and that was enough for me. I'm a very dedicated fan of TPL5010s! KISS the Listen Mode goodbye!
Communicating with the GW on a scheduled basis works for me for virtually all my battery powered motes. If I enter a mode in which I need to communicate more often than the TPL timer (like I just turned on a Sprinkler Valve that may need to be turned off right away) I'll switch to use Listen Mode as a 2.8 second timer only and only during this critical period.
Tom
Tom - Are you using the TPL5010s to synchronize across the GW and nodes? I have some ideas on how to do that, and how to re-sync every now and then to account for the 1% variance the timer mentions it can have. Im curious how you achieved that, do you have a github with such an example?I use the TPL5010 as a Watchdog on ALL of my devices because I want them to work without any intervention. On most of my motes, I also use the TPL5010 as a basic time keeper, simply because it's simpler using the Done signal to wakeup the Mote and have it do its thing - there's no programming effort to get this to work (other than the interrupt handler that simply sets a SW flag that the Interrupt has occurred - one line of code).
I could probably post my TPL5010 'library' there.Done!