1
\$\begingroup\$

I have never used the nRF24l01 before, and there is something I don’t fully understand. I’ve tried googling and searching the forums but haven’t found a satisfactory explanation.

My understanding is that, to use the nRF24l01, you select a channel and an address. Every nRF24l01 in your network must use the same channel, and must have a different address. So far, so good.

However, what I don’t understand is how I avoid conflicts with other nRF24l01 users. The range is considerable, and the device is popular.

Let’s suppose I set up a pair of nRF24l01 on a specific channel, and have one of them send a message to the other once a day.

Some weeks later, my neighbour (or someone a kilometre away!) gets some nRF24l01 and configures them to use the same channel and addresses. He doesn’t notice my presence, because my device only sends a message once a day, when he’s not looking.

Surely, then, my project would receive his messages and get confused? And he will experience similar problems due to my messages.

So my question is, how to prevent this problem? How to ensure that rogue messages sent from other users do not trigger my receiver and cause unwanted actions or taint the data I am collecting?

\$\endgroup\$

4 Answers 4

2
\$\begingroup\$

So my question is, how to prevent this problem? How to ensure that rogue messages sent from other users do not trigger my receiver and cause unwanted actions or taint the data I am collecting?

You identified the problem.

Luckily, depending on whether you use 3, 4 or 5 byte long addresses, there's 23·8 = 16.8 million, 24·8 = 4.29 billion, or 25·8 = 11.0 trillion addresses. So, if you picked your addresses equally likely from all possible addresses, the probability of an address conflict happening unintentionally is really damn near to 0: It's the birthday problem, i.e. when you have \$2^k\$ possible addresses, all addresses are equally likely chosen to be used by a device, and \$n\$ devices in your area, then the probability of all randomly chosen address being distinct is

$$\begin{align} P_{\text{no addr conflict}} &= \frac{2^k!}{{2^k}^n\cdot(2^k-n)!}\\ &=\frac{(2^k-n)\cdot(2^k-(n-1))\cdot(2^k-(n-2))\cdot\ldots\cdot (2^k-0) }{{2^k}^n}\\ &= \underbrace{\frac{2^k-n}{2^k}}_{\text{very close to }1} \cdot\underbrace{\frac{2^k-(n-1)}{2^k}}_{\text{ very very close to }1} \cdot\underbrace{\frac{2^k-(n-2)}{2^k}}_{\text{ damn near }1}\cdots \underbrace{\frac{2^k-(n-n)}{2^k}}_{=1}\\ &\approx 1\\ &\forall n \ll 2^k , \end{align}$$

which, for realistic values of \$n\$, and \$k=40\$, is really really practically "1". This is a very practical "practical": in fact, if you want to, say, press the probability of this happen to below 1 in 10000, you'd only need about 15000 active devices on the same channel to break that probabilistic bound. However, considering something else: at the point where any receiver can "hear" 15000 other devices, chances are the system you're trying to build suffers from something else: on-the-air contention, where simultaneously sent packets collide with each other¹.

That's why I have my doubts with your initial assertion that you can receive these devices for kilometers: it would be stupid for almost all users of them to operate them at maximum transmit power. Generally, if you want to build a many-devices low power wide area network (LPWAN), then these aren't the kind of devices you'll ever want to work with – they are meant for a computer mouse to communicate with a computer, not for 10000 street lights to be controlled by a city, or for 4000 electric scooters to be controlled by a venture-capital fueled loss leader company.

This means you either "production-side" program the addresses randomly chosen with a good random number generator (not UNIX rand, [but almost anything else]), or your devices have their own implementation of the random number generation (modern microcontrollers tend to even have built-in true random generators!), and a "pairing" address. That pairing address would be static, but your users would need to manually initiate the pairing process by pressing a button or something, then there would only be a short time window in which someone might interfere, and if you can, you'd usually set the sensitivity of your receiver low and reduce the transmit power, so that this really only works with closely co-located devices.

Now, that doesn't inhibit intentional meddling by someone else observing your packets and then "squatting" your address. There's no help against that but to authenticate your packets; an HMAC is the usual way to go about that.


¹ It's a common method to model this collision probability very similar to a address collision probability: say the average burst is 100 bit long, and you're using the 1 Mbps mode, then the transmitter is 100 µs active on air. Assuming every transmitter needs to send a packet every hour, we can "chunk up" this hour (= 3600s) into 100 µs slots, of which every burst occupies (because it's very unlikely that a packet "aligns" perfectly with the slot), thus effectively halving the available "slot space" from 3.6·10⁹ slots to 1.8·10⁹ slots. Now, as you'll notice, 1.8·10⁹ is already much less than 232 or 240; so, address collision is less of a concern than transmit collision. And hence, yeah, for all practical purposes, 32 bit addresses solve that for systems with this 1µs/3600s duty cycle, because it's much less likely that two transmitters collide on addresses than on transmit time, and when it's much more likely that they collide on transmit time, you need to care about that, because re-transmission can have cascading effects, bringing this slotted ALOHA with retransmissions system to its knees long before address collisions become likely.

\$\endgroup\$
3
  • \$\begingroup\$ So, the important takeaways here seem to be (1) don't pick addresses sequentially like I would otherwise have done; (2) it's possible to vary the transmission strength; and (3) if someone else transmits when I do, the packets will likely corrupt each other even if the addresses are different. Does that about sum it up? \$\endgroup\$ Commented Jul 15 at 12:02
  • \$\begingroup\$ I am concerned about (3). How serious is it, and what can be done about it? If my transmitter is closer to my receiver than others, will my packet "win"? I know I could just send the message again on failure, but sometimes that's not feasible. Suppose I made a doorbell using these modules. I've seen tutorials where people have done just that. But the receiver has to respond immediately when the bell is pressed. Sending the data multiple times over a period of time wouldn't work here: The person will give up and leave. So how to avoid missing messages due to interference from other users? \$\endgroup\$ Commented Jul 15 at 12:05
  • \$\begingroup\$ Also, is it even possible for the transmitter to know that the sending failed? I don't see how it can be. \$\endgroup\$ Commented Jul 15 at 12:07
0
\$\begingroup\$

Conceptually, you do this by validating the data you receive and not trusting the "network". There are many ways to do this technically, including things like magic identifiers at specific offsets into the data and uncommon checksum mechanisms. Look into how binary files are stored on a disk for some examples(they usually have a 4 byte prefix at the beginning of the file which can indicate the type of binary file.)

\$\endgroup\$
1
  • \$\begingroup\$ that still leads to other devices sending ACKs for packets destined for your device. You need to solve this on MAC layer. Luckily, it's already solved by the MAC layer's large address space. \$\endgroup\$ Commented Jul 14 at 14:53
0
\$\begingroup\$

How to ensure that rogue messages sent from other users do not trigger my receiver and cause unwanted actions or taint the data I am collecting?

You have to design your payload data in such a way as to statistically make a transmission from a different system on the same channel appear nonsensical. It has nothing to do with the nRF24l01; everyone transmitting data on a common radio channel has to ensure that false transmissions are clearly distinguishable from your own transmission. Of course, it's a statistical problem and your payload must be uniquely distinguishable as far as that is practicable.

The way you distinguish a valid payload from an invalid payload is with an MCU so, use tricks like CRCs, double transmissions, plenty of redundancy etc..

\$\endgroup\$
2
  • \$\begingroup\$ @MarcusMüller I never used the word authenticity so, what are you trying to say? Are you saying my answer is wrong in some way. I never used the word integrity either so, what point are you trying to make here? I have no idea what salted hashes are so, maybe you meant this comment for someone else? \$\endgroup\$ Commented Jul 14 at 15:37
  • 1
    \$\begingroup\$ nope, actually for you :) What you're saying is that you need to identify "false" transmissions. True! But in the context of the question, "false" doesn't mean "without flipped bits or missing parts" (integrity), it means "actually for the receiver that you are" (authenticity). A CRC in itself does nothing to tell you that you are the intended receiver: all it can ensure is that the packet you might have erroneously gotten is intact. (A salted hash is simply a (nicely-behaving) checksum over the message, but with a secret being prepended to the message) \$\endgroup\$ Commented Jul 14 at 15:42
0
\$\begingroup\$

Your chip will receive all valid packects on that channel and that ID. The radio chip cannot know what packets are transmitted by your system in order to receive only packets from your system.

That info needs to be in the data you send so you know your receiver MCU must act on it.

For example, add a custom CRC calculation to your data packet. Only send data and CRC, but initialize the CRC to some specific value, use some sepecific final XOR, or calculate the CRC from data by prefixing and/or postfixing it with some constant data.

Some other systems also use the CRC as an indication or ID which subsystems on same bus can communicate with each other.

However the data pipes already have a 5-byte address that must be unique, which can be used for identifying purposes. Just generate an address and use it on transmitter and receiver.

\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.