nRF24L01+ isn't as fast as it should be....? - Page 1
Forum section: electronics / projects

author: Boscoe
author_rank: Frequent Contributor
timestamp: May 03, 2019, 03:54:43 pm
content: Hi all,I'm working on a project that involves the nRF24L01+. I'm using the library I've linked to below however I have implemented HW SPI and interrupts on the reception of data.When I send data and waiting for it to send I'm polling the following function as seen in the example:Code:while(nrf24_isSending());I'm setting and resetting a pin on my MCU before and after this while loop to measure the time it takes to transmit. I get a value of 480us for a 32 byte packet which gives a data rate of just 0.533Mb/s, well below the 2Mb/s advertised (I know I won't get 100% throughput).I have turn off ACKs, turned off re transmits and set the speed to 2Mb/s with one byte of CRC.Does anyone have any tips? I find this really strange and can't find anything on the internet about it.Github nRF24 code:https://github.com/kehribar/nrf24L01_plusThanksBoscoe

author: Buriedcode
author_rank: Super Contributor
timestamp: May 03, 2019, 04:20:14 pm
content: The 2Mbps is the over-the-air rate, or symbol rate. So you are correct in that you won't ever get this actual throughput as there's preambles, addresses, CRC's, ACKs and resends. But the time taken isn't just the transmit time, there is also time taken to enable the transmitter, time taken to send the 32-byte packet via SPI - which may have quite a few delays depending on the routine you use, switching channels, and the time taken for the receiver micro to read out the packet from its SPI port.Also note, given how common bit errors are, often a packet has to be resent as there is no FEC, just error checking.Measuring actual throughput can be quite difficult, especially if you're using libraries that aren't optimized for speed. If you're just timing how long it has the "is sending" flag up then the library could be doing any number of things before it actually flags up that its finished, and might not really indicate how long it takes to send data.I must say though, if you measured the end-to-end time as 480us for 32 bytes, 533kbs is pretty fast for these modules!

author: Boscoe
author_rank: Frequent Contributor
timestamp: May 03, 2019, 05:26:24 pm
content: Quote from: Buriedcode on May 03, 2019, 04:20:14 pmThank you for the reply, this information is interesting.So just to confirm, the isSending function for me is just reading a flag in the MCU that is set by the ISR that is triggered when the nRF has sent the data. This means that 480us is purely the nRF module sending data. Putting the data into the FIFO etc is done outside of this time.However, looking at a paper that I don't really just, they are only getting around 300kB/s throughput so maybe I'm doing well like you say.My library is quick, the SPI is fast. Sure, I'm blocking while waiting to send however efficient MCU utilisation is not my goal, fast transmission is. And so I'm just not hitting the throughput I'm after. It's not the end of the world though, I can live with it.I'm not using any auto ACKs for this test - I don't need it. So 480us is just one way.

author: xani
author_rank: Frequent Contributor
timestamp: May 03, 2019, 06:56:33 pm
content: I'd slap logic analyzer on nrf pins and see exactly what is happening. Maybe enable interrupt pin on nrf and monitor that too so you will get signalling exactly when nrf finished its transferThe library doesn't *seem* to use interrupts, just polling, on top of using bit-banged SPI, are you *sure* your bottleneck isn't there ?

author: Buriedcode
author_rank: Super Contributor
timestamp: May 03, 2019, 08:34:31 pm
content: That's the trouble with some libraries. Nothing inherently wrong with using them - but they are often for convenience to just get something working, and can become quite cumbersome trying to make provisions for every feature. Whilst I have nothing against the Arduino platform (I know your library wasn't for Arduino), many libraries for that are far from optimized, but thats not what they're for, they are convenient and get the job done. That's why it can be prudent to look at the code in the library to see exactly what its doing, and perhaps modify it to suit your needs.I'll be quite keen to hear your results, because I last used these devices about a decade ago, and managed just about ~750k full streaming ~10m. But it's been so long I can't remember the details.

author: SiliconWizard
author_rank: Super Contributor
timestamp: May 03, 2019, 11:05:32 pm
content: Sorry if this is obvious, but I just took a look at the library code and they hard-coded the data rate at 1 Mbps and not 2 Mbps, did you modify the library?Another thing to consider, I have used the nRF24L01+ quite a while ago so I don't quite remember, but doesn't it handle auto retransmit? So I think whatever your config is, you're still bound by the receiver itself. Have you tried different channels and different distances? Have you set up a receiving device at all?

author: Boscoe
author_rank: Frequent Contributor
timestamp: May 04, 2019, 07:06:48 pm
content: Quote from: xani on May 03, 2019, 06:56:33 pmQuote from: Buriedcode on May 03, 2019, 08:34:31 pmQuote from: SiliconWizard on May 03, 2019, 11:05:32 pmThank you for your replies but in my first post:QuoteI have totally re implemented the library only really using it as a skeleton to build on - it wasn't very well written originally.As I say I have a GPIO pin going high just after I assert the CE pin and just before I start polling the status register to see when the transmission has completed. The GPIO pin goes low once the polling has determined the transfer is complete. The time from the pin going high to low is 480us. As I said before I have set the device to 2Mb/s no ACKs no retries.ThanksBoscoe

author: xani
author_rank: Frequent Contributor
timestamp: May 06, 2019, 11:33:11 pm
content: Have you looked into 7.8 section of the datasheet ? It describes timing diagram on transmission.130us is "wasted" on PLL lock, add SPI transmission delay and packet's address/flag/crc overhead and you've pretty much "used" at least half of the peak bandwidth.I get a feeling from datasheet that this chip was designed mostly for multiple transmitters/one receiver use cases