I want to connect a Raspberry Pi to a handheld ARM MCU-based device which contains a display and some buttons to show information from the Pi and transmit commands. I want to use nrf24l01+ 2.4GHz transceivers for that.

I'm pondering with how to setup the communications link and especially whether or not to use Enhanced Shock Burst (ESB). ESB is very practical since it supports auto-ack and hence could relieve me of manual ack-management which is a hassle especially on the MCU-based device. However, from how much I have understood from the datasheets, ESB requires one device to be a primary receiver and one device to be a primary transmitter and only the latter initiates a new transmission, even though the former can transmit data in it's reponse. In my case, this is problematic because both devices receive external events that trigger the need for a data transmission.

I've been reading around and there is basically three possible solutions to this problem:

  1. Configure one device as PTX and one as PRX and have the PTX send empty messages to give the PRX a chance to send it's data in a response packet. This seems to be done by some projects. I see the downside of continuously having traffic on the air which is bad for battery powered devices. Furthermore, the PRX still needs some buffer to store the messages until a transmission comes in and the message can be sent in the acknowledgement.

  2. Configure both devices as PRX. If one device needs to transmit a message it switches to PTX role and transmits the message. The advantage is that there is no continuous traffic on the air and both devices can transmit the messages as needed. However, I didn't find that this is being done anywhere. So I wonder if this is possible or if there are other caveats with this solution?

  3. Ditch Enhanced Shock Burst and make an own protocol. The least favored solution as it involves more work and puts more load on the controller. The automatic retransmit feature sounds very good and it would be a shame to put this potential to waste.

So I wonder if anyone had this problem already and how you solved it. I would especially like to know if there are problems with possibility two.

  • \$\begingroup\$ how about using wifi and e.g. an ESP8266 chip instead? \$\endgroup\$ Nov 26, 2015 at 7:04

2 Answers 2


The second option is actually very common. Essentially, the PRX and PTX can be on a per-transmission basis. Both of them should be in rx mode most of the time, and when you need to transmit something you would first look at the status bit which tells you whether or not there is a signal present on your channel. If there is not, you set the send address and set your ack address and fire away. If there is, go back to rx mode and have some timeout period.

Your first option seems like your describing a beaconing network protocol. Like you observed, this has the downside of continuous traffic and more power usage. However, it is really the only way you can guarantee communication if anything is time sensitive.


Your first option allows the master to control access to the airwaves - slaves will only transmit when directed to do so by the master. This can be good in high usage situations to avoid collisions, but it requires the slaves remain powered on at least whenever they have something waiting to send to the master, and it requires the master to poll "often enough".

(I'm assuming that by "response packet" you probably mean an ACK packet with payload, tho the same dynamics described above can be implemented if the slave manually switches briefly to PTX mode to send the response packet shortly after being requested by Master).

For some sensor nets where transmissions are less common, it's useful to use something more like your second option. Listen-before-send is not 100% reliable for several reasons, so there may be collisions, but with low traffic those can be uncommon enough to be acceptable, and sometimes sensor readings are not critical (if you send temperature every 5 minutes, it's usually not critical to miss a few updates).

So the main options break down into "master timed" and "asynchronous transmit" options (your "own protocol" third option would have to decide upon one of these as well). And each has it's niche. In a design where the master is sending out a lot of data (controlling Christmas lights), I use the former and let the master poll for data from the slaves at it's convenience. In a sensor network, I'm thinking to use the second dynamics, largely to allow the sensor slave nodes to sleep most of the time.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.