I've got a bunch of Arduinos connected together using the RF24 library (http://maniacbug.github.com/RF24/index.html) and nRF24L01+ transceivers.
It's basically working, but I have a strange problem:
Between some pairs of Arduinos, when I send a message the message arrives, but the radio.write() method returns a false (failure) status code. I think this means that the outgoing message was received, but the sender did not receive an ack from the receiver.
The problem is quite widespread; usually, write() succeeds but returns false. Occasionally, when I start up two Arduinos I don't see this problem; the write() returns true (success) every time for hours on end. And then for no apparent reason, it will start returning false.
When problem is occurring, I will occasionally (perhaps 1 in 100 messages) see a successful ack.
I don't think it is a hardware problem - the problem affects all my Arduinos and they are all capable of sending and receiving.
I don't think it is a signal strength problem - I see the problem when the radios are two feet apart or twenty feet apart.
I see the problem with just two Arduinos running - I don't think it is a collision/overlap problem.
I have a suspicion it may be due to internal behaviour of the RF24 library. Sometimes I have an Arduino that is acting as an intermediary between two other Arduinos, and it will consistently fail to send messages that are initiated locally but it will successfully send a message that is being forwarded (i.e. radio.read() immediately followed by radio.write()) and then subsequent write()s will fail.
I have briefly turned on debug within the RF24 library, got a welter of information that I didn't understand and quickly turned it off again.
Here are two small sketches that demonstrate the problem:
Sender code:
#include <SPI.h>
#include <OneWire.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
//
// Hardware configuration
//
RF24 radio(9, 10);
#define RADIO_GROUND 8
const uint64_t receiverAddress = 0x0000000000000001LL;
unsigned long lastMessageMillis;
#define MESSAGE_INTERVAL_MILLIS 10000
unsigned int message = 0;
void setup(void)
{
//
// Print preamble
//
Serial.begin(9600);
printf_begin(); // enable stdout to Arduino host serial stream
printf("\n\rSimpleSender\n\r");
//
// Setup and configure radio
//
setupRadio();
lastMessageMillis = 0;
}
void setupRadio()
{
pinMode(RADIO_GROUND, OUTPUT);
digitalWrite(RADIO_GROUND, LOW);
delay(500);
radio.begin();
radio.setPALevel(RF24_PA_HIGH);
radio.setRetries(15, 15); // set the number of retries and interval between retries to the maximum
}
void loop(void)
{
if((millis() - lastMessageMillis) > MESSAGE_INTERVAL_MILLIS)
{
lastMessageMillis += MESSAGE_INTERVAL_MILLIS;
//radio.stopListening();
radio.openWritingPipe(receiverAddress);
if( radio.write(&message, sizeof(message)) )
{
printf("Sent %d\r\n", message);
}
else
{
printf("Send %d failed\n\r", message);
// radio.printDetails();
}
//radio.startListening();
message++;
}
}
Sender output:
SimpleSender
Send 0 failed
Send 1 failed
Send 2 failed
...
Receiver code:
#include <SPI.h>
#include <OneWire.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
//
// Hardware configuration
//
RF24 radio(9, 10);
#define RADIO_GROUND 8
const uint64_t receiverAddress = 0x0000000000000001LL;
void setup(void)
{
//
// Print preamble
//
Serial.begin(9600);
printf_begin(); // enable stdout to Arduino host serial stream
printf("\n\rSimpleReceiver\n\r");
setupRadio();
}
void setupRadio()
{
pinMode(RADIO_GROUND, OUTPUT);
digitalWrite(RADIO_GROUND, LOW);
delay(500);
radio.begin();
radio.setRetries(15, 15); // set the number of retries and interval between retries to the maximum
radio.openReadingPipe(1, receiverAddress);
radio.startListening();
}
void loop(void)
{
// if there is data ready
uint8_t pipe;
unsigned int message;
if ( radio.available(&pipe) )
{
if( radio.read(&message, sizeof(message)) )
{
printf("RECEIVED %d\r\n", message);
}
else
{
printf("Radio read failed\n\r");
// radio.printDetails();
}
}
}
Receiver output:
SimpleReceiver
RECEIVED 0
RECEIVED 1
RECEIVED 2
RECEIVED 3
...
Hardware connections are:
1 GND connected to nano pin D8
2 VCC connected to nano pin 3V3
3 CE connected to nano pin D9
4 CSN connected to nano pin D10
5 SCK connected to nano pin D13 =SCK
6 MOSI connected to nano pin D11 =MOSI
7 MISO connected to nano pin D12 =MISO
8 IRQ not connected
Any idea what I'm doing wrong?