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.
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;
}