Written by 2bndy5 in 2020
This is a simple example of using the RF24 class on a Raspberry Pi for using 1 nRF24L01 to receive data from up to 6 other transceivers. This technique is called "multiceiver" in the datasheet.
Remember to install the Python wrapper, then navigate to the "RF24/examples_linux" folder.
To run this example, enter
python3 multiceiver_demo.py
and follow the prompts.
- Note
- this example requires python v3.7 or newer because it measures transmission time with
time.monotonic_ns()
.
2A simple example of sending data from as many as 6 nRF24L01 transceivers to
31 receiving transceiver. This technique is trademarked by
4Nordic Semiconductors as "MultiCeiver".
6This example was written to be used on up to 6 devices acting as TX nodes &
7only 1 device acting as the RX node (that's a maximum of 7 devices).
9See documentation at https://nRF24.github.io/RF24
14from RF24
import RF24, RF24_PA_LOW, RF24_DRIVER
25if RF24_DRIVER ==
"MRAA":
27elif RF24_DRIVER ==
"wiringPi":
31radio =
RF24(CE_PIN, CSN_PIN)
35 raise RuntimeError(
"radio hardware is not responding")
39radio.setPALevel(RF24_PA_LOW)
45radio.payloadSize = struct.calcsize(
"ii")
54 b
"\xf1\xb6\xb5\xb4\xb3",
55 b
"\xcd\xb6\xb5\xb4\xb3",
56 b
"\xa3\xb6\xb5\xb4\xb3",
57 b
"\x0f\xb6\xb5\xb4\xb3",
58 b
"\x05\xb6\xb5\xb4\xb3",
64def master(node_number):
65 """start transmitting to the base station.
67 :param int node_number: the node's identifying index (from the
68 the `addresses` list). This is a required parameter
74 ((node_number * 3) % 12) + 3, 15
79 radio.openWritingPipe(addresses[node_number])
85 payload = struct.pack(
"<ii", node_number, counter)
86 start_timer = time.monotonic_ns()
87 report = radio.write(payload)
88 end_timer = time.monotonic_ns()
91 f
"Transmission of payloadID {counter} as node {node_number}",
96 f
"successful! Time to transmit = {(end_timer - start_timer) / 1000} us"
100 print(
"failed or timed out")
102 print(failures,
"failures detected. Leaving TX role.")
105def slave(timeout: int = 10):
106 """Use the radio as a base station for listening to all nodes
108 :param int timeout: The number of seconds to wait (with no transmission)
109 until exiting function.
112 for pipe_n, addr
in enumerate(addresses):
113 radio.openReadingPipe(pipe_n, addr)
114 radio.startListening()
115 start_timer = time.monotonic()
116 while time.monotonic() - start_timer < timeout:
117 has_payload, pipe_number = radio.available_pipe()
120 node_id, payload_id = struct.unpack(
"<ii", radio.read(radio.payloadSize))
123 f
"Received {radio.payloadSize} bytes",
124 f
"on pipe {pipe_number} from node {node_id}.",
125 f
"PayloadID: {payload_id}",
127 start_timer = time.monotonic()
129 print(
"Nothing received in", timeout,
"seconds. Leaving RX role")
130 radio.stopListening()
133def set_role() -> bool:
134 """Set the role using stdin stream. Timeout arg for slave() can be
135 specified using a space delimiter (e.g. 'R 10' calls `slave(10)`)
138 - True when role is complete & app should continue running.
139 - False when app should exit
143 "*** Enter 'R' for receiver role.\n"
144 "*** Enter a number in range [0, 5] to use a specific node ID for "
145 "transmitter role.\n"
146 "*** Enter 'Q' to quit example.\n"
150 user_input = user_input.split()
151 if user_input[0].upper().startswith(
"R"):
152 if len(user_input) > 1:
153 slave(int(user_input[1]))
157 if user_input[0].isdigit()
and 0 <= int(user_input[0]) <= 5:
158 master(int(user_input[0]))
160 if user_input[0].upper().startswith(
"Q"):
163 print(user_input[0],
"is an unrecognized input. Please try again.")
167if __name__ ==
"__main__":
171 except KeyboardInterrupt:
172 print(
" Keyboard Interrupt detected. Powering down radio.")
175 print(
" Run slave() on the receiver")
176 print(
" Run master(node_number) on a transmitter")
177 print(
" master()'s parameter, `node_number`, must be in range [0, 5]")
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.