Written by 2bndy5 in 2020
This is a simple example of using the RF24 class on a Raspberry Pi to transmit and respond with acknowledgment (ACK) transmissions. Notice that the auto-ack feature is enabled, but this example doesn't use automatic ACK payloads because automatic ACK payloads' data will always be outdated by 1 transmission. Instead, this example uses a call and response paradigm.
Remember to install the Python wrapper, then navigate to the "RF24/examples_linux" folder.
To run this example, enter
python3 manual_acknowledgements.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 1 nRF24L01 transceiver to another
3with manually transmitted (non-automatic) Acknowledgement (ACK) payloads.
4This example still uses ACK packets, but they have no payloads. Instead the
5acknowledging response is sent with `write()`. This tactic allows for more
6updated acknowledgement payload data, where actual ACK payloads' data are
7outdated by 1 transmission because they have to loaded before receiving a
10This example was written to be used on 2 devices acting as 'nodes'.
12See documentation at https://nRF24.github.io/RF24
16from RF24
import RF24, RF24_PA_LOW, RF24_DRIVER
29if RF24_DRIVER ==
"MRAA":
31elif RF24_DRIVER ==
"wiringPi":
35radio =
RF24(CE_PIN, CSN_PIN)
39 raise RuntimeError(
"radio hardware is not responding")
43address = [b
"1Node", b
"2Node"]
51 int(input(
"Which radio is this? Enter '0' or '1'. Defaults to '0' ")
or 0)
56radio.setPALevel(RF24_PA_LOW)
59radio.openWritingPipe(address[radio_number])
62radio.openReadingPipe(1, address[
not radio_number])
81 """Transmits a message and an incrementing integer every second, then
82 wait for a response for up to 200 ms.
89 buffer = b
"Hello \x00" + bytes(counter)
90 start_timer = time.monotonic_ns()
91 result = radio.write(buffer)
94 print(
"Transmission failed or timed out")
96 radio.startListening()
97 timout = time.monotonic() * 1000 + 200
99 while not radio.available()
and time.monotonic() * 1000 < timout:
101 radio.stopListening()
102 end_timer = time.monotonic_ns()
103 decoded = buffer[:6].decode(
"utf-8")
105 f
"Transmission successful. Sent: {decoded}{counter[0]}.",
108 has_payload, pipe_number = radio.available_pipe()
111 received = radio.read(radio.payloadSize)
113 counter[0] = received[7:8][0]
114 decoded = bytes(received[:6]).decode(
"utf-8")
116 f
"Received {radio.payloadSize} bytes",
117 f
"on pipe {pipe_number}: {decoded}{counter[0]}.",
118 f
"Round-trip delay: {(end_timer - start_timer) / 1000} us.",
121 print(
"No response received.")
123 print(failures,
"failures detected. Leaving TX role.")
126def slave(timeout: int = 6):
127 """Listen for any payloads and print the transaction
129 :param int timeout: The number of seconds to wait (with no transmission)
130 until exiting function.
132 radio.startListening()
134 start_timer = time.monotonic()
135 while (time.monotonic() - start_timer) < timeout:
137 has_payload, pipe_number = radio.available_pipe()
139 received = radio.read(radio.payloadSize)
142 counter[0] = received[7:8][0] + 1
if received[7:8][0] < 255
else 0
145 buffer = b
"World \x00" + bytes(counter)
146 radio.stopListening()
147 radio.writeFast(buffer)
149 result = radio.txStandBy(150)
151 radio.startListening()
153 decoded = bytes(received[:6]).decode(
"utf-8")
155 f
"Received {radio.payloadSize} bytes"
156 f
"on pipe {pipe_number}: {decoded}{received[7:8][0]}.",
161 decoded = buffer[:6].decode(
"utf-8")
162 print(f
"Sent: {decoded}{counter[0]}")
164 print(
"Response failed or timed out")
165 start_timer = time.monotonic()
167 print(
"Nothing received in", timeout,
"seconds. Leaving RX role")
169 radio.stopListening()
172def set_role() -> bool:
173 """Set the role using stdin stream. Timeout arg for slave() can be
174 specified using a space delimiter (e.g. 'R 10' calls `slave(10)`)
177 - True when role is complete & app should continue running.
178 - False when app should exit
182 "*** Enter 'R' for receiver role.\n"
183 "*** Enter 'T' for transmitter role.\n"
184 "*** Enter 'Q' to quit example.\n"
188 user_input = user_input.split()
189 if user_input[0].upper().startswith(
"R"):
190 if len(user_input) > 1:
191 slave(int(user_input[1]))
195 if user_input[0].upper().startswith(
"T"):
198 if user_input[0].upper().startswith(
"Q"):
201 print(user_input[0],
"is an unrecognized input. Please try again.")
205if __name__ ==
"__main__":
209 except KeyboardInterrupt:
210 print(
" Keyboard Interrupt detected. Powering down radio.")
213 print(
" Run slave() on receiver\n Run master() on transmitter")
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.