Hi amazing Arduino community,
I'm starting to loose my mind on a problem regarding the RF24 library and two arduino DUE.
I've cleaned my code so you can have a look at it. I work on an arduino DUE with nRF24L01+ modules.
There is one master device that initiates the communication and then the system follows the followin pattern :
Master sends message 1
Salve answers with message 2
Master answers with message 3
Master sends second answer with message 4
And the loop starts again.
Here is my code :
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
// Hardware configuration
RF24 globalRadio(57,77); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
// =======================================================
// Defines the attirbutes of the RF24Controller class that I use for my radio communication
// =======================================================
class RF24Controller
{
public:
virtual ~RF24Controller();
void begin(int device);
void Send(byte id);
RF24 &_radio;
//protected:
RF24Controller(uint8_t IRQPin, uint8_t CEPin, uint8_t CSPin, RF24 & radio = globalRadio);
uint32_t _timeSync;
byte doInterrupt();
bool _isDoneTransmitting;
uint8_t _IRQPin;
};
// =======================================================
// Other variables that will be used throughout the code
// =======================================================
// Demonstrates another method of setting up the addresses
byte address[][5] = { 0xCC,0xCE,0xCC,0xCE,0xCC , 0xCE,0xCC,0xCE,0xCC,0xCE};
volatile uint32_t emissionTimeStamp = 0;
volatile uint32_t receptionTimeStamp = 0;
volatile bool failed = false;
RF24Controller testRadio(55,57,77);
// =======================================================
// Defines the role of the bord : set to 1 to act as the master or to 2 to act as a slave
// =======================================================
int role = 1;
/********************** Setup *********************/
void setup(){
pinMode(55, INPUT);
delay(20);
SerialUSB.begin(115200);
testRadio.begin(role);
}
/********************** Main Loop *********************/
void loop() {
static uint32_t timer = 0;
static bool resendInfo = false;
static uint32_t lastSent = 0;
// =======================================================
// Master sends message 1 every 100 ms
// =======================================================
if (role == 1) {
if(millis() - timer > 100)
{
SerialUSB.print(F("Now sending "));
SerialUSB.println(timer);
testRadio.Send(1);
timer = millis();
}
}
byte id = testRadio.doInterrupt();
// =======================================================
// Depending on the received message, we answer with another message
// =======================================================
if(id != 0)
{
SerialUSB.println("Received " + String(id));
if(id == 1)
testRadio.Send(2);
if(id == 2)
{
testRadio.Send(3);
resendInfo = true;
lastSent = millis();
}
}
if(millis() - lastSent > 10 && resendInfo)
{
testRadio.Send(4);
resendInfo = false;
}
}
// =======================================================
// Definition of the methods of the RF24Controller class
// =======================================================
RF24Controller::RF24Controller(uint8_t IRQPin, uint8_t CEPin,
uint8_t CSPin, RF24 & radio) : _radio(radio)
{
_IRQPin = IRQPin;
_timeSync = 0;
}
RF24Controller::~RF24Controller() {}
void catchInterrupt()
{
uint32_t interruptTime = micros();
bool tx,fail,rx;
globalRadio.whatHappened(tx,fail,rx);
if ( tx || fail)
{
emissionTimeStamp = interruptTime;
failed = fail;
}
else if ( rx || globalRadio.available())
{
receptionTimeStamp = interruptTime;
}
}
byte RF24Controller::doInterrupt()
{
static uint32_t lastReceptionTime = 0;
static uint32_t lastEmissionTime = 0;
byte tmp[32];
uint8_t size;
if (lastReceptionTime != receptionTimeStamp)
{
lastReceptionTime = receptionTimeStamp;
while (_radio.available())
{
size = _radio.getDynamicPayloadSize();
_radio.read(tmp, size);
}
return (tmp[0]);
}
else if (emissionTimeStamp != lastEmissionTime)
{
lastEmissionTime = emissionTimeStamp;
_radio.flush_tx();
_radio.startListening();
SerialUSB.println("Emission\t" + String(failed));
}
return 0;
}
void RF24Controller::begin(int device)
{
pinMode(_IRQPin, INPUT);
byte address2[][5] = { 0xCC,0xCE,0xCC,0xCE,0xCC , 0xCE,0xCC,0xCE,0xCC,0xCE};
_radio.begin();
_radio.setPALevel(RF24_PA_MAX);
//globalRadio.setDataRate(RF24_250KBPS);
_radio.setRetries(0, 0);
_radio.enableDynamicPayloads();
//_radio.setChannel(108);
_radio.setAutoAck(true);
if(device == 1)
{
_radio.openReadingPipe(1, address2[1]);
_radio.openWritingPipe(address2[0]);
}
else if(device == 2)
{
_radio.openReadingPipe(1, address2[0]);
_radio.openWritingPipe(address2[1]);
}
_radio.startListening();
delay(50);
attachInterrupt(digitalPinToInterrupt(_IRQPin),
catchInterrupt, LOW);
}
void RF24Controller::Send(byte id)
{
_radio.stopListening();
byte buffer[30]= {0};
buffer[0] = id;
_radio.startWrite(buffer, 30, false);
}
I have defined a class that is supposed to deal with the RF24 messages.
Before the Setup you can define a role : 1 is master and 2 is slave.
I print each time i receive a message and also I print the fail status each time I send a message.
Now when I have both devices communicating I should get the following information :
On the master side :
Now sending 54641
Emission 0
Received 2
Emission 0
Emission 0
And on the slave side:
Received 1
Emission 0
Received 3
Received 4
But almost every two messages, I have the "Emission 0" on the slave side (which means that the message went over and the ACK was received) but I don't have any "Received 2" on the master side.
And more incredibly, when I comment the "Send(4)" line everything works normally...
I would really appreciate your help on this matter
If you need any more explanation or details I will be glad to provide them.
Thanks a lot,
Regards