| Electronics > Projects, Designs, and Technical Stuff |
| nRF24L01+ isn't as fast as it should be....? |
| (1/2) > >> |
| Boscoe:
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()); --- End code --- 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_plus Thanks Boscoe |
| Buriedcode:
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! |
| Boscoe:
--- Quote from: Buriedcode on May 03, 2019, 04:20:14 pm ---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! --- End quote --- Thank 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. |
| xani:
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 transfer The library doesn't *seem* to use interrupts, just polling, on top of using bit-banged SPI, are you *sure* your bottleneck isn't there ? |
| Buriedcode:
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. |
| Navigation |
| Message Index |
| Next page |