nRF24 / RF24Network

OSI Layer 3 Networking for nRF24L01(+) and nRF52x on Arduino and Raspberry Pi
https://nrf24.github.io/RF24Network/
GNU General Public License v2.0
353 stars 163 forks source link

Connect to more than 5 devices #206

Closed luke2023 closed 1 year ago

luke2023 commented 1 year ago

Hello ,thank you for your library!I found this tutorial very helpful about your library https://howtomechatronics.com/tutorials/arduino/how-to-build-an-arduino-wireless-network-with-multiple-nrf24l01-modules/

In the intro is says it is limited to 5 devices each module, but I don’t see devices limitation on your examples. If the limitation is correct ,how do I modify the code to make a single device connect to more than 5 devices? Because I have many devices in a small area and they might be unstable if I use so many levels (if the battery is out or something).

Thank you so much! Luke lin

TMRh20 commented 1 year ago

The radios are designed with a limited number of 'pipes' that can be assigned addresses. Typically, if you want to have more than 5 devices connected to a single device, you need to create a network with intermediate nodes passing traffic to more distant nodes, or you can disable Auto-Ack and have all of the devices using the same address and use multicast. These are the two most common scenarios.

2bndy5 commented 1 year ago

It is a hardware limitation, not a software limitation.

luke2023 commented 1 year ago

@TMRh20 Thank you for your reply, do you mean if I use the same address every of my device will get the message from the master? Thank you so much !

(My possible solution: many two way communication https://www.hackster.io/lightthedreams/nrf24l01-for-communication-1-way-and-2-way-80e65c)

Luke Lin

2bndy5 commented 1 year ago

Please don't use the RF24 radio object directly when using RF24Network library! It will break the network object's behavior if you manually set the pipe addresses yourself, especially if you don't know what exactly you're doing.

TMRh20 is referring to RF24Network::multicast() which is listed in the docs as an advanced function because it requires a basic understanding of network topology (see here and here)

2bndy5 commented 1 year ago

It should be noted that network addresses (AKA "logical addresses") are different from the "physical addresses" used for the radios' pipes.

luke2023 commented 1 year ago

@2bndy5 thank you so much for your answer ! I will share my project on github when I am done ! (making a low cost IOT standard for automation )

Luke lin

2bndy5 commented 1 year ago

or you can disable Auto-Ack and have all of the devices using the same address and use multicast.

example pseudo code:

const uint16_t siblings = 01; // used for all devices except master
const uint16_t master_node = 00;

network.begin(siblings); // pass `master_node` on the network master device 
radio.setAutoAck(false); // not usually recommended

// ...

// send to all siblings from master node
network.multicast(header, message, sizeof(message), /*level*/ 1);
// 1 is the network level for devices using the logical address `01`-`05`
TMRh20 commented 1 year ago

I guess I was thinking about using the RF24 layer when I made the comment about disabling auto-ack and using the same address. Typically with RF24Network, you can also just call network.multicastLevel(1) on each device while retaining normal functionality and having a unique id for each device. Both methods will work I guess.

2bndy5 commented 1 year ago

Yeah, that's a much better idea that should retain normal network behavior. Here's an updated example pseudo code:

network.begin(thisNode); // pass logical address specific to the device
network.multicastLevel(1); // for all devices except master

// ...

// send to all siblings from master node
network.multicast(header, message, sizeof(message), /*level*/ 1);
2bndy5 commented 1 year ago

Disabling AutoAck with the radio object isn't guaranteed to persist after a normal network.write(). Furthermore, calling radio.setAutoAck(false) before network.write() could instigate data loss because network-acks is disabled as well.

luke2023 commented 1 year ago

@2bndy5 thank you for the replay! If I can remain each unique id for each device(like TMRh20 recommended) ,can 011 get the message with network.multicast( ,, /*level*/ 1); while 01 has dead?

Or I should set every device to 01 except master? Thank you!

Luke Lin

TMRh20 commented 1 year ago

If I can remain each unique id for each device(like TMRh20 recommended) ,can 011 get the message with network.multicast( ,, /level/ 1); while 01 has dead?

Yes, as long as you call network.multicastLevel(1); on each device except master. Master can be level 0.

Or I should set every device to 01 except master?

You should set the devices as normal, each with a unique address. Then call network.multicast(header, message, sizeof(message), /*level*/ 1); when sending from master. Nodes sending to master can send to level 0.

luke2023 commented 1 year ago

@TMRh20 Thank you, if I want to broadcast to all the devices, should I use For (int i =0 ;i<5;i++){network.multicast( ,, /*level*/ i);}? Thank you!

2bndy5 commented 1 year ago

Yes, if you want to use the default multicast levels that are calculated when you pass the logical address to network.begin().

If you set each device to use the same multicast level with network.multicastLevel(x), then you only need to call network.multicast(..., /*level*/ x) once.

luke2023 commented 1 year ago

@2bndy5 Thank you, I understand now!