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).
13from RF24
import RF24, RF24_PA_LOW
16parser = argparse.ArgumentParser(
17 description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
22 choices=(
"0",
"1",
"2",
"3",
"4",
"5",
"R",
"r"),
23 help=
"the identifying node ID number for the TX role. "
24 "Use 'R' or 'r' to specify the RX role",
36radio =
RF24(CE_PIN, CSN_PIN)
46 b
"\xF1\xB6\xB5\xB4\xB3",
47 b
"\xCD\xB6\xB5\xB4\xB3",
48 b
"\xA3\xB6\xB5\xB4\xB3",
49 b
"\x0F\xB6\xB5\xB4\xB3",
50 b
"\x05\xB6\xB5\xB4\xB3",
56def master(node_number):
57 """start transmitting to the base station.
59 :param int node_number: the node's identifying index (from the the `addresses` list). This is a required parameter
65 ((node_number * 3) % 12) + 3, 15
70 radio.openWritingPipe(addresses[node_number])
76 payload = struct.pack(
"<ii", node_number, counter)
77 start_timer = time.monotonic_ns()
78 report = radio.write(payload)
79 end_timer = time.monotonic_ns()
82 f
"Transmission of payloadID {counter} as node {node_number}",
87 f
"successful! Time to transmit = {(end_timer - start_timer) / 1000} us"
91 print(
"failed or timed out")
93 print(failures,
"failures detected. Leaving TX role.")
96def slave(timeout: int = 10):
97 """Use the radio as a base station for listening to all nodes
99 :param int timeout: The number of seconds to wait (with no transmission)
100 until exiting function.
103 for pipe_n, addr
in enumerate(addresses):
104 radio.openReadingPipe(pipe_n, addr)
105 radio.startListening()
106 start_timer = time.monotonic()
107 while time.monotonic() - start_timer < timeout:
108 has_payload, pipe_number = radio.available_pipe()
111 node_id, payload_id = struct.unpack(
"<ii", radio.read(radio.payloadSize))
114 f
"Received {radio.payloadSize} bytes",
115 f
"on pipe {pipe_number} from node {node_id}.",
116 f
"PayloadID: {payload_id}",
118 start_timer = time.monotonic()
120 print(
"Nothing received in", timeout,
"seconds. Leaving RX role")
121 radio.stopListening()
124def set_role() -> bool:
125 """Set the role using stdin stream. Timeout arg for slave() can be
126 specified using a space delimiter (e.g. 'R 10' calls `slave(10)`)
129 -
True when role
is complete & app should
continue running.
130 -
False when app should exit
134 "*** Enter 'R' for receiver role.\n"
135 "*** Enter a number in range [0, 5] to use a specific node ID for "
136 "transmitter role.\n"
137 "*** Enter 'Q' to quit example.\n"
141 user_input = user_input.split()
142 if user_input[0].upper().startswith(
"R"):
143 if len(user_input) > 1:
144 slave(int(user_input[1]))
148 if user_input[0].isdigit()
and 0 <= int(user_input[0]) <= 5:
149 master(int(user_input[0]))
151 if user_input[0].upper().startswith(
"Q"):
154 print(user_input[0],
"is an unrecognized input. Please try again.")
158if __name__ ==
"__main__":
160 args = parser.parse_args()
163 if not radio.begin():
164 raise RuntimeError(
"radio hardware is not responding")
170 radio.setPALevel(RF24_PA_LOW)
176 radio.payloadSize = struct.calcsize(
"ii")
183 if args.node
is None:
188 if args.node.isdigit():
189 master(int(args.node))
192 except KeyboardInterrupt:
193 print(
" Keyboard Interrupt detected. Powering down radio.")
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.