2

I’m trying to create a link between two nRF24L01 units. Each nRF24L01+-based module (purchased) is connected to Arduino Nano on a custom-designed PCB.

The printed wiring is per the hardware application, and is functionally verified by the positive result of the isChipConnected() method.

enter image description here

The NRF24L01 is fed from the Nano 3.3V output. According to the component’s datasheet this should be OK:

• According to the datasheet the max consumption is 9mA when transmitting in high power. The Nano output can source up to 150mA. So it doesn't close to the limit.

• I measured the 3.3V supply line and the value is 3.23V on both modules (the specified minimum is 3.0V).

• The supply line is being filtered by a 10uF cap.

The two stations are using the same code; the roles are being defined by the level of an IO pin. It contains two modules - the application and the high-level driver class.

Now to the problem: According to the Arduino screenshots it appears that the transmitter does not sending the data. Since the low-level transmitting routine (radio.write()) is waiting for the receiver auto acknowledge, I considered also the possibility that receiver side doesn't send the auto-ACK. However, I Switched off the auto acknowledge in both stations and the result wasn't changed.

Any clue will be helpful. Thank tou.

#define Radio0_IRQ   2
#define TerminalPin  6
#define CsnPin       10
#define terminalRole 1

String msgHeader;
bool role;
/************************************************/
void(*resetFunc) (void) = 0;//declare reset function at address 0
/***********************************************************/
#include "radioPortClass.h"
RadioPort communicationPort;

/************************************************/
void setup(void)
{
  pinMode(TerminalPin, INPUT_PULLUP);
  role = !digitalRead(TerminalPin);
  if(role == terminalRole)
    msgHeader = "Terminal: ";
  else
    msgHeader = "Field unit: ";

  Serial.begin(9600);
  while (!Serial)
    delay(10);
  if (communicationPort.portInit(role))
    Serial.println(msgHeader + "Port initiated successfully\n\n");
  else if (!radio.isChipConnected ())
  {
    Serial.println(msgHeader + "Port initiation failed\n\n");
    delay(2000);
    resetFunc();
  }
}
/***********************************************************/
void loop(void)
{
  if (role == terminalRole)
  {
// Terminal role. Transmit a message and receive the reply
    if (!communicationPort.tx("Terminal to field unit"))
      Serial.println(msgHeader + "Failed, transmit timed out.\n\n");
    else
    {
      Serial.print(msgHeader + "Got response: ");
      delay(1000);
      Serial.println(communicationPort.rx());
      started_waiting_at = millis();
    }
    delay(3000);
  }
  else  // Field unit role. Receive each packet, print it and reply
  {
    String receive_payload = communicationPort.rx();
    if (receive_payload == "\0")
    {
      if((millis() - started_waiting_at) > rxDelay)
      {
        Serial.println(msgHeader + "Failed, receive timed out.\n\n");
        delay(100);
        resetFunc(); //call reset    
      }
    }
    else
    {
      Serial.print  (msgHeader + "Got payload: ");
      Serial.println(receive_payload);
      if (!communicationPort.tx("Field unit to terminal"))
        Serial.println(msgHeader + "Failed, transmit timed out.\n\n");
      else
        Serial.println(msgHeader + "Sent response.\n\n");
    }
  }
}
 
Radio Driver
class RadioPort
{
  public:
    bool tx(String txData);
    String rx(void);
    bool portInit(bool role);
};
#include "RF24.h"
RF24 radio(9, CsnPin);

const uint64_t pipes[2] = {0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL};
#define rxDelay   1000
#define txDelay   100
unsigned long started_waiting_at;

/************************************************/
bool RadioPort::tx(String txData)
{
// First, stop listening so we can talk.
  radio.stopListening();
  bool success = radio.write(&txData, txData.length());
  radio.startListening();
  return success;
}
/************************************************/
String RadioPort::rx(void)
{
 // if there is data ready
  if (radio.available())
  {
// Fetch the payload, and see if this was the last one.
    uint8_t len = radio.getDynamicPayloadSize();
    char receive_payload[len + 1];
    radio.read(receive_payload, len);
// Put a zero at the end for easy printing
    receive_payload[len] = 0;
    return receive_payload;
  }
  else return "\0";      // Dummy statement, for the compiler warning
}
/************************************************/
bool RadioPort::portInit(bool role)
{
  pinMode(Radio0_IRQ, INPUT_PULLUP);
  radio.begin();//(5,CsnPin)
  if(!radio.isChipConnected ())
    return false;

  radio.enableDynamicPayloads();
  radio.setRetries(15,15);
  radio.setPALevel(0, true);
  radio.setChannel(105);
  radio.setAutoAck(false);//true);
  
  if (role == terminalRole)
  {
    radio.openWritingPipe(pipes[0]);
    radio.openReadingPipe(1,pipes[1]);
  }
  else
  {
    radio.openWritingPipe(pipes[1]);
    radio.openReadingPipe(1,pipes[0]);
    started_waiting_at = millis();
  }
  radio.startListening();
  return true;
}
2
  • "According to the Arduino screenshots" what screenshots? Are you confirming that each Arduino is in its correct role?
    – timemage
    Commented Mar 17, 2021 at 20:31
  • Yes: I open a serial monitor for every station. As can be seen from the code, the major activity of the LOOP method of the sketch is printing messages to the serial, which are visible on the serial monitor. All the messages are invoked by failure feedback of the tx and rx methods. The messages are prefixed with the station role, so I know which one sent it. Commented Mar 18, 2021 at 8:57

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.