I found the problem occurs because the transmitter is expecting acknowledgment from the receiver which is getting lost somehow, while transmission and the transmitter still waits for ack for the last transmitted data (which it never gets) so it keeps on transmitting the last packet again and again. I saw on forums that its because of the TX buffer getting full after 3 retries or something. I don't exactly know why it happens.
I first tried resetting just the transmitter through code but it was not enough (as already mentioned in the question). So I now reset both the TX and RX using the below code. I have a separate 1 byte reset-counter in the first byte of the array (you may use a single byte variable) which acts as an id for the packet (you may use the internal PID as well).
The below code resets the TX if transmission fails by checking the return value of write
function and resets the RX when it receives the same ack or packet (with the same reset-counter value) more than 2 times (I use a condition to check if the last counter value is different from the current one or not). To reset it using code I use the below algorithm :
- Power Down the NRF using
powerDown()
function.
- Re-initialize the nrf for the MCU.
- Power Up the NRF using
powerUp()
function.
Note: I am using TMRH20 RF24 Library.
TX Code
void radio1_init()
{
pinMode(9, OUTPUT);
digitalWrite(9, HIGH);
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
myRadio1.begin();
delay(100);
myRadio1.setChannel(96);
myRadio1.setPALevel(POWERLEVEL);
myRadio1.setDataRate(DATARATE);
myRadio1.setAutoAck(1);
myRadio1.enableAckPayload();
myRadio1.enableDynamicPayloads();
myRadio1.setRetries(2, 10);
myRadio1.setCRCLength(RF24_CRC_8);
myRadio1.openWritingPipe( addresses1[0]);
}
void loop()
{
dataTransmitted[0]++;
if ( myRadio1.write( &dataTransmitted, sizeof(dataTransmitted)))
{
if (myRadio1.isAckPayloadAvailable())
{
myRadio1.read(&ack, sizeof(ack));
}
}
else
{
myRadio1.powerDown();
\\Serial.println(" 1 Tx1 problem end");
radio1_init();
myRadio1.powerUp();
}
}
RX Code
void radio2_init()
{
pinMode(9, OUTPUT);
digitalWrite(9, HIGH);
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
myRadio2.begin();
delay(100);
myRadio2.setChannel(96);
myRadio2.setPALevel(POWERLEVEL);
myRadio2.setDataRate(DATARATE);
myRadio2.setAutoAck(1);
myRadio2.enableAckPayload();
myRadio2.enableDynamicPayloads();
myRadio2.setRetries(10, 10);
myRadio2.setCRCLength(RF24_CRC_8);
myRadio2.openReadingPipe(1, addresses2[0]);
myRadio2.startListening();
}
void loop()
{
if (myRadio2.available())
{
myRadio2.read( &dataReceived, sizeof(dataReceived));
myRadio2.writeAckPayload(1, &ack2, sizeof(ack2));
if (prevack2 == dataReceived[0])
{
\\Serial.println("RX 2 problem");
c2++;
}
prevack2 = dataReceived[0];
if (c2 > 2)
{
myRadio2.powerDown();
radio2_init();
myRadio2.powerUp();
c2 = 0;
}
}
}