nrf24.waitPacketSent() and nrf24.waitAvailable()

1,143 views
Skip to first unread message

Shiu Kumar

unread,
Jan 6, 2013, 8:02:15 AM1/6/13
to nrf24-...@googlegroups.com
I am using the NRF24 library and the above to commands are used for waiting that the data is sent and the later used to wait until data is available.

I do understand that when nrf24.waitAvailable() function is called, the module changes state to RX mode and waits to receive data that is waits until data is available(). However I am not sure when the register NRF24_RX_EMPTY  goes LOW. Does it go LOW when all payload data is available or when the first byte data is in the register.

Secondly, can someone briefly explain what happens with the nrf24.waitPacketSent() function.

Mike McCauley

unread,
Jan 7, 2013, 3:42:40 AM1/7/13
to nrf24-...@googlegroups.com
It blocks until either the current packet is successfully sent (and received
by the other side) or the max retries limit is exceeded.

Cheers.


--
Mike McCauley mi...@open.com.au
Open System Consultants Pty. Ltd
9 Bulbul Place Currumbin Waters QLD 4223 Australia http://www.open.com.au
Phone +61 7 5598-7474 Fax +61 7 5598-7070

Radiator: the most portable, flexible and configurable RADIUS server
anywhere. SQL, proxy, DBM, files, LDAP, NIS+, password, NT, Emerald,
Platypus, Freeside, TACACS+, PAM, external, Active Directory, EAP, TLS,
TTLS, PEAP, TNC, WiMAX, RSA, Vasco, Yubikey, MOTP, HOTP, TOTP,
DIAMETER etc. Full source on Unix, Windows, MacOSX, Solaris, VMS, NetWare etc.

Shiu Kumar

unread,
Jan 7, 2013, 7:03:56 AM1/7/13
to nrf24-...@googlegroups.com
Hello

When does the register NRF24_RX_EMPTY  goes LOW. Does it go LOW when all payload data is available or when the first byte data is in the register.

cheers

Mike McCauley

unread,
Jan 7, 2013, 5:58:19 PM1/7/13
to nrf24-...@googlegroups.com
On Monday, January 07, 2013 04:03:56 AM Shiu Kumar wrote:
> Hello
>
> When does the register NRF24_RX_EMPTY goes LOW. Does it go LOW when all
> payload data is available or when the first byte data is in the register.

Hmm, its not very clear to me.
The available() code seems to depend on it being 'all payload data is
available'.

Cheers.

>
> cheers
>
> On Monday, January 7, 2013 5:42:40 PM UTC+9, mikem wrote:
> > On Sunday, January 06, 2013 05:02:15 AM Shiu Kumar wrote:
> > > I am using the NRF24 library and the above to commands are used for
> >
> > waiting
> >
> > > that the data is sent and the later used to wait until data is
> >
> > available.
> >
> > > I do understand that when nrf24.waitAvailable() function is called, the
> > > module changes state to RX mode and waits to receive data that is waits
> > > until data is available(). However I am not sure when the
> > > register NRF24_RX_EMPTY goes LOW. Does it go LOW when all payload data
> >
> > is
> >
> > > available or when the first byte data is in the register.
> > >
> > > Secondly, can someone briefly explain what happens with
> > > the nrf24.waitPacketSent() function.
> >
> > It blocks until either the current packet is successfully sent (and
> > received
> > by the other side) or the max retries limit is exceeded.
> >
> > Cheers.
> >
> >
> >

Ivatt Diesel

unread,
Jan 15, 2013, 6:07:42 PM1/15/13
to nrf24-...@googlegroups.com

i'm seeing a system lockup that i've traced (by putting debug around the lines) to my waitPacketSent() command.  it only happens about once every 5000 sends, and I cant see any correlation to the data being sent (the same message has gone out many times in that 5000 or so). I'm using noack in the send routine so i'm happy to handle the consequences if a packet doesn't get through.

I'm thinking about three different alternatives, and wondered if anyone could suggest which is the better route;

     1. Find some way of setting the number of retries the chip will try 
     2  doing a while loop with isSending() to achieve the same as waitPAcketSent()
     3  do a delay(10)    (which I think should be long enough for 17Bytes at 2Mbps?)

Mark B

The following code gives debug which ends with "send started" about 1 time in 5000;

                // Send the Probe data packet    
                if (!nrf24.send((uint8_t*)&DataPacket, sizeof(DataPacket), true))
                          Serial.println("send failed");  
                else
                          Serial.println("send started");  
                          
                if (!nrf24.waitPacketSent())
                {
                    if (Verbose_debug)
                         Serial.println("waitPacketSent failed");  
                } 
                else
                {
                    if (Verbose_debug)
                         Serial.println("packet sent");

Mike McCauley

unread,
Jan 15, 2013, 8:20:18 PM1/15/13
to nrf24-...@googlegroups.com
Hello,

can you post some code that will let me reproduce the problem?

Cheers.

Mike McCauley

unread,
Jan 16, 2013, 4:40:38 PM1/16/13
to nrf24-...@googlegroups.com
On Wednesday, January 16, 2013 11:20:18 AM you wrote:
> Hello,
>
> can you post some code that will let me reproduce the problem?

Just to be clear, I meant a complete sketch.

Cheers.

Ivatt Diesel

unread,
Jan 16, 2013, 4:50:09 PM1/16/13
to nrf24-...@googlegroups.com
Mike,

 Thanks.  I'm just working on a sketch that demonstrates it.   I think I have it, as it has  just failed once, and i'm waiting for it to fail again now. It can take some time.

 I've taken my main project sketch, and removed the non-radio related bits to make it clearer and easier to follow, but without changing the actual send/receive structure.

I'll send the sketch a bit later, when i've captured the debug from another failure

Mark

Ivatt Diesel

unread,
Jan 16, 2013, 5:44:54 PM1/16/13
to nrf24-...@googlegroups.com



Mike,


   Below is a sketch that demonstrates what i'm seeing. The system always stops after the send in the waitPacketSent()

    The debug it produces looks like this;

    Run 1
    ---------


250  Going to send...  send started...packet sent
251  Going to send...  send started...packet sent
***** Got a Non-zeo length message
252  Going to send...  send started...packet sent
***** Got a Non-zeo length message
253  Going to send...  send started...


    Run 2
    ---------
12503  Going to send...  send started...packet sent
***** Got a Non-zeo length message
12504  Going to send...  send started…


  It _seems_ to fail when sending after having received a message - but that may be a red herring, because it is likely that another message is being received at just about the same time as the send is happening.  I wonder if it is something to do with the timing of the send when messages are coming in as well.

  It seems to be worse (ie. fail more regularly) when there are lots of messages being transmitted in the air.

  As you can see from the debug above, it can sometimes take a considerable number of messages to fail. I had thought of adjusting the loop to send messages more frequently, but didn't want to disrupt the timing.

  Let me know if that makes any sense, and thanks for your assistance.

Mark
 

//-----------------------------------------------------------------------------------------------------------------------------------------------------
#include <arduino.h>
#include <SPI.h>
#include <NRF24.h>


#define PreferredChannel         1
#define delay_interval           300
#define AddrLen                  5
#define PayloadLen               17  // size of Message


//Message structure
struct Message
{
    long  msg1;
    long  msg2;
    byte  msg3;
    byte  msg4;
    byte  msg5;
    int   msg6;  
    long  msg7;
};




NRF24 nrf24; // use this to be electrically compatible with Mirf


byte BroadcastAddr[AddrLen];


long counter = 0;
Message DataPacket;


void setup() {
  
 // set serial
  Serial.begin(57600);
  
  //set broadcast address
  BroadcastAddr[0] = 0xFF;
  BroadcastAddr[1] = 0xFF;
  BroadcastAddr[2] = 0xFF;
  BroadcastAddr[3] = 0xFF;
  BroadcastAddr[4] = 0xFF;
  
  
  // set up radio
  Serial.println("NRF24 Host");
  if (!nrf24.init())
    Serial.println("NRF24 init failed");
    
    
  // SET SPI DATA RATE TO SOMETHING RELIABLE 
  SPI.setClockDivider(SPI_CLOCK_DIV64);
  
  // Defaults after init are 2.402 GHz (channel 2)
  
  if (!nrf24.setChannel(PreferredChannel))
    Serial.println("setChannel failed");
    
  if (!nrf24.setThisAddress((uint8_t*)BroadcastAddr, AddrLen))
    Serial.println("setThisAddress failed");
    
  if (!nrf24.setPayloadSize(PayloadLen))
    Serial.println("setPayloadSize failed");
    
  if (!nrf24.setRF(NRF24::NRF24DataRate2Mbps, NRF24::NRF24TransmitPower0dBm))
    Serial.println("setRF failed");    

  // Enable the EN_DYN_ACK feature so we can use noack
  nrf24.spiWriteRegister(NRF24_REG_1D_FEATURE, NRF24_EN_DYN_ACK);
  
  Serial.println("initialised");
  
  //  seed the random number generator
  randomSeed(analogRead(0));
  
}



void Sendonoff(int nodeentry, boolean state)
{                
                // set my trasnmit address to something constant
                if (!nrf24.setThisAddress((uint8_t*)"Contr", 5))
                          Serial.println("setThisAddress failed");
                          
                // Need to set the address of the detination each time, since auto-ack changes the TX address
                if (!nrf24.setTransmitAddress((uint8_t*) BroadcastAddr, 5))
                          Serial.println("setTransmitAddress failed");
                      
                      
                DataPacket.msg1 = 0x00;
                DataPacket.msg2 = 0x00;
                DataPacket.msg3 = 0x00;
                DataPacket.msg4 = 0x00;
                DataPacket.msg5 = 0x00;
                DataPacket.msg6 = 0x00;
                DataPacket.msg7 = 0x00;
                
                Serial.print(counter++);
                Serial.print("  Going to send...  ");
             
              
                // Send the data packet    
                if (!nrf24.send((uint8_t*)&DataPacket, sizeof(DataPacket), true))
                          Serial.print("send failed");  
                else
                          Serial.print("send started...");  
                          
                //  **** this is where the execution seems to stop ****          
                if (!nrf24.waitPacketSent())
                {
                   
                         Serial.println("waitPacketSent failed");  
                } 
                else
                {
                    
                         Serial.println("packet sent");
        
                }
}







void loop() {
                
  
     Sendonoff(0,true);
  
      
  //wait for radio for a random time to de-sync us with other nodes
  boolean  rxd = nrf24.waitAvailableTimeout(random(delay_interval)+150);
  
  // if we think we got something
  if (rxd)
  {
    
     uint8_t len;
     if (!nrf24.recv((uint8_t*)&DataPacket, &len))
          Serial.println("read failed");
       
     if ( len == 0)
     {
           Serial.println("***** Got zero length message ");
     }
     else
     {
         
          Serial.println("***** Got a Non-zeo length message"); 
    }   
  }
  
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------

Ivatt Diesel

unread,
Jan 16, 2013, 6:13:37 PM1/16/13
to nrf24-...@googlegroups.com


Here is another debug run showing the same pattern when it stops (in the waitPacketSent, just after one receive, and when there is likely to be another happening while doing the send);

4125  Going to send...  send started...packet sent
4126  Going to send...  send started...packet sent
4127  Going to send...  send started...packet sent
4128  Going to send...  send started...packet sent
4129  Going to send...  send started...packet sent
4130  Going to send...  send started...packet sent
4131  Going to send...  send started...packet sent
4132  Going to send...  send started...packet sent
4133  Going to send...  send started...packet sent
4134  Going to send...  send started...packet sent

***** Got a Non-zeo length message
4135  Going to send...  send started...packet sent

***** Got a Non-zeo length message
4136  Going to send...  send started...packet sent

***** Got a Non-zeo length message
4137  Going to send...  send started…

Mike McCauley

unread,
Jan 16, 2013, 6:20:00 PM1/16/13
to nrf24-...@googlegroups.com
Hello,

Thanks.

Is this code from the transmitter? Is there corresponding receiver code needed
to reproduce the problem?

Cheers.

Ivatt Diesel

unread,
Jan 16, 2013, 6:24:02 PM1/16/13
to nrf24-...@googlegroups.com

Mike,

   It is one end of  the link (both ends transmit and receive).  I think it will work on its own, but if my guess is right about being related to receipt while sending, then you may need a transmitter sending to this unit to stimulate it to fail. As this code send broadcast messages, just run a couple of them.

Mark

Mike McCauley

unread,
Jan 16, 2013, 9:57:12 PM1/16/13
to nrf24-...@googlegroups.com, Ivatt Diesel
Hi,

after 688777 trials I still havent been able to reproduce this, trying with
and without an identical unit providing interference.

Are you sure your electrical connections are sound? Are you sure its not a
problem with your Arduino or your NRF24?

Cheers.

Mike McCauley

unread,
Jan 17, 2013, 1:57:19 AM1/17/13
to nrf24-...@googlegroups.com
Hi again,

now over 1000,000 waits and no hangs.

Cheers.

Ivatt Diesel

unread,
Jan 17, 2013, 3:41:32 PM1/17/13
to nrf24-...@googlegroups.com

Mike, Thanks for testing.

   I can't honestly completely rule out a problem with hardware or connections - but they run successfully for many thousand messages, so they are probably wired up right.  Could it be a dodgy connection or a failing chip?  Yes, but then, I see the same on many different boards and  RF24s.

  You got to 1million count - I assume therefore you modified the timeout on the send to speed the cycle up?  I'm fairly convinced this is a timing issue, and so that may have an effect on the test.  So what I did today, was run my test code that I sent yesterday, on it's own, with no other transmitters, and it ran for 250,000+ message with no problem.  I then turned on 6 transmitters with the code below, and it failed within a few thousand messages in the same place as before.

  My application is a hub and spoke network, the code I sent yesterday is the hub, and below is the spoke.  I have it running on 6 arduino nanos, and the hub on a uno. All are using NRF24 boards like this;



  Tonight i'll change the waitPacketSent to be a delay(30) and see if that is stable over the long term (if it is my wiring or chip then it would most likely fail in the same way).

  Again, many thanks for your library, and the support of it.
Mark B


// -------------------------  SPOKE NODE CODE ---------------------------------------
#include <arduino.h>
#include <SPI.h>
#include <NRF24.h>

#define PreferredChannel         1


#define delay_interval           200
#define MyHandleInEEPROM         0
#define AddrLen                  5
#define PayloadLen               17  // size of Message

#define StatusMessageInterval    1000 //msec
#define MessageInterval          2000 //msec


//Message structure
struct Message
{
    long  msg1;
    long  msg2;
    byte  msg3;
    byte  msg4;
    byte  msg5;
    int   msg6;
    long  msg7;  
};





//NRF24 nrf24;
NRF24 nrf24; // use this to be electrically compatible with Mirf

long LastSeqNo = 0;
long LastStatusMessage = 0;
long LastMessage = 0;

byte BroadcastAddr[AddrLen];

long NoOfInterferencePackets = 0;

Message DataPacket;

boolean InitialStatusSent = false;


void setup() {
  // set serial
  Serial.begin(57600);
  
  
  //set broadcast address
  BroadcastAddr[0] = 0xFF;
  BroadcastAddr[1] = 0xFF;
  BroadcastAddr[2] = 0xFF;
  BroadcastAddr[3] = 0xFF;
  BroadcastAddr[4] = 0xFF;
  
  
  // set up radio
  
  Serial.println("NRF24 Client");
  if (!nrf24.init())
    Serial.println("NRF24 init failed");
  // Defaults after init are 2.402 GHz (channel 2)
  // Now be compatible with Mirf ping_server

  // SET SPI DATA RATE TO SOMETHING RELIABLE 
  SPI.setClockDivider(SPI_CLOCK_DIV64);
    
  if (!nrf24.setChannel(PreferredChannel))
    Serial.println("setChannel failed");
    
  if (!nrf24.setThisAddress((uint8_t*)BroadcastAddr, 5))
    Serial.println("setThisAddress failed");
    
  if (!nrf24.setPayloadSize(PayloadLen))
    Serial.println("setPayloadSize failed");
    
  if (!nrf24.setRF(NRF24::NRF24DataRate2Mbps, NRF24::NRF24TransmitPower0dBm))
    Serial.println("setRF failed");    
    
    
  // Enable the EN_DYN_ACK feature so we can use noack
  nrf24.spiWriteRegister(NRF24_REG_1D_FEATURE, NRF24_EN_DYN_ACK);

  Serial.println("initialised");
  
}


  

void loop() {

  
  // wait for radio to be available  
  Serial.println("waiting...");
  boolean rxd = nrf24.waitAvailableTimeout(random(delay_interval));
  
  if (rxd)
  {
     // check for messages
     unsigned long data;
     uint8_t len;

     if (!nrf24.recv((uint8_t*)&DataPacket, &len))
        Serial.println("read failed");
     else
        Serial.println("Packet Received");
    
     Serial.print("Data Received:  Len:");
     Serial.println(len);

  
  }
  
  long Timediff = millis() - LastMessage;
  if ( Timediff > MessageInterval)
  {
    Serial.println("***  No Message Received for a while.");

    LastMessage = millis();
    
    // set the intial status back to false to force us to send more status message  
    InitialStatusSent = false;
    
  }
  
  
  // send a status message if time to
  Timediff = millis() - LastStatusMessage;
  if ( ( Timediff > StatusMessageInterval) ||  (InitialStatusSent == false))
  {
    Serial.println("time to send a status message");
    
     
      // set my trasnmit address to something constant
      if (!nrf24.setThisAddress((uint8_t*)"Node", 5))
                          Serial.println("setThisAddress failed");

      // Need to set the address of the detination each time, since auto-ack changes the TX address
      if (!nrf24.setTransmitAddress((uint8_t*) BroadcastAddr, 5))
                          Serial.println("setTransmitAddress failed");
                      
 
 
      DataPacket.msg1 = 0x00;
      DataPacket.msg2 = 0x00;
      DataPacket.msg3 = 0x00;
      DataPacket.msg4 = 0x00;
      DataPacket.msg5 = 0x00;
      DataPacket.msg6 = 0x00;
      DataPacket.msg7 = 0x00;
      
      Serial.println("I'm going to send");  

      
      // Send the Probe data packet    
      if (!nrf24.send((uint8_t*)&DataPacket, sizeof(DataPacket), true))
                          Serial.println("send failed");  
      else
      {
         InitialStatusSent = true;
         LastStatusMessage = millis();

Mike McCauley

unread,
Jan 17, 2013, 4:47:27 PM1/17/13
to nrf24-...@googlegroups.com
Hi,

OK, I have started a test with your hub and spoke code. But I dont have enough
modules to reproduce your test exactly.

Im using the sparkfun WRL-00691 module.

Cheers.

Ivatt Diesel

unread,
Jan 17, 2013, 4:51:42 PM1/17/13
to nrf24-...@googlegroups.com

Thanks Mike.

  I started a test with the waitPacketSent replaced with a delay(30) about an hour ago on 1 hub and 6 spokes. No failures yet after approx 6000 messages.

Mark

Mike McCauley

unread,
Jan 17, 2013, 5:41:29 PM1/17/13
to nrf24-...@googlegroups.com
On Thursday, January 17, 2013 01:51:42 PM Ivatt Diesel wrote:
> Thanks Mike.
>
> I started a test with the waitPacketSent replaced with a delay(30) about
> an hour ago on 1 hub and 6 spokes. No failures yet after approx 6000
> messages.

OK, Im running a test with a hub and a spoke. Now up to 13000. Im unavailable
for a few hours, will check again later.

Cheers.

Mike McCauley

unread,
Jan 18, 2013, 12:52:57 AM1/18/13
to nrf24-...@googlegroups.com
Now 112000, no hangs.

Cheers.

Mike McCauley

unread,
Jan 18, 2013, 4:04:10 PM1/18/13
to nrf24-...@googlegroups.com
On Friday, January 18, 2013 03:52:57 PM you wrote:
> Now 112000, no hangs.

321000 now, no hangs

Ivatt Diesel

unread,
Jan 18, 2013, 5:00:45 PM1/18/13
to nrf24-...@googlegroups.com
Mike,

  Thanks for testing.  I've changed my code to use a delay(30) instead of the waitPacketSent and it is now rock solid on all units.
  That doesn't necessarily implicate the waitPacketSent of course - maybe there was another problem which was triggered when I happened to call it.  I can't explain it but the problem is gone, and my system is working fine now.

  Many tanks for your help and assistance.

Mark B

Mike McCauley

unread,
Jan 18, 2013, 6:19:06 PM1/18/13
to nrf24-...@googlegroups.com
Hi again,

I have just uploaded version 1.7 with this change:

Improvements to waitPacketSent() so if the chip is not in transmit mode, it
wont wait forever.

I dont know if it will fix your problem, but its probably a sensible change
anyway. Perhaps you will test it?

Cheers.

Ivatt Diesel

unread,
Jan 18, 2013, 6:21:37 PM1/18/13
to nrf24-...@googlegroups.com
Mike,

Yes,I will test this tomorrow (uk time).  Many Thanks.

Mark B

Ivatt Diesel

unread,
Jan 19, 2013, 2:06:17 PM1/19/13
to nrf24-...@googlegroups.com
Mike,

  I'm using V1.7 now, and it is rock solid. I see no problems. It's been running for hours and working fine. I will continue testing and let you know if I see anything.

  On another subject, have  you had success using the modules on an Arduino mega 2560 or Due. I'm in need of a bigger memory footprint, and i've tried using the 2560 using the pins described in the header  file (8, 50..53) but I don't get messages received.  If i move that module back to a uno (8, 10..13) it works fine.  I've tried setting pin 10 to an output on the mega, just in case - any other suggestions?


Mark

Mike McCauley

unread,
Jan 19, 2013, 5:16:56 PM1/19/13
to nrf24-...@googlegroups.com
Hi,

On Saturday, January 19, 2013 11:06:17 AM Ivatt Diesel wrote:
> Mike,
>
> I'm using V1.7 now, and it is rock solid. I see no problems. It's been
> running for hours and working fine. I will continue testing and let you
> know if I see anything.

OK.

>
> On another subject, have you had success using the modules on an Arduino
> mega 2560 or Due. I'm in need of a bigger memory footprint, and i've tried
> using the 2560 using the pins described in the header file (8, 50..53) but
> I don't get messages received. If i move that module back to a uno (8,
> 10..13) it works fine. I've tried setting pin 10 to an output on the mega,
> just in case - any other suggestions?

Works for me out of the box with the nrf24_ping_client / nrf24_ping_server
test progs.

Cheers.
Reply all
Reply to author
Forward
0 new messages