Optimized high speed nRF24L01+ driver class documentation v1.4.8
TMRh20 2020 - Optimized fork of the nRF24L01+ driver
Loading...
Searching...
No Matches
examples_linux/getting_started.py

Written by 2bndy5 in 2020

This is a simple example of using the RF24 class on a Raspberry Pi.

Remember to install the Python wrapper, then navigate to the "RF24/examples_linux" folder.
To run this example, enter

python3 getting_started.py

and follow the prompts.

Note
this example requires python v3.7 or newer because it measures transmission time with time.monotonic_ns().
1"""
2A simple example of sending data from 1 nRF24L01 transceiver to another.
3This example was written to be used on 2 devices acting as 'nodes'.
4
5See documentation at https://nRF24.github.io/RF24
6"""
7
8import time
9import struct
10from RF24 import RF24, RF24_PA_LOW, RF24_DRIVER
11
12print(__file__) # print example name
13
14
21CSN_PIN = 0 # GPIO8 aka CE0 on SPI bus 0: /dev/spidev0.0
22if RF24_DRIVER == "MRAA":
23 CE_PIN = 15 # for GPIO22
24elif RF24_DRIVER == "wiringPi":
25 CE_PIN = 3 # for GPIO22
26else:
27 CE_PIN = 22
28radio = RF24(CE_PIN, CSN_PIN)
29
30# initialize the nRF24L01 on the spi bus
31if not radio.begin():
32 raise RuntimeError("radio hardware is not responding")
33
34# For this example, we will use different addresses
35# An address need to be a buffer protocol object (bytearray)
36address = [b"1Node", b"2Node"]
37# It is very helpful to think of an address as a path instead of as
38# an identifying device destination
39
40
41# to use different addresses on a pair of radios, we need a variable to
42# uniquely identify which address this radio will use to transmit
43# 0 uses address[0] to transmit, 1 uses address[1] to transmit
44radio_number = bool(
45 int(input("Which radio is this? Enter '0' or '1'. Defaults to '0' ") or 0)
46)
47
48# set the Power Amplifier level to -12 dBm since this test example is
49# usually run with nRF24L01 transceivers in close proximity of each other
50radio.setPALevel(RF24_PA_LOW) # RF24_PA_MAX is default
51
52# set the TX address of the RX node into the TX pipe
53radio.openWritingPipe(address[radio_number]) # always uses pipe 0
54
55# set the RX address of the TX node into a RX pipe
56radio.openReadingPipe(1, address[not radio_number]) # using pipe 1
57
58# To save time during transmission, we'll set the payload size to be only
59# what we need. A float value occupies 4 bytes in memory using
60# struct.pack(); "f" means an unsigned float
61radio.payloadSize = struct.calcsize("f")
62
63# for debugging, we have 2 options that print a large block of details
64# (smaller) function that prints raw register values
65# radio.printDetails()
66# (larger) function that prints human readable data
67# radio.printPrettyDetails()
68
69# using the python keyword global is bad practice. Instead we'll use a 1 item
70# list to store our float number for the payloads sent/received
71payload = [0.0]
72
73
74def master():
75 """Transmits an incrementing float every second"""
76 radio.stopListening() # put radio in TX mode
77 failures = 0
78 while failures < 6:
79 # use struct.pack() to packet your data into the payload
80 # "<f" means a single little endian (4 byte) float value.
81 buffer = struct.pack("<f", payload[0])
82 start_timer = time.monotonic_ns() # start timer
83 result = radio.write(buffer)
84 end_timer = time.monotonic_ns() # end timer
85 if not result:
86 print("Transmission failed or timed out")
87 failures += 1
88 else:
89 print(
90 "Transmission successful! Time to Transmit:",
91 f"{(end_timer - start_timer) / 1000} us. Sent: {payload[0]}",
92 )
93 payload[0] += 0.01
94 time.sleep(1)
95 print(failures, "failures detected. Leaving TX role.")
96
97
98def slave(timeout=6):
99 """Listen for any payloads and print the transaction
100
101 :param int timeout: The number of seconds to wait (with no transmission)
102 until exiting function.
103 """
104 radio.startListening() # put radio in RX mode
105
106 start_timer = time.monotonic()
107 while (time.monotonic() - start_timer) < timeout:
108 has_payload, pipe_number = radio.available_pipe()
109 if has_payload:
110 # fetch 1 payload from RX FIFO
111 buffer = radio.read(radio.payloadSize)
112 # use struct.unpack() to convert the buffer into usable data
113 # expecting a little endian float, thus the format string "<f"
114 # buffer[:4] truncates padded 0s in case payloadSize was not set
115 payload[0] = struct.unpack("<f", buffer[:4])[0]
116 # print details about the received packet
117 print(
118 f"Received {radio.payloadSize} bytes",
119 f"on pipe {pipe_number}: {payload[0]}",
120 )
121 start_timer = time.monotonic() # reset the timeout timer
122
123 print("Nothing received in", timeout, "seconds. Leaving RX role")
124 # recommended behavior is to keep in TX mode while idle
125 radio.stopListening() # put the radio in TX mode
126
127
128def set_role() -> bool:
129 """Set the role using stdin stream. Timeout arg for slave() can be
130 specified using a space delimiter (e.g. 'R 10' calls `slave(10)`)
131
132 :return:
133 - True when role is complete & app should continue running.
134 - False when app should exit
135 """
136 user_input = (
137 input(
138 "*** Enter 'R' for receiver role.\n"
139 "*** Enter 'T' for transmitter role.\n"
140 "*** Enter 'Q' to quit example.\n"
141 )
142 or "?"
143 )
144 user_input = user_input.split()
145 if user_input[0].upper().startswith("R"):
146 if len(user_input) > 1:
147 slave(int(user_input[1]))
148 else:
149 slave()
150 return True
151 if user_input[0].upper().startswith("T"):
152 master()
153 return True
154 if user_input[0].upper().startswith("Q"):
155 radio.powerDown()
156 return False
157 print(user_input[0], "is an unrecognized input. Please try again.")
158 return set_role()
159
160
161if __name__ == "__main__":
162 try:
163 while set_role():
164 pass # continue example until 'Q' is entered
165 except KeyboardInterrupt:
166 print(" Keyboard Interrupt detected. Powering down radio.")
167 radio.powerDown()
168else:
169 print(" Run slave() on receiver\n Run master() on transmitter")
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.
Definition RF24.h:116