Packet Error Rate

Started by ChemE, May 01, 2017, 10:17:42 AM

ChemE

After a moderate hiatus I'm back at work with my radio code.  I want to do some extensive testing to try to quantify packet error rates and how to drive them downward without using too much power in the process.  This initial post is really just a placeholder and I'll be updating it with more information as I generate it.  Initially I'm doing all my testing at 300kbps.  The scheme I'm using is I have a node placed 15' away from the gateway with line-of-sight and the node sends a packet every 8 seconds with among other things, a packet ID expressed as two bytes.  The gateway uses these packet IDs to detect if a packet was missed and in the case of multiple consecutive missed packets how many were lost.  I'm also keeping an average RSSI as I go.  The node is *not* sending with retries, just sending with no ACK request.  I'm not using CRC either since I like being able to use very small packets and 16 bytes is much more than I ever need.

So far at a RSSI of -70dBm, 6 preamble bytes, and 3 sync word bytes I basically never lose a packet.  12 packets lost in 4,200 sent or 0.3% packet error rate.  When I scroll through the data, 10 of those drops came when I was too close to the gateway and the RSSI dropped closer to -90dBm; an interesting observation in and of itself.  I plan on testing smaller numbers of preamble and sync bytes using the same setup to see what the cost is.  Here is a sample of the data the gateway logs:

[BASEMENT NODE]	77.62F	42.82%RH	Dewpoint: 53.24F - Pleasant	Vcc: 279VDC	Packet Counter: 4591	Missed: 12	Received: 4564	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	77.40F	42.91%RH	Dewpoint: 53.11F - Pleasant	Vcc: 279VDC	Packet Counter: 4592	Missed: 12	Received: 4565	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	77.23F	43.14%RH	Dewpoint: 53.09F - Pleasant	Vcc: 279VDC	Packet Counter: 4593	Missed: 12	Received: 4566	PER: 0%	RX_RSSI:-68 | -75
[BASEMENT NODE]	77.09F	43.28%RH	Dewpoint: 53.06F - Pleasant	Vcc: 279VDC	Packet Counter: 4594	Missed: 12	Received: 4567	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	77.04F	43.57%RH	Dewpoint: 53.19F - Pleasant	Vcc: 279VDC	Packet Counter: 4595	Missed: 12	Received: 4568	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	76.94F	43.63%RH	Dewpoint: 53.14F - Pleasant	Vcc: 279VDC	Packet Counter: 4596	Missed: 12	Received: 4569	PER: 0%	RX_RSSI:-71 | -75
[BASEMENT NODE]	76.80F	43.72%RH	Dewpoint: 53.08F - Pleasant	Vcc: 279VDC	Packet Counter: 4597	Missed: 12	Received: 4570	PER: 0%	RX_RSSI:-69 | -75
[BASEMENT NODE]	76.71F	43.86%RH	Dewpoint: 53.07F - Pleasant	Vcc: 279VDC	Packet Counter: 4598	Missed: 12	Received: 4571	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	76.59F	43.97%RH	Dewpoint: 53.04F - Pleasant	Vcc: 279VDC	Packet Counter: 4599	Missed: 12	Received: 4572	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	76.48F	44.12%RH	Dewpoint: 53.02F - Pleasant	Vcc: 279VDC	Packet Counter: 4600	Missed: 12	Received: 4573	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	76.34F	44.27%RH	Dewpoint: 53.00F - Pleasant	Vcc: 279VDC	Packet Counter: 4601	Missed: 12	Received: 4574	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	76.21F	44.41%RH	Dewpoint: 52.96F - Pleasant	Vcc: 279VDC	Packet Counter: 4602	Missed: 12	Received: 4575	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	76.17F	44.47%RH	Dewpoint: 52.96F - Pleasant	Vcc: 278VDC	Packet Counter: 4603	Missed: 12	Received: 4576	PER: 0%	RX_RSSI:-69 | -75
[BASEMENT NODE]	76.11F	44.56%RH	Dewpoint: 52.96F - Pleasant	Vcc: 278VDC	Packet Counter: 4604	Missed: 12	Received: 4577	PER: 0%	RX_RSSI:-69 | -75
[BASEMENT NODE]	76.01F	44.68%RH	Dewpoint: 52.95F - Pleasant	Vcc: 278VDC	Packet Counter: 4605	Missed: 12	Received: 4578	PER: 0%	RX_RSSI:-69 | -75
[BASEMENT NODE]	75.95F	44.76%RH	Dewpoint: 52.95F - Pleasant	Vcc: 278VDC	Packet Counter: 4606	Missed: 12	Received: 4579	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	75.88F	44.82%RH	Dewpoint: 52.91F - Pleasant	Vcc: 278VDC	Packet Counter: 4607	Missed: 12	Received: 4580	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	75.76F	44.88%RH	Dewpoint: 52.84F - Pleasant	Vcc: 278VDC	Packet Counter: 4608	Missed: 12	Received: 4581	PER: 0%	RX_RSSI:-70 | -75
[BASEMENT NODE]	75.68F	44.99%RH	Dewpoint: 52.84F - Pleasant	Vcc: 278VDC	Packet Counter: 4609	Missed: 12	Received: 4582	PER: 0%	RX_RSSI:-71 | -75
[BASEMENT NODE]	75.67F	45.09%RH	Dewpoint: 52.89F - Pleasant	Vcc: 277VDC	Packet Counter: 4610	Missed: 12	Received: 4583	PER: 0%	RX_RSSI:-69 | -75
[BASEMENT NODE]	75.53F	45.16%RH	Dewpoint: 52.80F - Pleasant	Vcc: 277VDC	Packet Counter: 4611	Missed: 12	Received: 4584	PER: 0%	RX_RSSI:-70 | -75


More to come...

WhiteHare

#1
Just a guess, but I think it might be more informative to test with NLOS conditions rather than LOS.  NLOS conditions are more likely  when packets are lost, due to multipath, fading, reflections or whatever.

In the past when I did testing like this, I would send a packet and then have the gateway send it back.  That way I could compare what was received against what was sent and thereby determine if there were any errors.  It also has the virtue of testing whatever your normal packets are.

ChemE

I agree, thanks WhiteHare.  Any other feedback before I start generating a slew of data?

ChemE

I moved it to the other room so that it is now non-line-of-sight without turning up the Tx power and just watching the data at -90dBm you can see dropped packets every now and then, but also bit errors creeping in.

[BASEMENT NODE]	72.73F	50.50%RH	Dewpoint: 53.29F - Pleasant	Vcc: 276VDC	Packet Counter: 4812	Missed: 17	Received: 4780	PER: 0%	RX_RSSI:-86 | -75
[BASEMENT NODE]	72.79F	50.53%RH	Dewpoint: 53.36F - Pleasant	Vcc: 276VDC	Packet Counter: 4813	Missed: 17	Received: 4781	PER: 0%	RX_RSSI:-85 | -75
[BASEMENT NODE]	72.71F	50.54%RH	Dewpoint: 53.30F - Pleasant	Vcc: 276VDC	Packet Counter: 4814	Missed: 17	Received: 4782	PER: 0%	RX_RSSI:-85 | -75
 - ACK sent[BASEMENT NODE]	72.69F	50.56%RH	Dewpoint: 53.29F - Pleasant	Vcc: 276VDC	Packet Counter: 4815	Missed: 17	Received: 4783	PER: 0%	RX_RSSI:-87 | -75
[BASEMENT NODE]	72.69F	50.57%RH	Dewpoint: 53.30F - Pleasant	Vcc: 276VDC	Packet Counter: 4816	Missed: 17	Received: 4784	PER: 0%	RX_RSSI:-87 | -75
[BASEMENT NODE]	72.71F	50.63%RH	Dewpoint: 53.35F - Pleasant	Vcc: 276VDC	Packet Counter: 4818	Missed: 18	Received: 4785	PER: 0%	RX_RSSI:-92 | -75
[BASEMENT NODE]	72.61F	50.63%RH	Dewpoint: 53.26F - Pleasant	Vcc: 276VDC	Packet Counter: 4819	Missed: 18	Received: 4786	PER: 0%	RX_RSSI:-89 | -75
[BASEMENT NODE]	72.65F	50.60%RH	Dewpoint: 53.28F - Pleasant	Vcc: 276VDC	Packet Counter: 4820	Missed: 18	Received: 4787	PER: 0%	RX_RSSI:-90 | -75
[BASEMENT NODE]	72.63F	50.59%RH	Dewpoint: 53.25F - Pleasant	Vcc: 276VDC	Packet Counter: 4821	Missed: 18	Received: 4788	PER: 0%	RX_RSSI:-90 | -75
[BASEMENT NODE]	-6.38F	54.49%RH	Dewpoint: -18.54F - Pleasant	Vcc: 276VDC	Packet Counter: 6871	Missed: 2067	Received: 4789	PER: 2%	RX_RSSI:-94 | -75
[BASEMENT NODE]	72.67F	50.54%RH	Dewpoint: 53.26F - Pleasant	Vcc: 276VDC	Packet Counter: 4825	Missed: 20	Received: 4790	PER: 0%	RX_RSSI:-91 | -75
[BASEMENT NODE]	72.69F	50.51%RH	Dewpoint: 53.26F - Pleasant	Vcc: 276VDC	Packet Counter: 4826	Missed: 20	Received: 4791	PER: 0%	RX_RSSI:-87 | -75

WhiteHare

#4
Well, since you ask....  If you wrote a sketch that was a generic test loop (i.e. no hardware dependencies like testing temperature and humidity), and posted it, then others could repeat the test in their locations and post the results.  That would be an easy way to get more datapoints under more varied conditions. 

But, I don't want to overload you.  Literally anything would be better than nothing.

ChemE

#5
I like the idea.  I'm torn though.  Most of what needs to be changed is in RFM69.cpp and that isn't as easy as editing the code itself.  I could post up a generic sketch and leave it for everyone to edit their settings in Felix's library, or I could post my radio code which does not link to Felix's library.  Of course, my code is used by one whole person where Felix's is used by thousands.

EDIT:  Thinking back to my initial tinkerings with Felix's library, the first few times I looked at it I got lost and gave up.  I was totally unsure how it worked or what to change especially those nested ifs that set radio frequency.  Looking at the code in Wordpad rather than Notepad++ made things much harder as well.

WhiteHare

#6
Assume people are lazy (or perhaps "marginally motivated" would be more accurate), and so post whatever is easiest for them to try.  Otherwise, few, if any, will even bother attempting it.

ChemE

Quote from: WhiteHare on May 01, 2017, 11:29:41 AM
Assume people are lazy (or perhaps "marginally motivated" would be more accurate), and so post whatever is easiest for them to try.  Otherwise, few, if any, will even bother attempting it.

Cool, I was able to override the default settings set in RFM69.cpp directly from my setup code by making tons of calls to radio.writeReg().  I'm just stripping out all my OLED and TH-sensor calls now and I'll have something posted shortly that marginally motivated people can still pop on their motes to 1) play with 300kbps 2) test out packet error rate (PER) under whatever conditions they like.  Appreciate the feedback as always WhiteHare.

ChemE

#8
Okay, node and gateway code for 2 default stock Motes not connected to anything else.

Gateway code
#include <RFM69.h>
#include <RFM69registers.h>
#include <SPI.h>

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
#define NETWORKID     100  //the same on all nodes that talk to each other - 170 is 10101010 DC free value
#define RECEIVER      1    //unique ID of the gateway/receiver
#define SENDER        2
#define NODEID        RECEIVER  //change to "SENDER" if this is the sender node (the one with the button)
#define FREQUENCY     RF69_915MHZ  //Match frequency to the hardware version of the radio on your Moteino (uncomment one):
//#define IS_RFM69HW    //uncomment only for RFM69HW! Leave out if you have RFM69W!
//*********************************************************************************************

#define SERIAL_BAUD   115200
RFM69 radio;
uint16_t Last_Packet, Curr_Packet, Packets_Received, Packets_Missed;
int32_t LT_RSSI;

void setup() {
  Serial.begin(SERIAL_BAUD);
  
  // Assume default settings, we will override them next
  radio.initialize(FREQUENCY,NODEID,NETWORKID);
  
  // Make the changes to bring the bitrate up to 300kbps and turn CRC off allowing for packets <16 bytes
  radio.writeReg( REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_STANDBY );
  radio.writeReg( REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_00 );	// 0x02
  radio.writeReg( REG_BITRATEMSB, RF_BITRATEMSB_300000 );	// 0x03
  radio.writeReg( REG_BITRATELSB, RF_BITRATELSB_300000 );	// 0x04
  radio.writeReg( REG_FDEVMSB, RF_FDEVMSB_300000 );	// 0x05
  radio.writeReg( REG_FDEVLSB, RF_FDEVLSB_300000 );	// 0x06
  radio.writeReg( REG_FRFMSB, RF_FRFMSB_915 );	// 0x07
  radio.writeReg( REG_FRFMID, RF_FRFMID_915 );	// 0x08
  radio.writeReg( REG_FRFLSB, RF_FRFLSB_915 );	// 0x09
  radio.writeReg( REG_RXBW, RF_RXBW_DCCFREQ_111 | RF_RXBW_MANT_16 | RF_RXBW_EXP_0 );	// 0x19
  radio.writeReg( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01 );	// 0x25
  radio.writeReg( REG_DIOMAPPING2, RF_DIOMAPPING2_CLKOUT_OFF );	//0x26
  radio.writeReg( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );	// 0x28
  radio.writeReg( REG_RSSITHRESH, 220 );	// 0x29
  radio.writeReg( REG_PREAMBLELSB, 6 );	// 0x2D
  radio.writeReg( REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_3 | RF_SYNC_TOL_0 );	// 0x2E
  radio.writeReg( REG_SYNCVALUE1, 0x88 );	// 0x2F
  radio.writeReg( REG_SYNCVALUE2, NETWORKID );	// 0x30
  radio.writeReg( REG_SYNCVALUE3, 0x88 );	// 0x2F
  radio.writeReg( REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_OFF | RF_PACKET1_CRC_OFF | RF_PACKET1_CRCAUTOCLEAR_OFF | RF_PACKET1_ADRSFILTERING_OFF );	// 0x37
  radio.writeReg( REG_PAYLOADLENGTH, 66 );	// 0x38
  radio.writeReg( REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | RF_FIFOTHRESH_VALUE );	// 0x3C
  radio.writeReg( REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF );	// 0x3D
  radio.writeReg( REG_TESTDAGC, RF_DAGC_IMPROVED_LOWBETA0 );	// 0x6F
  
  radio.setPowerLevel(0);
  radio.encrypt(null);
  Serial.print("Listening at ");
  Serial.print(FREQUENCY);
  Serial.println("Mhz...");
}

void loop() {    // Loop Forever
  int16_t RSSI;
  uint8_t SenderID;
  
    //check if something was received (could be an interrupt from the radio)
    if (radio.receiveDone()) {
      if (radio.ACKRequested()) {  //check if sender wanted an ACK
        radio.sendACK();    // send the ACK
        Serial.print(" - ACK sent");
      }
      RSSI = radio.RSSI;
      LT_RSSI += RSSI;
      
      if (radio.SENDERID == 2) {
        //print message received to serial
        Serial.print("Vcc: ");
        uint16_t rbgv = radio.DATA[1]<<8 | radio.DATA[0]; 
        uint16_t voltage = ((1125300/rbgv)+5)/10;
        Serial.print(voltage);
        Serial.print("VDC\tPacket Counter: ");
        
        // Work out PER statistics
        Curr_Packet = radio.DATA[3]<<8 | radio.DATA[2];
        if (!( Curr_Packet == ++Last_Packet ) && Packets_Received ) Packets_Missed += (Curr_Packet - Last_Packet);
        Last_Packet = Curr_Packet;
        Serial.print(Curr_Packet);
        Serial.print("\tMissed: ");
        Serial.print(Packets_Missed);
        Serial.print("\tReceived: ");
        Serial.print(++Packets_Received);
        Serial.print("\tPER: ");
        Serial.print( 100 * Packets_Missed / Packets_Received );
        Serial.print("%\tRX_RSSI:");
        Serial.print(RSSI);
        Serial.print(" | ");
        Serial.print(LT_RSSI/Packets_Received);
        Serial.println();    
      }
    }  // End if  
    _delay_us(10);
}  // End Loop


Node Code
#include <RFM69.h>
#include <RFM69Registers.h>
#include <SPI.h>
#include <LowPower.h>

// Define various ADC prescaler
#define       ADC_PS_16               (1 << ADPS2)
#define       ADC_PS_32               (1 << ADPS2) |                (1 << ADPS0)
#define       ADC_PS_64               (1 << ADPS2) | (1 << ADPS1)
#define       ADC_PS_128              (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0)
#define       sbi(sfr, bit)           (_SFR_BYTE(sfr) |= _BV(bit))
#define       cbi(sfr, bit)           (_SFR_BYTE(sfr) &= ~_BV(bit))
#define       START_ADC_CONVERSION    sbi(ADCSRA, ADSC);  // start a conversion
#define       ENABLE_ADC              cbi(PRR, PRADC); sbi(ADCSRA, ADEN);  //ADCSRA |= bit(ADEN); // Enable the ADC
#define       DISABLE_ADC             cbi(ADCSRA, ADEN); sbi(PRR, PRADC); // Disable the ADC to save power

#define DEBUG 0

//*********************************************************************************************
// *********** IMPORTANT SETTINGS - YOU MUST CHANGE/ONFIGURE TO FIT YOUR HARDWARE *************
//*********************************************************************************************
#define NETWORKID     100  //the same on all nodes that talk to each other
#define RECEIVER      1    //unique ID of the gateway/receiver
#define SENDER        2
#define NODEID        SENDER  //change to "SENDER" if this is the sender node (the one with the button)
//#define IS_RFM69HW    //uncomment only for RFM69HW! Leave out if you have RFM69W!
#define FREQUENCY     RF69_915MHZ

RFM69 radio;    //Create an instance of the object

static inline void Fast_ADC_Init(void) {
  sei();
  // Timer 0 initialization from wiring.c for a ATmega 328P (Arduino Uno rev 3) + 12 bytes to sketch size
  TCCR0A = _BV(WGM01) | _BV(WGM00);      // set timer 0 prescale factor to 64
  TCCR0B = _BV(CS01) | _BV(CS00);        // set timer 0 prescale factor to 64
  TIMSK0 = _BV(TOIE0);                 // enable timer 0 overflow interrupt
  
  // Timer 2 initialization from wiring.c for an ATmega 328P (Arduino Uno rev 3) + 20 bytes to sketch size
  TCCR2A |= _BV(COM2A1) | _BV(WGM20);    // Enable timer 2 to _delay_ms() works properly
  TCCR2B |= CS22;                        // set clkT2S/64 (From prescaler)
  
  // ADC Housekeeping
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);    // Set the multiplexer to read the internal bandgap voltage
  //ADCSRA &= ~ADC_PS_128;    // Unset the bits set by init()
  ADCSRA |= ADC_PS_32;    // set our own prescaler to 32 
  
  // Make unused pins outputs to reduce power consumption
  //DDRB |= (1<<PB1) | (1<<PB0);
  //DDRC |= (1<<PC1) | (1<<PC0);
  //DDRD |= (1<<PD7) | (1<<PD6)| (1<<PD5) | (1<<PD4) | (1<<PD3);
}

int main(void) {
	uint8_t data[4];  //16-bit temp, 16-bit RH, 16-bit Vcc, 16-bit packet counter
        uint16_t packet_cnt = 0;    // 16-bit packet counter to measure PER
	#if DEBUG
	  uint16_t startT, elapsed;
	  startT = micros();           // ==================== START THE CLOCK ====================
	#endif
	
	Fast_ADC_Init();    // Initialize the AVR registers needed
        radio.initialize(FREQUENCY,NODEID,NETWORKID);
        radio.encrypt(null);
        radio.setPowerLevel(0);
        radio.sleep();
        
        // Make the changes to bring the bitrate up to 300kbps and turn CRC off allowing for packets <16 bytes
        radio.writeReg( REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_STANDBY );
        radio.writeReg( REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_00 );	// 0x02
        radio.writeReg( REG_BITRATEMSB, RF_BITRATEMSB_300000 );	// 0x03
        radio.writeReg( REG_BITRATELSB, RF_BITRATELSB_300000 );	// 0x04
        radio.writeReg( REG_FDEVMSB, RF_FDEVMSB_300000 );	// 0x05
        radio.writeReg( REG_FDEVLSB, RF_FDEVLSB_300000 );	// 0x06
        radio.writeReg( REG_FRFMSB, RF_FRFMSB_915 );	// 0x07
        radio.writeReg( REG_FRFMID, RF_FRFMID_915 );	// 0x08
        radio.writeReg( REG_FRFLSB, RF_FRFLSB_915 );	// 0x09
        radio.writeReg( REG_RXBW, RF_RXBW_DCCFREQ_111 | RF_RXBW_MANT_16 | RF_RXBW_EXP_0 );	// 0x19
        radio.writeReg( REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01 );	// 0x25
        radio.writeReg( REG_DIOMAPPING2, RF_DIOMAPPING2_CLKOUT_OFF );	//0x26
        radio.writeReg( REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN );	// 0x28
        radio.writeReg( REG_RSSITHRESH, 220 );	// 0x29
        radio.writeReg( REG_PREAMBLELSB, 6 );	// 0x2D
        radio.writeReg( REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_3 | RF_SYNC_TOL_0 );	// 0x2E
        radio.writeReg( REG_SYNCVALUE1, 0x88 );	// 0x2F
        radio.writeReg( REG_SYNCVALUE2, NETWORKID );	// 0x30
        radio.writeReg( REG_SYNCVALUE3, 0x88 );	// 0x2F
        radio.writeReg( REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_OFF | RF_PACKET1_CRC_OFF | RF_PACKET1_CRCAUTOCLEAR_OFF | RF_PACKET1_ADRSFILTERING_OFF );	// 0x37
        radio.writeReg( REG_PAYLOADLENGTH, 66 );	// 0x38
        radio.writeReg( REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | RF_FIFOTHRESH_VALUE );	// 0x3C
        radio.writeReg( REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF );	// 0x3D
        radio.writeReg( REG_TESTDAGC, RF_DAGC_IMPROVED_LOWBETA0 );	// 0x6F
  
	//initTWI();  // Initialize the I2C bus at 400kHz
	#if DEBUG
	  elapsed = micros()-startT;   // ==================== STOP THE CLOCK ====================
  	  Serial.begin(115200);
  	  Serial.print("\nInitialization took ");
  	  Serial.print(elapsed);
  	  Serial.print(" us");
  	  _delay_ms(6);
	#else
	  cbi(PRR, PRUSART0);  // Turn off the UART since we won't be using it
	#endif
	
	for(;;) {  // Loop forever
		#if DEBUG
		  startT = micros();           // ==================== START THE CLOCK ====================
		#endif
		ENABLE_ADC;                       // Turn on the ADC just prior to needing it
		START_ADC_CONVERSION;             // start a conversion
                _delay_us(70);                    // Give some time for the ADC conversion to finish
		data[0] = ADCL;                   // Avoid 16-bit math in this loop since it adds 40us
		data[1] = ADCH;                   // Read back the results of the ADC
                data[2] = (++packet_cnt & 0xFF);  // Increment packet_count and stash the LSB
                data[3] = (packet_cnt >> 8);      // Stash the MSB of the packet counter
		DISABLE_ADC;                      // Turn off the ADC to save power     
                radio.send(RECEIVER, data, 4, 0); //target node Id, message as string or byte array, message length, ack requested
                radio.sleep();
                
		#if DEBUG
        	  elapsed = micros()-startT;   // ==================== STOP THE CLOCK ====================
        	  Serial.print("\nVcc: ");
        	  Serial.print(112296/(data[1]<<8 | data[0]));
                  Serial.print("\tPacket Count: ");
                  Serial.print((uint16_t)(data[3]<<8 | data[2]));
        	  Serial.print("\t\tLoop took: ");
        	  Serial.print(elapsed);
        	  Serial.print(" us");
        	  _delay_ms(4);  // Give the UART time to get our output across
        	  Serial.flush();
		#endif

                uint8_t sleep_count=0;
                do LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
                while (++sleep_count < 1);
	}  // end for
}  // end main


DEBUG on the node should be defined as 0 when doing actual PER testing.  For just getting things set up, feel free to define it as 1 and open a serial monitor to ensure that your node is behaving appropriately.