dparson55 / NRFLite

nRF24L01+ library with AVR 2 pin support, requiring very little code along with YouTube videos showing all available features.
MIT License
161 stars 27 forks source link

NRF24L01+PA+LNA module compatibility #63

Closed RMW946 closed 3 years ago

RMW946 commented 3 years ago

Hello. I've made a couple of projects with nrflite. Really a great library! The issue I have is using the 2 pin control on an Arduino Mega. The SPI pins (50-53) are used for an TFT display and SD card reader.

This handset works fine with a generic nrf24l01. However it locks up when used with a longer range module with antenna. I understand there are differences between radio modules due to different manufacturers. The project has a keypad and 2 pots. Transmit is only on change of state. Pressing the keypad is an auto ack send, and the pots are programmed as No Ack. The pots seem to cause the lock so the assumption is the more fancy radio module cannot cope.

What can I adjust in the library which might help? I have been reluctant to edit libraries until I get familiar with an IDE which can keep different versions, also, I'm more of a hardware person. Any suggestions? Thanks!

IMG_5688

dparson55 commented 3 years ago

Thanks and cool project, I hope you do a write up or make a video showing it in action some day!

One question, since you are already sharing the SPI bus between 2 devices, why not add the radio to the same bus? NRFLite fully supports this, it will only bring the radio's CSN pin low when it needs to communicate with the radio.

But anyway, here are a couple of things to try:

  1. Change the code behind the pots to use a REQUIRE_ACK send rather than NO_ACK send.
  2. Limit how often changing the pots is allowed to perform the NO_ACK send, e.g. if a user turns the pot for 1 second, only allow the NO_ACK send to occur once every 10 milliseconds. So in this case 100 packets would be sent over the course of that 1 second.

Due to the limitations of the 2-pin operation mode, NRFLite is forced to stop the radio from transmitting (or receiving) in order to communicate with it. With NO_ACK sends, the only thing NRFLite can do is wait a specific amount of time between communication attempts with the radio to see if the radio is ready to transmit a new packet. I had to hard code the amount of time to wait in the library and maybe it is too short for the particular radio module you are using. The time to wait is set based on the transmission speed and is assigned to the variable _transmissionRetryWaitMicros here:

2 Mbps https://github.com/dparson55/NRFLite/blob/master/src/NRFLite.cpp#L386 1 Mbps https://github.com/dparson55/NRFLite/blob/master/src/NRFLite.cpp#L393 500 Kbps https://github.com/dparson55/NRFLite/blob/master/src/NRFLite.cpp#L400

This variable is used in the waitForTxToComplete function right here to delay how often NRFLite attempts to communicate with the radio.

RMW946 commented 3 years ago

Option 1, use REQUIRE_ACK solved the problem. Thanks very much! I finished this handset last year and was disappointed the long range radio didn't work. All good now. I will review your other recommendations when I have more time.

Yes, I have looked at networking the SPI with the same TFT_SD module, I will try it on the next version.

The library notes state that all send transmissions are REQ_ACK by default, is that correct? I will review my program and get back with a few more questions if that's ok.

IMG_5711

dparson55 commented 3 years ago

Good news, well glad that fixed it.

Yes the default send type is defined here so if you do not specify one in the send method, it will default to REQUIRE_ACK.