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
26if RF24_DRIVER ==
"MRAA":
28elif RF24_DRIVER ==
"wiringPi":
32radio =
RF24(CE_PIN, CSN_PIN)
36 raise RuntimeError(
"radio hardware is not responding")
40radio.setPALevel(RF24_PA_LOW)
46radio.payloadSize = struct.calcsize(
"ii")
55 b
"\xf1\xb6\xb5\xb4\xb3",
56 b
"\xcd\xb6\xb5\xb4\xb3",
57 b
"\xa3\xb6\xb5\xb4\xb3",
58 b
"\x0f\xb6\xb5\xb4\xb3",
59 b
"\x05\xb6\xb5\xb4\xb3",
65def master(node_number):
66 """start transmitting to the base station.
68 :param int node_number: the node's identifying index (from the
69 the `addresses` list). This is a required parameter
75 ((node_number * 3) % 12) + 3, 15
80 radio.openWritingPipe(addresses[node_number])
86 payload = struct.pack(
"<ii", node_number, counter)
87 start_timer = time.monotonic_ns()
88 report = radio.write(payload)
89 end_timer = time.monotonic_ns()
92 f
"Transmission of payloadID {counter} as node {node_number}",
97 f
"successful! Time to transmit = {(end_timer - start_timer) / 1000} us"
101 print(
"failed or timed out")
103 print(failures,
"failures detected. Leaving TX role.")
106def slave(timeout: int = 10):
107 """Use the radio as a base station for listening to all nodes
109 :param int timeout: The number of seconds to wait (with no transmission)
110 until exiting function.
113 for pipe_n, addr
in enumerate(addresses):
114 radio.openReadingPipe(pipe_n, addr)
115 radio.startListening()
116 start_timer = time.monotonic()
117 while time.monotonic() - start_timer < timeout:
118 has_payload, pipe_number = radio.available_pipe()
121 node_id, payload_id = struct.unpack(
"<ii", radio.read(radio.payloadSize))
124 f
"Received {radio.payloadSize} bytes",
125 f
"on pipe {pipe_number} from node {node_id}.",
126 f
"PayloadID: {payload_id}",
128 start_timer = time.monotonic()
130 print(
"Nothing received in", timeout,
"seconds. Leaving RX role")
131 radio.stopListening()
134def set_role() -> bool:
135 """Set the role using stdin stream. Timeout arg for slave() can be
136 specified using a space delimiter (e.g. 'R 10' calls `slave(10)`)
139 - True when role is complete & app should continue running.
140 - False when app should exit
144 "*** Enter 'R' for receiver role.\n"
145 "*** Enter a number in range [0, 5] to use a specific node ID for "
146 "transmitter role.\n"
147 "*** Enter 'Q' to quit example.\n"
151 user_input = user_input.split()
152 if user_input[0].upper().startswith(
"R"):
153 if len(user_input) > 1:
154 slave(int(user_input[1]))
158 if user_input[0].isdigit()
and 0 <= int(user_input[0]) <= 5:
159 master(int(user_input[0]))
161 if user_input[0].upper().startswith(
"Q"):
164 print(user_input[0],
"is an unrecognized input. Please try again.")
168if __name__ ==
"__main__":
172 except KeyboardInterrupt:
173 print(
" Keyboard Interrupt detected. Powering down radio.")
176 print(
" Run slave() on the receiver")
177 print(
" Run master(node_number) on a transmitter")
178 print(
" master()'s parameter, `node_number`, must be in range [0, 5]")
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.