and follow the prompts.
2This example uses Acknowledgement (ACK) payloads attached to ACK packets to
3demonstrate how the nRF24L01's IRQ (Interrupt Request) pin can be
4configured to detect when data is received, or when data has transmitted
5successfully, or when data has failed to transmit.
7This example was written to be used on 2 devices acting as "nodes".
12import RPi.GPIO
as GPIO
13from RF24
import RF24, RF24_PA_LOW
16parser = argparse.ArgumentParser(
17 description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
24 help=
"the identifying radio number (or node ID number)",
31 help=
"'1' specifies the TX role. '0' specifies the RX role.",
43radio =
RF24(CE_PIN, CSN_PIN)
57tx_payloads = (b
"Ping ", b
"Pong ", b
"Radio", b
"1FAIL")
58ack_payloads = (b
"Yak ", b
"Back", b
" ACK")
61def interrupt_handler(channel):
62 """This function is called when IRQ pin is detected active LOW"""
63 print(
"IRQ pin", channel,
"went active LOW.")
64 tx_ds, tx_df, rx_dr = radio.whatHappened()
67 print(f
"\ttx_ds: {tx_ds}, tx_df: {tx_df}, rx_dr: {rx_dr}")
68 if pl_iterator[0] == 0:
69 print(
" 'data ready' event test", (
"passed" if rx_dr
else "failed"))
70 elif pl_iterator[0] == 1:
71 print(
" 'data sent' event test", (
"passed" if tx_ds
else "failed"))
72 elif pl_iterator[0] == 3:
73 print(
" 'data fail' event test", (
"passed" if tx_df
else "failed"))
78GPIO.setup(IRQ_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
79GPIO.add_event_detect(IRQ_PIN, GPIO.FALLING, callback=interrupt_handler)
86def _ping_n_wait(pl_iter):
87 """private function to ping RX node and wait for IRQ pin to be handled
89 :param int pl_iter: The index of the buffer in `tx_payloads` tuple to
90 send. This number
is also used to determine
if event test was
95 pl_iterator[0] = pl_iter
97 radio.startFastWrite(tx_payloads[pl_iter],
False)
101def print_rx_fifo(pl_size: int):
102 """Flush RX FIFO by printing all available payloads with 1 buffer
104 :param int pl_size: the expected size of each payload
106 if radio.rxFifoFull():
109 print(
"Complete RX FIFO:", radio.read(pl_size * 3).decode(
"utf-8"))
112 while radio.available():
113 buffer += radio.read(pl_size)
115 print(
"Complete RX FIFO:", buffer.decode(
"utf-8"))
119 """Transmits 4 times and reports results
121 1. successfully receive ACK payload first
122 2. successfully transmit on second
123 3. send a third payload to fill RX node's RX FIFO (supposedly making RX node unresponsive)
124 4. intentionally fail transmit on the fourth
126 radio.stopListening()
129 print(
"\nConfiguring IRQ pin to only ignore 'on data sent' event")
130 radio.maskIRQ(
True,
False,
False)
131 print(
" Pinging slave node for an ACK payload...", end=
" ")
135 print(
"\nConfiguring IRQ pin to only ignore 'on data ready' event")
136 radio.maskIRQ(
False,
False,
True)
137 print(
" Pinging slave node again... ", end=
" ")
141 print(
"\nSending one extra payload to fill RX FIFO on slave node.")
142 radio.maskIRQ(1, 1, 1)
143 if radio.write(tx_payloads[2]):
145 if radio.rxFifoFull():
146 print(
"RX node's FIFO is full; it is not listening any more")
149 "Transmission successful, but the RX node might still be listening."
153 print(
"Transmission failed or timed out. Continuing anyway.")
156 print(
"\nConfiguring IRQ pin to go active for all events.")
157 radio.maskIRQ(
False,
False,
False)
158 print(
" Sending a ping to inactive slave node...", end=
" ")
162 radio.stopListening()
165 print_rx_fifo(len(ack_payloads[0]))
168def slave(timeout: int = 6):
169 """Only listen for 3 payload from the master node
171 :param int timeout: The number of seconds to wait (with no transmission)
172 until exiting function.
176 radio.writeAckPayload(1, ack_payloads[0])
177 radio.writeAckPayload(1, ack_payloads[1])
178 radio.writeAckPayload(1, ack_payloads[2])
179 radio.startListening()
180 start_timer = time.monotonic()
181 while not radio.rxFifoFull()
and time.monotonic() - start_timer < timeout:
185 radio.stopListening()
186 print_rx_fifo(len(tx_payloads[0]))
189def set_role() -> bool:
190 """Set the role using stdin stream. Timeout arg for slave() can be
191 specified using a space delimiter (e.g. 'R 10' calls `slave(10)`)
194 -
True when role
is complete & app should
continue running.
195 -
False when app should exit
199 "*** Enter 'R' for receiver role.\n"
200 "*** Enter 'T' for transmitter role.\n"
201 "*** Enter 'Q' to quit example.\n"
205 user_input = user_input.split()
206 if user_input[0].upper().startswith(
"R"):
207 if len(user_input) > 1:
208 slave(int(user_input[1]))
212 if user_input[0].upper().startswith(
"T"):
215 if user_input[0].upper().startswith(
"Q"):
218 print(user_input[0],
"is an unrecognized input. Please try again.")
222if __name__ ==
"__main__":
224 args = parser.parse_args()
227 if not radio.begin():
228 raise RuntimeError(
"radio hardware is not responding")
232 address = [b
"1Node", b
"2Node"]
241 radio_number = args.node
242 if args.node
is None:
244 int(input(
"Which radio is this? Enter '0' or '1'. Defaults to '0' ")
or 0)
249 radio.setPALevel(RF24_PA_LOW)
252 radio.enableDynamicPayloads()
256 radio.enableAckPayload()
259 radio.openWritingPipe(address[radio_number])
262 radio.openReadingPipe(1, address[
not radio_number])
271 if args.role
is None:
280 except KeyboardInterrupt:
281 print(
" Keyboard Interrupt detected. Powering down radio.")
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.