This is the code I am uploading to both Arduinos, each Arduino connected to one computer. This is the example code of the library with some modifications, as the one made to flush the RX FIFO.
This tries to send the information but I keep receiving the FAIL error. What should I do?
/*
Copyright (C) 2011 James Coliz, Jr. <maniacbug@ymail.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
*/
/**
* Full test on single RF pair
*
* This sketches uses as many RF24 methods as possible in a single test.
*
* To operate:
* Upload this sketch on two nodes, each with IRQ -> pin 2
* One node needs pin 7 -> GND, the other NC. That's the receiving node
* Monitor the sending node's serial output
* Look for "+OK PASS" or "+OK FAIL"
*/
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
//
// Hardware configuration
//
// Set up nRF24L01 radio on SPI bus plus pins 8 & 9
RF24 radio(8, 9); /////////////////////////////////////
// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
// Leave open to be the 'ping' transmitter
const short role_pin = 5;
//
// Topology
//
// Single radio pipe address for the 2 nodes to communicate.
const uint64_t pipe = 0xE8E8F0F0E1LL; ///0xCCCECCCECC
//
// Role management
//
// Set up role. This sketch uses the same software for all the nodes in this
// system. Doing so greatly simplifies testing. The hardware itself specifies
// which node it is.
//
// This is done through the role_pin
//
// The various roles supported by this sketch
typedef enum {
role_sender = 1,
role_receiver
} role_e;
// The debug-friendly names of those roles
const char* role_friendly_name[] = {"invalid", "Sender", "Receiver"};
// The role of the current running sketch
role_e role;
// Interrupt handler, check the radio because we got an IRQ
void check_radio(void);
//
// Payload
//
const int min_payload_size = 4;
const int max_payload_size = 32;
int payload_size_increments_by = 2;
int next_payload_size = min_payload_size;
char receive_payload[max_payload_size + 1]; // +1 to allow room for a terminating NULL char
//
// Test state
//
bool done; //*< Are we done with the test? */
bool passed; //*< Have we passed the test? */
bool notified; //*< Have we notified the user we're done? */
const int num_needed = 10; //*< How many success/failures until we're done? */
int receives_remaining = num_needed; //*< How many ack packets until we declare victory? */
int failures_remaining = num_needed; //*< How many more failed sends until we declare failure? */
const int interval = 100; //*< ms to wait between sends */
char configuration = '1'; //*< Configuration key, one char sent in by the test framework to tell us how to configure, this is the default */
uint8_t pipe_number = 1; // Which pipe to send on. ///////////////////////////////////////
void one_ok(void)
{
// Have we received enough yet?
if (!--receives_remaining) {
done = true;
passed = true;
}
}
void one_failed(void)
{
// Have we failed enough yet?
if (!--failures_remaining) {
done = true;
passed = false;
}
}
//
// Setup
//
void setup(void)
{
//
// Role
//
// set up the role pin
pinMode(role_pin, INPUT);
digitalWrite(role_pin, HIGH);
delay(20); // Just to get a solid reading on the role pin
// read the address pin, establish our role
if (digitalRead(role_pin)) {
role = role_sender;
} else {
role = role_receiver;
}
//
// Print preamble
//
Serial.begin(115200);
printf_begin();
printf("\n\rRF24/tests/pingpair_test/\n\r");
printf("ROLE: %s\n\r", role_friendly_name[role]);
//
// Read configuration from serial
//
// It would be a much better test if this program could accept configuration
// from the serial port. Then it would be possible to run the same test under
// lots of different circumstances.
//
// The idea is that we will print "+READY" at this point. The python script
// will wait for it, and then send down a configuration script that we
// execute here and then run with.
//
// The test controller will need to configure the receiver first, then go run
// the test on the sender.
//
printf("+READY press any key to start\n\r\n\r");
while (!Serial.available()) {
}
configuration = Serial.read();
printf("Configuration\t = %c\n\r", configuration);
//
// Setup and configure rf radio
//
if (!radio.begin()) {
Serial.println(F("radio hardware not responding!"));
while (1) {} // hold program in infinite loop to prevent subsequent errors
}
if (!radio.isChipConnected()) {
Serial.println(F("Chip not connected."));
while (1) {} // hold program in infinite loop to prevent subsequent errors
}
// We will be using the Ack Payload feature, so please enable it
radio.enableAckPayload();
radio.enableDynamicPayloads(); // needed for using ACK payloads
// Config 2 is special radio config
if (configuration == '2'){
radio.setCRCLength(RF24_CRC_8);
radio.setDataRate(RF24_250KBPS);
radio.setChannel(10);
}else{
//Otherwise, default radio config
// Optional: Increase CRC length for improved reliability
radio.setCRCLength(RF24_CRC_16);
// Optional: Decrease data rate for improved reliability
radio.setDataRate(RF24_1MBPS);
// Optional: Pick a high channel
radio.setChannel(90);
}
// Config 3 is static payloads only
if (configuration == '3'){
next_payload_size = 16;
payload_size_increments_by = 0;
radio.setPayloadSize(next_payload_size);
}else{
// enable dynamic payloads
radio.enableDynamicPayloads();
}
// Config 4 tests out a higher pipe ##
if (configuration == '4' && role == role_sender){
// Set top 4 bytes of the address in pipe 1
radio.openReadingPipe(1, 0xFFFFFFFF00ULL);
// indicate the pipe to use
pipe_number = 5;
}else if (role == role_sender){
radio.openReadingPipe(5, 0xFFFFFFFF00ULL);
}
//
// Open pipes to other nodes for communication
//
// This simple sketch opens a single pipe for these two nodes to communicate
// back and forth. One listens on it, the other talks to it.
if (role == role_sender){
radio.openWritingPipe(pipe);
}else{
radio.openReadingPipe(pipe_number, pipe);
}
//
// Start listening
//
if (role == role_receiver){
radio.startListening();
}
//
// Dump the configuration of the rf unit for debugging
//
radio.printDetails();
//
// Attach interrupt handler to interrupt #0 (using pin 2)
// on BOTH the sender and receiver
//
attachInterrupt(0, check_radio, FALLING);
delay(50);
if (role == role_receiver){
printf("\n\r+OK ");
}
}
//
// Print buffer
//
// Printing from the interrupt handler is a bad idea, so we print from there
// to this intermediate buffer
//
char prbuf[1000];
char* prbuf_end = prbuf + sizeof(prbuf);
char* prbuf_in = prbuf;
char* prbuf_out = prbuf;
//
// Loop
//
static uint32_t message_count = 0;
static uint32_t last_message_count = 0;
void loop(void){
//
// Sender role. Repeatedly send the current time
//
if (role == role_sender && !done){
// The payload will always be the same, what will change is how much of it we send.
static char send_payload[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ789012";
// First, stop listening so we can talk.
radio.stopListening();
// Send it. This will block until complete
printf("\n\rNow sending length %i...", next_payload_size);
radio.startWrite(send_payload, next_payload_size, 0);
// Update size for next time.
next_payload_size += payload_size_increments_by;
if (next_payload_size > max_payload_size){
next_payload_size = min_payload_size;
}
// Try again soon
delay(interval);
// Timeout if we have not received anything back ever
if (!last_message_count && millis() > interval * 100){
printf("No responses received. Are interrupts connected??\n\r");
done = true;
}
}
//
// Receiver role: Does nothing! All the work is in IRQ
//
if (role == role_sender && !done){
radio.flush_rx();
}
//
// Spew print buffer
//
size_t write_length = prbuf_in - prbuf_out;
if (write_length){
Serial.write(reinterpret_cast<uint8_t*>(prbuf_out), write_length);
prbuf_out += write_length;
}
//
// Stop the test if we're done and report results
//
if (done && !notified){
notified = true;
printf("\n\r+OK ");
if (passed){
printf("PASS\n\r\n\r");
}else{
printf("FAIL\n\r\n\r");
}
}
}
void check_radio(void)
{
// What happened?
bool tx, fail, rx;
radio.whatHappened(tx, fail, rx);
// Have we successfully transmitted?
if (tx){
if (role == role_sender){
prbuf_in += sprintf(prbuf_in, "Send:OK ");
}
if (role == role_receiver){
prbuf_in += sprintf(prbuf_in, "Ack Payload:Sent\n\r");
}
}
// Have we failed to transmit?
if (fail){
if (role == role_sender){
prbuf_in += sprintf(prbuf_in, "Send:Failed ");
// log status of this line
one_failed();
}
if (role == role_receiver){
prbuf_in += sprintf(prbuf_in, "Ack Payload:Failed\n\r");
}
}
// Not powering down since radio is in standby mode
//if (( tx || fail ) && ( role == role_sender )){ radio.powerDown(); }
// Did we receive a message?
if (rx){
// If we're the sender, we've received an ack payload
if (role == role_sender){
radio.read(&message_count, sizeof(message_count));
prbuf_in += sprintf(prbuf_in, "Ack:%lu ", message_count);
// is this ack what we were expecting? to account
// for failures, we simply want to make sure we get a
// DIFFERENT ack every time.
if ((message_count != last_message_count) || (configuration == '3' && message_count == 16)){
prbuf_in += sprintf(prbuf_in, "OK ");
one_ok();
}else{
prbuf_in += sprintf(prbuf_in, "FAILED ");
one_failed();
}
last_message_count = message_count;
}
// If we're the receiver, we've received a time message
if (role == role_receiver){
// Get this payload and dump it
size_t len = max_payload_size;
memset(receive_payload, 0, max_payload_size);
if (configuration == '3'){
len = next_payload_size;
}else{
len = radio.getDynamicPayloadSize();
}
radio.read(receive_payload, len);
// Put a zero at the end for easy printing
receive_payload[len] = 0;
// Spew it
prbuf_in += sprintf(prbuf_in, "Recv size=%i val=%s len=%u\n\r", len, receive_payload, strlen(receive_payload));
// Add an ack packet for the next time around.
// Here we will report back how many bytes we got this time.
radio.writeAckPayload(pipe_number, &len, sizeof(len));
++message_count;
}
}
}