nRF24 proper multi device settings

I am trying to configure a multi-point system. I will have one controller, and up to 5 remotes.

Here is my end game:

Controller broadcasts to all remotes on pipeLine0. Controller listens on pipeLine1-5.

Remote 1 listens on pipeLine0 and transmits on pipeLine1
Remote 2 listens on pipeLine0 and transmits on pipeLine2
Remote 3 listens on pipeLine0 and transmits on pipeLine3
Remote 4 listens on pipeLine0 and transmits on pipeLine4
Remote 5 listens on pipeLine0 and transmits on pipeLine5

My first question is about the naming of the pipeLines. I have seen 2 variants:

variant 1

const byte pipeLine[] = {"00006", "00005", "00004", "00003", "00002", "00001"};

variant 2

const uint64_t pipeLine[] = {0x7878787878LL, 0xB3B4B5B6F1LL, 0xB3B4B5B6CDLL, 0xB3B4B5B6A3LL, 0xB3B4B5B60FLL, 0xB3B4B5B605LL };

Which is the better option and what is the difference? Can I just use a pure number? for example:

const int pipeLine[] = {6, 5, 4, 3, 2, 1};

Now on to the second portion.

Using my notes above, my controller will have all 6 pipelines active. My remotes will only have 2 pipelines active. They will have pipeLine0 and pipeLine? where ? is the unit number. I would like to be able to go into my remote unit code and have this feature:

// This is in the remote
// It will only have pipeLine0 and pipeLine1 active, I just need to make sure the 2 pipeLines match the Controller

const int unitNum = 2;
pipeLine[1] = unitNum + 1;  // adjusts for 0 channel

Where all I have to do is set the unit number, and everything else adjusts. Is this possible?

I am not familiar with the NRF24 devices, but have two on order to learn about them

What is the purpose of all the different pipes and how will they be used?

Paul

The pipes can be a bit of a distraction especially because some of the demo programs use a variable named pipe to hold the address. For most applications there is no need to use more than one pipe - even for communication with a 100 other devices.

Think of the pipes as 6 shelves onto which the mail for different residents in an apartment block can be placed. All the letters come through the same mail slot (the radio receiver listening on Channel N) and when they fall on the floor someone picks them up, looks at the name of the recipient (the address the message was sent to) and puts them on the correct shelf (the pipe that has been assigned the same address as the message) or shreds them if they are for a recipient who lives in another block (i.e. if they are for an address that is not assigned to any of the pipes on this nRF24)

One reason for using multiple pipes is so that the receiver can identify who sent the message. IMHO it is easier to do that by including an ID code in each message.

There is only one wireless receiver so, even if multiple pipes are being used, only one message can be received at any one time. If two or more messages are transmitted at the same time both will be garbled.

This Simple nRF24L01+ Tutorial may help. There is an example of a master communicating with 2 slaves that can be extended to a large number of slaves.

...R

Thank you. That did help explain the idea behind the "pipes".

My end game is to have a single arduino nano (master) listen for (up to) 6 other arduino nanos (remotes).

My theory/understanding/etc is that each remote unit will be on it's own single "channel". I want the master to send a ping to remote 0, get an acknowledgement from remote 0. Then do this with remote 1, 2, 3, 4, & 5.

Then after I run the ping cycle, each remote that does not respond, I count a flag. So, let's say I run the ping cycle 10 times, and remote 3 did not respond at all. There will be a counter that holds "10" for 10 fails.

When a remote goes into failure, I get a notice (an LED pops up on the master to indicate which remote has failed).

That is the end game. Right now I am working on getting this process to work just with one master and one remote.

I am trying to have a single nano talk to another single nano via a nRF24L01.

The master is sending a random number to the remote. The remote hears it and immediately sends the number back.

Trouble is, when the code hits the radio.write command, it locks up.

Here is my master ino file:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

//============  Constants  ============
// ---- Sets Pins ----
const int led = 0;                // the pin numbers for the Inputs and Outputs
const int siren = 1;              // the pin numbers for the Inputs and Outputs
const int reset = 2;              // the pin numbers for the Inputs and Outputs

// ---- Program Values ----
const int unitNumber = 0;         // Sets the pair out of the 6 programmed channels
const int alarmLimit = 20;        // Number of failed cycles after activation

// ---- Radio Setup ----
RF24 radio(7, 8); // CE, CSN
const byte deviceID[6] = {0xC76F601D00,0xC76F601D01,0xC76F601D02,0xC76F601D03,0xC76F601D04,0xC76F601D05};

//============  VARIABLES (will change)  ============
int alarmSet = LOW;
int dataSend = 0;
int dataReceive = 0;
int alarmCount = 0;

//============  Setup function  ============
void setup() {
  Serial.begin(9600);
  
// ---- Activate pins ----
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, INPUT);

// ---- Activate Radio ----
  radio.begin();
  radio.openWritingPipe(deviceID[unitNumber]);
  radio.openReadingPipe(unitNumber, deviceID[unitNumber]);
  radio.setPALevel(RF24_PA_MIN);
  radio.setChannel(115);
  radio.setPayloadSize(1);        // Sets payload to 1 byte
  radio.setDataRate(RF24_250KBPS);
  radio.setAutoAck(unitNumber, false);

// ---- Activate Random Generator ----
  randomSeed(analogRead(15));      //create unique seed value for random number generation 
}

//============  Loop Function  ============
void loop() {
  Serial.println("Loop Start");
  rxtx();
  Serial.println("Loop End");
}

//============  Send/Recieve Function  ============
/*
 * Sends data and listens back to make sure remote is in range
 */
void rxtx() {
  Serial.println("rxtx Start");
  uint8_t deadPool = random(255);
  uint8_t frankCastle = 0;
  int iTx = 0;
  int iRx = 0;
  Serial.println("variables created");

  //Begin Transmission and send for 10ms
  for (int iTx=0; iTx <= 10; iTx++){
    Serial.println("TX Start");
    radio.stopListening();
    Serial.println("Stop Listening");
    radio.write(&deadPool, 1);
    Serial.println("TX data");
    delay(1);
    Serial.println("delay");
  }

  //Begin Receive and listen for 10ms
  for (int iRx=0; iRx <= 10; iRx++){
    Serial.println("RX Start");
    radio.startListening();
    radio.read(&frankCastle, 1);
    delay(1);
  }
  dataSend = deadPool;
  dataReceive = frankCastle;
  Serial.print("RxTx Cycle Finished");
  Serial.print(dataSend);
  Serial.print(dataReceive);
  Serial.print("");
}

I put in the serial.print lines to see where it was hanging up.

On the serial monitor, I get the following:
Loop Start
rxtx Start
Variables created
TX Start
Stop Listening

.........and this is where it hangs. So It appears that the line

radio.write(&deadPool, 1);

is the issue.

Did I miss a command ahead of this line? Am I missing some kind of acknowledge? From the tutorials I read, this should just blast TX for 10ms and then flip to receive.

Thank you for your help.

vader7071:
The master is sending a random number to the remote. The remote hears it and immediately sends the number back.

Trouble is, when the code hits the radio.write command, it locks up.

Those two lines taken together lead me to believe that nothing is working.

If you are new to nRF24 wireless have a look at the examples in this Simple nRF24L01+ Tutorial

Be sure to use the TMRh20 version of the TF24 library. Unfortunately it has the same name as the earlier ManiacBug version which has some problems. If in doubt delete all versions and then install the correct one.

...R

vader7071:
My theory/understanding/etc is that each remote unit will be on it's own single "channel". I want the master to send a ping to remote 0, get an acknowledgement from remote 0. Then do this with remote 1, 2, 3, 4, & 5.

You are getting your jargon mixed up.

"Channel" determines the frequency that the wireless devices use. They must all use the same channel as the master.

Each slave should have its own "address".

The master-to-multiple-slaves example in my Tutorial should be suitable for what you describe unless you want your slaves to spend most of the time asleep to save energy - but you have not said so.

...R

Power saving is way down the list. The mission critical part is making sure the units are in range. If they get out of range, I need to know immediately.

Thank you. I'll go through that.

Yes I am new to the nRF24.

When I loaded the library, I used the "Include Library" feature in the IDE. I used sketch -> include library -> manage library and from there I searched RF24. The one I found was RF24 by TMRh20 v 1.3.1

I have just realized you have started two Threads about the same thing. I am suggesting to the Moderator to merge them so all the info is one place.

...R

MOderator: merged topics as they are quite related.

Sorry. While I knew they were related, I didn't think they needed to be in the same thread.

But, continuing with the process, I have tried multiple examples. I have tried your base code, Robin2, I have tried other examples. All of them seem to lock up when it hits the

radio.write(msg, 1);

line.

Watching the serial monitor, and putting the radio.write line inside of an if command that I can externally trigger, the code just stops.

In my latest test, I set a switch to write to the monitor its status. Then a second switch activates the if statement and triggers the radio.write. As soon as the radio.write gets triggered, the serial monitor stops. No more printing the switch status.

vader7071:
I have tried your base code, Robin2, I have tried other examples. All of them seem to lock up when it hits the

radio.write(msg, 1);

line.

Post the programs from my examples that YOU have uploaded and post samples of the output that they two programs produce. I want to be certain that you are using my code with NO changes - debugging wireless is difficult enough without having to deal with minor variations.

...R

Here is what I did in order:

Step 0) Hardware: (2) Arduino Nano ATMega168, (2) nRF24L01 (I do not remember if + or not).

Step 1) Went to the thread of your tutorial: Simple nRF24L01+ 2.4GHz transceiver demo - Exhibition / Gallery - Arduino Forum

Step 2) copied exactly your SimpleTx.ino code from the post (select all, copy, open new file in IDE, paste, save).

Step 3) copied exactly your SimpleRx.ino code from the post (select all, copy, open new file in IDE, paste, save).

Step 4) run SimpleTx.ino on Nano(1).

Step 5) run SimpleRx.ino on Nano(2).

Step 6) open serial monitor on Nano(2). Serial Monitor shows:

SimpleRx Starting
Data received 
Data received 
Data received 
Data received
Data received 
Data received 
Data received 
Data received 
Data received 
Data received

Step 7) open serial monitor on Nano(1). Serial Monitor shows:

SimpleTx Starting

(pause for comment) - I noticed that according to SimpleRx.ino, the code should have been:

SimpleRx Starting
Data received 
{value}
Data received 
{value}

or

SimpleRx Starting
Data received {value}
Data received {value}

Did not get this. from what I could tell from the code, it appeared that the Nano(2) thought it was getting data, just nothing there.

Looking at the SimpleTx.ino code, I was supposed to get:

SimpleTx Starting
Data Sent 
{value}
Data Sent 
{value}

or

SimpleTx Starting
Data Sent {value}
Data Sent {value}

But I was not getting this at all. Just the "SimpleTX Starting".

vader7071:
But I was not getting this at all. Just the "SimpleTX Starting".

You seem to have missed the first part of my request in Reply #12

Post the programs from my examples that YOU have uploaded

...R

As copied from thread: Simple nRF24L01+ 2.4GHz transceiver demo - Exhibition / Gallery - Arduino Forum

As entered in reply #1 to original post in above thread:

Copied as typed in reply, and pasted into a new ino file:

// SimpleTx - the master or the transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>


#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[5] = {'R','x','A','A','A'};


RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataToSend[10] = "Message 0";
char txNum = '0';


unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second


void setup() {

    Serial.begin(9600);

    Serial.println("SimpleTx Starting");

    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress);
}

//====================

void loop() {
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
        prevMillis = millis();
    }
}

//====================

void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    Serial.print(dataToSend);
    if (rslt) {
        Serial.println("  Acknowledge received");
        updateMessage();
    }
    else {
        Serial.println("  Tx failed");
    }
}

//================

void updateMessage() {
        // so you can see that new data is being sent
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[8] = txNum;
}

As copied from thread: Simple nRF24L01+ 2.4GHz transceiver demo - Exhibition / Gallery - Arduino Forum

As entered in reply #1 to original post in above thread:

Copied as typed in rely, and pasted into a new ino file:

// SimpleRx - the slave or the receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.startListening();
}

//=============

void loop() {
    getData();
    showData();
}

//==============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        newData = true;
    }
}

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        newData = false;
    }
}

Method used to copy and paste:

in reply on thread, click "[Select]" link in code block and highlight all. Press CTRL+C on keyboard. Open new ino file in Arduino IDE. In ino file, press CTRL+A on keyboard to select all. Then press CTRL+C to paste code copied from above referenced thread. Do this for SimpleTx.ino and SimpleRx.ino

Results from above sketches running:

Step 4) run SimpleTx.ino on Nano(1).

Step 5) run SimpleRx.ino on Nano(2).

Step 6) open serial monitor on Nano(2). Serial Monitor shows:

SimpleRx Starting

Data received
Data received
Data received
Data received
Data received
Data received
Data received
Data received
Data received
Data received




Step 7) open serial monitor on Nano(1). Serial Monitor shows:



SimpleTx Starting




(pause for comment) - I noticed that according to SimpleRx.ino, the code should have been:


SimpleRx Starting
Data received
{value}
Data received
{value}




or



SimpleRx Starting
Data received {value}
Data received {value}




Did not get this. from what I could tell from the code, it appeared that the Nano(2) thought it was getting data, just nothing there. 

Looking at the SimpleTx.ino code, I was supposed to get:



SimpleTx Starting
Data Sent
{value}
Data Sent
{value}




or



SimpleTx Starting
Data Sent {value}
Data Sent {value}




But I was not getting this at all. Just the "SimpleTX Starting".

Thank you for posting the code. I know it seems tedious but many people make little changes that they think won't matter and never say so.

This (in your TX program)

But I was not getting this at all. Just the "SimpleTX Starting".

suggests that there is a crash before the line that prints "Data sent". I have never come across that before.

Try putting Serial.println("Ready to send"); just before the line rslt = radio.write(

If that prints it suggests that the SPI part is not working - whether through a fault in the Arduino or in the nRF24 I don't know. Try running the program with the nRF24 completely disconnected.

Are you sure you have the correct RF24 library installed? Maybe it would be worth deleting it completely and reinstalling it.

What version of the Arduino IDE are you using?

Separately - relating to the RX program ....

I presume the Data received is repeating very quickly. If everything is working it should be once per second. The fast repetition has happened to me a few times and I think it is due to a poor or incorrect connection. Maybe it would also happen if the nRF24 is faulty.

...R

The RX "Data Received" was about 1 second. It kept going as long as I was connected.

The TX side. I will try that and see. The RF24 should be the newest 1.3.1, but I will remove and reinstall. Can't hurt.

So you are wanting this code:

bool rslt;
    Serial.println("Ready to send");
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );

to see if I am even getting into the "send" function, and if so, how far. Gotcha!

I'll run that test tonight, and try and get more info on the physical nRF24 module as well.

I am using a breakout board with the 3.3v regulator onboard for the nRF24 as well. I am powering the nRF24 breakout board with the 5v from the Nano. The lights come on the breakout board.

Thanks for all of your help!

vader7071:
I am using a breakout board with the 3.3v regulator onboard for the nRF24 as well.

Another recent Thread seemed to have a problem with one of those. I have never used one myself - I have made my own, or just used a pair of AA alkaline cells.

...R