Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Issue using the ManualAcknowledgements.ino #949

Closed
pfpp89 opened this issue Feb 24, 2024 · 11 comments · Fixed by #953
Closed

[Question] Issue using the ManualAcknowledgements.ino #949

pfpp89 opened this issue Feb 24, 2024 · 11 comments · Fixed by #953

Comments

@pfpp89
Copy link

pfpp89 commented Feb 24, 2024

Hello,

I have an application where values are requested by a host to one or more clients. The clients consist of specific, non-related modules, usually connected to one or more sensors obtaining some sort of data.

I have created a simple messaging protocol where the host polls each client. The request triggers the generation of a custom, up to date response on the client (in accordance with the message received) and sent back to the host.

Due to these requirements, I started by testing the ManualAcknowledgements.ino official sample, which seems to meet my needs.
I took the sample AS IS, without any modifications (other than debug-mode activation and PA_LEVEL, which doesn’t seem to change anything).

For my tests I am using two official Arduino UNOs, even if I have something else in mind for my final host system.

As for the radios, I use two ITEAD nRF24L01 radios, the small ones, with the on-board antenna. I started by using Amazon radios, where I originally had this same problem, but I imported these from ITEAD since I read some threads talking about acknowledgment issues due to bad quality clone chips.

The nRF24 library version is 1.4.8, available directly on the Arduino IDE library manager.

The radios are also physically extremely close, maybe 5/10 centimeters apart.

I am having an issue with this particular example where messages are sent by the TX board (role 1) and apparently received by the RX board (role 0), but the acknowledgments do not seem to be working properly.

On the TX side, I systematically receive a message:

Transmission failed or timed out

This means that the write() function is always returning FALSE for some reason.

On the RX side, which interestingly prints a message for every message sent on the Serial Monitor, always prints the message:

Received 8 bytes on pipe 1: Hello 0 Response failed.

If I activate de debug mode (pretty print), I have the following information on the TX board at the start of the program:

SPI Frequency = 10 Mhz
Channel = 76 (~ 2476 MHz)
Model = nRF24L01+
RF Data Rate = 1 MBPS
RF Power Amplifier = PA_MAX
RF Low Noise Amplifier = Enabled
CRC Length = 16 bits
Address Length = 5 bytes
Static Payload Length = 8 bytes
Auto Retry Delay = 1500 microseconds
Auto Retry Attempts = 15 maximum
Packets lost on
current channel = 0
Retry attempts made for
last transmission = 15
Multicast = Disabled
Custom ACK Payload = Disabled
Dynamic Payloads = Disabled
Auto Acknowledgment = Enabled
Primary Mode = RX
TX address = 0x65646f4e32
pipe 0 (closed) bound = 0x65646f4e32
pipe 1 ( open ) bound = 0x65646f4e31
pipe 2 (closed) bound = 0xc3
pipe 3 (closed) bound = 0xc4
pipe 4 (closed) bound = 0xc5
pipe 5 (closed) bound = 0xc6

And on the RX board, I have the following information at the start of the program:

SPI Frequency = 10 Mhz
Channel = 76 (~ 2476 MHz)
Model = nRF24L01+
RF Data Rate = 1 MBPS
RF Power Amplifier = PA_MAX
RF Low Noise Amplifier = Enabled
CRC Length = 16 bits
Address Length = 5 bytes
Static Payload Length = 8 bytes
Auto Retry Delay = 1500 microseconds
Auto Retry Attempts = 15 maximum
Packets lost on
current channel = 0
Retry attempts made for
last transmission = 15
Multicast = Disabled
Custom ACK Payload = Disabled
Dynamic Payloads = Disabled
Auto Acknowledgment = Enabled
Primary Mode = RX
TX address = 0x65646f4e31
pipe 0 (closed) bound = 0x65646f4e31
pipe 1 ( open ) bound = 0x65646f4e32
pipe 2 (closed) bound = 0xc3
pipe 3 (closed) bound = 0xc4
pipe 4 (closed) bound = 0xc5
pipe 5 (closed) bound = 0xc6

I also tried using other radios, including some bought from ITEAD, since I read some threads about acknowledgment problems due to bad quality clone chips (my first ones, where the problem is also present, were bought from Amazon)

Can someone please test the ManualAcknowledgements.ino sample and share the test results?

Thank you very much

PFPP

@TMRh20
Copy link
Member

TMRh20 commented Feb 24, 2024

The examples are generally well tested, especially on AVR devices.

Since you've tried multiple radios, I would suggest reading the common issues doc

a: Try using a capacitor connected to the GND and VCC pins
b: Try calling radio.setPALevel(RF24_PA_MIN,0);

This is likely not a problem with the library but a hardware or power supply related issue, so not much we can do. This type of question would typically go in an Arduino or other such forum.

@2bndy5
Copy link
Member

2bndy5 commented Feb 24, 2024

The example is very time-critical. In testing it on my hardware (typically on ATSAMD21 or some other cortex processor or RPi) with known good non-PA/LNA radios, I never really got a 100% success rate (more like ~98%).

After playing with the example's code and TMRh20 reporting 100% on ATMega328p, I just left it as it is now.

Using auto-ACKs with ACK payloads is preferable to me since I don't have to deal with rewriting built-in functionality (like manual-ACKs). But, bad clones (like Si24R1) do present problems with auto-ACK.

@2bndy5
Copy link
Member

2bndy5 commented Feb 24, 2024

From ITEAD site:

  • Voltage: 3-3.6V (recommended 3.3V) V
  • Maximum output power: +20dBm
  • Emission mode current(peak): 115mA
  • Receive Mode Current(peak): 45mA
  • Power-down mode current: 4.2uA

The Max PA output seems inaccurate for radio's with builtin antennas (and the given peak emission current)... I can see from the pictures that they also skipped putting a capacitor by the antenna.
image
This means it would probably work better when you touch it with your finger (a problem also noted in the COMMON_ISSUES doc), in which case a suitable capacitor should be the answer.

@pfpp89
Copy link
Author

pfpp89 commented Feb 25, 2024

Hello

First of all, thank you very much for your confirmation that the sample is working fine, and for your suggestions. I only had little doubt about the sample, but I decided to confirm it anyway. According to my research, this sample does not seem to be the most used, and there seems to be a surprisingly small amount of people that used it as a basis for their projects and shared information about it online.

Due to the time-criticality mentioned by @2bndy5, I am decided to build a proper adaptor to interface the nRF24L01 and the Arduino, and have it built from something like PCBWay. This order may, however, take some time.
I will also consider a cap (something on the range 10uF to 100uF?) between VCC and GND mentioned almost everywhere, as close as possible to the module.

As for the missing cap on the antenna, also mentioned by @2bndy5, my module is somewhat different from the one on the image from the ITEAD website. However, the cap seems to also be missing from mine (image below).

IMG_20240225_093605

I admit I disregarded this information because it mainly pertains PA+LNA versions (which I'm not using here), and touching mine doesn’t seem to help in any way. I will also save this tip for last, since these are microscopic components, and I honestly do not have the material nor the skill to handle them properly.

Thank you very much for your help!

PFPP

@2bndy5
Copy link
Member

2bndy5 commented Feb 25, 2024

I will also consider a cap (something on the range 10uF to 100uF?)

Maybe try both in parallel. We can't say for certain what values would work since it highly depends on how the module is manufactured. IIRC, the COMMON_ISSUES doc blindly recommends 100uF.

touching mine doesn’t seem to help in any way

Thanks for reporting. You shouldn't need to monkey with SMD caps yourself; just play with various capacitance on the VCC & GND lines.

PA_LEVEL, which doesn’t seem to change anything

Yeah, lowering the PA level is a software hack that is supposed to reduce the required current needed to transmit (including auto-ack packets). This is really beneficial for PA/LNA modules, but we have seen it occasionally help avoid an unstable power supply for non-PA/LNA modules.

@pfpp89
Copy link
Author

pfpp89 commented Feb 29, 2024

Hello again!

Ok, my PCBs arrived today from JLCPCB, and I couldn’t wait to make a quick test. There is indeed a huge improvement., thanks a lot @2bndy5!

The sample does not yet work 100%, but the message round-trip is complete, the TX node receives the response correctly and is very consistent.

My only remaining issue, which is persistently gnawing at my inner perfectionist, is the “Response failed” written systematically by the RX side, as shown on the following picture:

Response_Failed_On_Rx

Reading the code, the issue seems to come from the txStandBy which, for some reason, keeps sending false:

radio.writeFast(&payload, sizeof(payload));  // load response to TX FIFO
bool report = radio.txStandBy(150);          // keep retrying for 150 ms

According to the documentation, it should send false if a payload has been sent by the RX but not acknowledged with an ACK packet by the TX. It also states that it can only be reported if the auto-ack feature is on, which, to my understanding is the case since we never call “setAutoAck(false)” on this sample, and it is enabled by default.

I show below the diagram I hastily designed last Sunday, and a preview of the PCB, in the case you think the issue may still related with the setup\hardware (and I am sorry if the board is not perfect, I am absolutely not an electronics\PCB design expert in any way).

The cap I settled with is 100uF electrolytic (without which almost every message fails).

Response_Failed_On_Rx_Schematic Response_Failed_On_Rx_PCBLayout

Thank you very much for your help!

PFPP

@2bndy5
Copy link
Member

2bndy5 commented Feb 29, 2024

bool report = radio.txStandBy(150);

This is the line I usually have to tweak. Remember when I said the example is very time critical? Now, you know why. Try playing with a higher value, like 200 instead of 150.

@TMRh20
Copy link
Member

TMRh20 commented Mar 1, 2024

This bugs me. Why? Because users shouldn't have to use special measure to make this work.

I recreated the issue between a Nano and a Due, then just added a simple delay call. Now it works.

I added delay(1) just before this line

I believe that the constant SPI polling via available is hindering the radio's attempts at handling the ACKS, Data, and switching between RX/TX. Lots of stuff going on internally.

@pfpp89 Please test this out if you can.

      while (!radio.available()) {             // wait for response
        if (millis() - start_timeout > 200){    // only wait 200 ms
          break;
        }
        delayMicroseconds(200);
      }

@TMRh20 TMRh20 added the bug label Mar 1, 2024
@2bndy5
Copy link
Member

2bndy5 commented Mar 1, 2024

We should probably add a comment to explain why the delayMicroseconds() is needed.

      while (!radio.available()) {             // wait for response
        if (millis() - start_timeout > 200){   // only wait 200 ms
          break;
        }
        delayMicroseconds(200);                // relax probing of available()
      }

Honestly, I hadn't thought to tweak the TX side. Probably better to use the IRQ pin (+ radio.maskIrq()) instead of radio.available() for this problem.

@pfpp89
Copy link
Author

pfpp89 commented Mar 1, 2024

Hello!

@pfpp89 Please test this out if you can.

while (!radio.available()) {             // wait for response
   if (millis() - start_timeout > 200){    // only wait 200 ms
     break;
   }
   delayMicroseconds(200);
 }

Thank you very much for the tip @TMRh20, I tested it as soon as I could, and it works like a charm!

See for yourself. Same setup as yesterday, no more “Response failed.” from the TX node:

Success

Also a big thanks to @2bndy5 for the first tips related to my initial hardware setup, which were definitely the cause of my original problem.

One last question @TMRh20: I noticed you changed the issue state to “bug”. Should I leave the issue open for now, even if I consider my issue solved (not using the “close with comment”)? Or do you wish me to close it?

Again, thanks a lot for your help, I can finally continue my project!

PFPP

@TMRh20
Copy link
Member

TMRh20 commented Mar 1, 2024 via email

TMRh20 added a commit that referenced this issue Mar 2, 2024
#949
- Add delay to relax how often available() is called to let the radio internally do its thing
TMRh20 added a commit that referenced this issue Mar 2, 2024
#949
- Add delay to relax how often available() is called to let the radio internally do its thing
* Update examples/ManualAcknowledgements/ManualAcknowledgements.ino

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants