Connecting 5+ NRF24 to multiple Arduino's

Hello,

I've been succesfully working with 2 NRF24 modules that can both receive and send data to each other.

Now I vaguely remind that I read somewhere that the max. NRF24 modules is 6 (to send & receive data to each other) is this true?

I've seen the long post from Robin2 about those modules but I didn't find anything with more than 2 NRF24, and when I look up on the forums I only see things that I don't recognise. (likes pipe names with 0xA1011B, why not use 'AAAAA', can someone explain?).

Alright so to keep it a bit more simple, I decided to have 1 master that receives ALL the data from the other 5 modules, then it reads out the message (decided to make this always 10 char long, to keep it even more simple), and then it passes the data to the next NRF24. So this way all the 5 NRF24 bi-directional communicate with the master one. And not all of them together, it always goes to the master! And the master passes it to the next one.

In the code it goes likes this:

  • Goes into read mode.
  • Read any data that comes in (not that much, probably only 1 message per 50 seconds).
  • Goes into write mode.
  • After it received something, it does something with it and passes it to the one it's meant for.

Now I'm stuck at multiple parts in coding this.
I now have this in the code as my addresses:

const byte NRF_ADRES[][6] = {"UNIT1", "UNIT2"};

And then in the setup:

  radio.begin();
  radio.setPALevel(RF24_PA_MIN);
  radio.setDataRate(RF24_250KBPS);
  radio.openWritingPipe(NRF_ADRES[1]);
  radio.openReadingPipe(1, NRF_ADRES[0]);
  radio.startListening();

So somehwere in the radio.openWriting and Reading I have to ADD another address (don't know how), OR I have to define in the code each time I want to send out data to a specific NRF24 the pipe, (as shown in the setup).
But I do not want it to send data to all 5 units, only to 1 of them. But I do want it to read data from all of them.

Can anyone help me with this?

Thanks in advance!

akatchi:
I've seen the long post from Robin2 about those modules but I didn't find anything with more than 2 NRF24,

In my Simple nRF24L01+ Tutorial Reply #17 illustrates how you can use two slaves with one master. That concept can be extended to a large number of slaves without needing to use any extra pipes.

No matter what arrangement you have if two (or more) nRF24s transmit on the same channel at the same time both (all) messages will be garbled.

You mention using the master to send on data to another slave. Before making any comments about that I would appreciate it if you could provide a full description of the project you want to implement.

...R

Robin2:
In my Simple nRF24L01+ Tutorial Reply #17 illustrates how you can use two slaves with one master. That concept can be extended to a large number of slaves without needing to use any extra pipes.

Ah thanks will have a look at that now!

No matter what arrangement you have if two (or more) nRF24s transmit on the same channel at the same time both (all) messages will be garbled.

They won't transmit data on the same time for almost 99% of the cases!

You mention using the master to send on data to another slave. Before making any comments about that I would appreciate it if you could provide a full description of the project you want to implement.

Yes basically all the 5 'slaves' have different sensors and like mini-games. Once you finished one it sends out a message to the master so it knows you have completed that one, and the master can 'unlock' something, but it also needs to give the information to another slave so that slave will also unlock something new.
For example you complete a puzzle on Slave 1, Slave 1 sends the message to the master, the master reads it and knows for which slave it's meant, and then it sends it to Slave 2 so slave 2 can unlock new things.

Alright Robin, so as I thought I have to call this one

radio.openWritingPipe(slaveAddress[n]);

to select the slave I want to send data too, so I don't initialize them in my setup, but I just call them everytime to the correct slave I want to send data too.

I can't find an answer to the radio.openReadingPipe tho..
How does that work, reading multiple NRF24's (at the same time)?

Because in the example from #17 from your tutorial, you never declared openReadingPipe, but you are reading data, how?

akatchi:
I can't find an answer to the radio.openReadingPipe tho..

Because it is using the ackPayload technique there is no need to explicitly open a reading pipe - it all happens automatically. It makes life very much simpler.

Study the second example in my tutorial before extending the idea to multiple slaves.

...R

Robin2:
Because it is using the ackPayload technique there is no need to explicitly open a reading pipe - it all happens automatically. It makes life very much simpler.

Study the second example in my tutorial before extending the idea to multiple slaves.

...R

Alright this sounds really great, will read that now!
So let me get this straight, in case I misunderstood something.

For the master:

  • Using ackPayload to read automatically the 5 slaves in case they send data.
  • To send data to a slave, select the slave each time first with openWritingPipe(slaveAdress[x]); and then send out the data.

For the slaves:

  • Also use ackPayload to read data from the master(?) (Just thinking, this will also read the data that the master is sending out, just ignore this data I think?)
  • Only 1 writing pipe needed, will be declared in the setup.

Just another question: I can sends 32 bytes or less using ackPayload, is a 10 char string more or less than 32 bytes? I'm really bad with that, I think it's just 10 bytes? Am I wrong?

Thanks so far Robin!

akatchi:
For the slaves:

  • Also use ackPayload to read data from the master(?)

No. The slaves are always listening.

Immediately after it receives a message the slave should update the ackPayload buffer. Then the next time the master sends a message whatever is in the ackPayload buffer is automatically sent to the master. In a sense the ackPayload data is always one step behind - but if the master polls the slaves regularly that won't be noticeable.

...R

Robin2:
No. The slaves are always listening.

Immediately after it receives a message the slave should update the ackPayload buffer. Then the next time the master sends a message whatever is in the ackPayload buffer is automatically sent to the master. In a sense the ackPayload data is always one step behind - but if the master polls the slaves regularly that won't be noticeable.

...R

I do not really understand it after reading it multiple times...
What do you mean by 1 step behind?

Also I do want the slaves to send out messages so the master can pass them to the next slave...

akatchi:
What do you mean by 1 step behind?

When the master sends a message to the slave it receives back data that the slave had put into the ackPayload buffer before the master sent the message.

Also I do want the slaves to send out messages so the master can pass them to the next slave...

That is the data that the slave should put into the ackPayload buffer so that it gets passed to the master

I suspect you have not spent much time trying out my second example and getting to understand it thoroughly

...R

Robin2:
I suspect you have not spent much time trying out my second example and getting to understand it thoroughly

I'm trying but it's pretty difficult for me.

Okey so it says

The idea is that the slave puts data in the ackPayload buffer BEFORE it receives a message from the master

But I want the slave to send data FIRST to the master, and not the master to the slave.
So Slave X1 --> Master --> Slave X2

For example the ackPayoad cannot take account of the data received in the message for which it is the acknowledgment.

Does this mean it cannot read out the data message? Or..?

Ok.. so after a while reading your codes and post I think I now understand it.
So the master sends out data to the slave, and only then it takes like that ackPayload pre-made from the slave, so the slave doesn't send it by itself, but the master reads out the message once the master itself sent a message...

But then I have a problem because I want the slave to send data first to the master.

I think you are making it too complicated.

Imagine you know the postman will be calling at your house and you need to send a letter to John. (Pretend you live a long way from the post box). So you write the letter, put it in the envelope, seal it and attach a stamp and leave it on the hall table. When the postman comes you give him the letter and he gives you another letter.

Suppose the letter that the postman brought happens to be from John. Obviously the letter that you gave the postman cannot have included anything in response to John's letter to you - because you had not received the letter when you sealed your envelope. If you need to respond to a question from John you will write another letter and give it to the postman the next time he calls.

Translating that to the nRF24, the master sending a message to the slave is playing the part of the postman. And rather than calling once per day, the nRF24 can call several times per second.

Does that help?

...R

Robin2:
I think you are making it too complicated.

Imagine you know the postman will be calling at your house and you need to send a letter to John. (Pretend you live a long way from the post box). So you write the letter, put it in the envelope, seal it and attach a stamp and leave it on the hall table. When the postman comes you give him the letter and he gives you another letter.

Suppose the letter that the postman brought happens to be from John. Obviously the letter that you gave the postman cannot have included anything in response to John's letter to you - because you had not received the letter when you sealed your envelope. If you need to respond to a question from John you will write another letter and give it to the postman the next time he calls.

Translating that to the nRF24, the master sending a message to the slave is playing the part of the postman. And rather than calling once per day, the nRF24 can call several times per second.

Does that help?

...R

Thanks Robin! Exactly what I thought (only after reading multiple times haha).

So in my case it's not possible to use this method, why? I'll explain:
Because the master won't be sending out the messages first, to check if the slaves have unlocked something, so that means that the postman doesn't come at my house until John has written me a letter, and John doesn't write me a letter as long as I haven't send him one... so the postman never comes and the letter will never be send nor arrive!

So that means I have to use your second code example that stopListening --> Sends out the message --> Startslistening again. And this is where my question started.

So now I have an answer on WRITING out messages to multiple slaves, I just have to call
openWritingPipe(slaveAdress[x]); each time!

But for the openReadingPipe in the setup and all the pipes, I do not have an answer!
Is the radio.openReadingPipe(1, masterAddress); 1 here for the amount of readingPipes? Do I just have to make that like 5 and add 5 adresses?

I really appreciate your effort and time in helping me :).

akatchi:
Because the master won't be sending out the messages first,

Why not?

After 10 messages have been sent and replies have been received who cares who sent the first one?

It may not be your natural way of thinking about the problem but putting the master in charge of communications makes life very much easier. Just get the the master to call each of the slaves in turn perhaps 5 times per second. Most of the time the slave will respond by saying it has NOT unlocked anything.

...R

Robin2:
Why not?

After 10 messages have been sent and replies have been received who cares who sent the first one?

It may not be your natural way of thinking about the problem but putting the master in charge of communications makes life very much easier. Just get the the master to call each of the slaves in turn perhaps 5 times per second. Most of the time the slave will respond by saying it has NOT unlocked anything.

...R

Hmh yes that's an option but it means I will have to implement on all 5 systems the 'blink without delay' method. The master has to run through a lot of cycles with some small delays, so I think that sending out a message each second to each slave is actually to much work...

I think it's just easier for each slave to just send a message to the master when something is unlocked, so the master is just always listening, and then it goes into write mode for a few milli secs and back to read (this way it's almost impossible to miss any incoming message and reading a message is also very easy this way), so that way everything is always waiting for new messages. And the master is always listening, while the slaves only have to listen at a certain time (so that way I can just work with delays etc).
So that would work right? Just calling the write line each time, but still don't know how to get the readingPipes. Or is this too difficult?

Or something else? From what I know now, this looks easier to me.

akatchi:
Hmh yes that's an option but it means I will have to implement on all 5 systems the 'blink without delay' method. The master has to run through a lot of cycles with some small delays, so I think that sending out a message each second to each slave is actually to much work...

I don't see a need for timing on any but the master.
Who cares how much work the master is doing? It will be doing 16 million instructions per second all the time - you might as well use some of the for your project

I think it's just easier for each slave to just send a message to the master when something is unlocked, so the master is just always listening, and then it goes into write mode for a few milli secs and back to read (this way it's almost impossible to miss any incoming message and reading a message is also very easy this way), so that way everything is always waiting for new messages. And the master is always listening, while the slaves only have to listen at a certain time (so that way I can just work with delays etc).

You are free to do it any way you want. I suspect when you actually implement this scheme with more than one slave it won't be quite as simple as you think. How will you deal with the situation where 2 slaves talk at the same time? Or when a slave talks while the master is talking?

So that would work right? Just calling the write line each time, but still don't know how to get the readingPipes. Or is this too difficult? .

You don't need multiple pipes. Look at my 3rd example if you really want separate listening and talking.

...R

Robin2:
You are free to do it any way you want. I suspect when you actually implement this scheme with more than one slave it won't be quite as simple as you think. How will you deal with the situation where 2 slaves talk at the same time? Or when a slave talks while the master is talking?

Yes well that might indeed be a problem, but 99% it won't be a problem in my case, when you unlock something on one of the 5 slaves you have to be there and 'play' on it. So when you're with max. 2 people it's almost impossible to unlock something at the EXACT same time. So I guess messages will only be send once per few minuts maybe, maybe even less!

And also this way everything is always reading (until it receives something) and will immediately receive & deal with the message, so that's why I think I'll use this one!

You don't need multiple pipes. Look at my 3rd example if you really want separate listening and talking.

Ehm yes I have seen that example but it's only with 1 slave and I see 2 adresses, so I thought I need for each slave an adress? Or..? Because your example with multiple slaves is using the ackPayload method.

If your slaves are sending messages to the master then they can all send to the same address and the master can listen for that address.

For the master to reply separately to each slave it will need to know the address of each slave. That part of it will be much the same as the way the master in my ackPayload example sends to multiple slaves.

...R

Robin2:
If your slaves are sending messages to the master then they can all send to the same address and the master can listen for that address.

For the master to reply separately to each slave it will need to know the address of each slave. That part of it will be much the same as the way the master in my ackPayload example sends to multiple slaves.

...R

Yes yes I know this, but I mean for the master, how do I get the master reading all the slaves?

akatchi:
Yes yes I know this, but I mean for the master, how do I get the master reading all the slaves?

I really don't understand what it is that you don't understand.

In the concept in my mind the master will normally be listening on a specific address. A slave (any slave) will send a message for that address and the master will receive it. I assume you will have included in the message a byte that identifies the slave that has sent the message so that the master can figure out what do to next.

If that does not answer your question then write down as a series of steps (one on each line) the sequence of messages that you want to happen.

...R

Robin2:
I really don't understand what it is that you don't understand.

In the concept in my mind the master will normally be listening on a specific address. A slave (any slave)

Yes this is exactly what I mean! It will be reading an address, so my question is how do I get it reading all the slaves? Can it read all the slaves at the same time? Or only 1 slave by 1 slave?

If it can read multiple at the same time, how do I code that in my setup?

And else if it read 1 slave by 1 slave, do I have to call 'openReadingPipe' each time on every slave?