Skip to content

Commit 6485df1

Browse files
authored
Merge pull request #42 from jerryneedell/jerryn_ack
Implement "reliable Datagram mode"
2 parents 8e2237d + b1c287b commit 6485df1

10 files changed

+674
-62
lines changed

adafruit_rfm9x.py

Lines changed: 206 additions & 60 deletions
Large diffs are not rendered by default.

examples/rfm9x_header.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Example to display raw packets including header
2+
# Author: Jerry Needell
3+
#
4+
import board
5+
import busio
6+
import digitalio
7+
import adafruit_rfm9x
8+
9+
# Define radio parameters.
10+
RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your
11+
# module! Can be a value like 915.0, 433.0, etc.
12+
13+
# Define pins connected to the chip.
14+
CS = digitalio.DigitalInOut(board.CE1)
15+
RESET = digitalio.DigitalInOut(board.D25)
16+
17+
# Initialize SPI bus.
18+
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
19+
20+
# Initialze RFM radio
21+
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, RADIO_FREQ_MHZ)
22+
23+
# Wait to receive packets.
24+
print("Waiting for packets...")
25+
# initialize flag and timer
26+
while True:
27+
# Look for a new packet: only accept if addresses to my_node
28+
packet = rfm9x.receive(with_header=True)
29+
# If no packet was received during the timeout then None is returned.
30+
if packet is not None:
31+
# Received a packet!
32+
# Print out the raw bytes of the packet:
33+
print("Received (raw header):", [hex(x) for x in packet[0:4]])
34+
print("Received (raw payload): {0}".format(packet[4:]))
35+
print("RSSI: {0}".format(rfm9x.last_rssi))
36+
# send reading after any packet received

examples/rfm9x_node1.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Example to send a packet periodically between addressed nodes
2+
# Author: Jerry Needell
3+
#
4+
import time
5+
import board
6+
import busio
7+
import digitalio
8+
import adafruit_rfm9x
9+
10+
11+
# set the time interval (seconds) for sending packets
12+
transmit_interval = 10
13+
14+
# Define radio parameters.
15+
RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your
16+
# module! Can be a value like 915.0, 433.0, etc.
17+
18+
# Define pins connected to the chip.
19+
CS = digitalio.DigitalInOut(board.CE1)
20+
RESET = digitalio.DigitalInOut(board.D25)
21+
22+
# Initialize SPI bus.
23+
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
24+
# Initialze RFM radio
25+
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, RADIO_FREQ_MHZ)
26+
27+
# enable CRC checking
28+
rfm9x.enable_crc = True
29+
# set node addresses
30+
rfm9x.node = 1
31+
rfm9x.destination = 2
32+
# initialize counter
33+
counter = 0
34+
# send a broadcast message from my_node with ID = counter
35+
rfm9x.send(
36+
bytes("Startup message {} from node {}".format(counter, rfm9x.node), "UTF-8")
37+
)
38+
39+
# Wait to receive packets.
40+
print("Waiting for packets...")
41+
now = time.monotonic()
42+
while True:
43+
# Look for a new packet: only accept if addresses to my_node
44+
packet = rfm9x.receive(with_header=True)
45+
# If no packet was received during the timeout then None is returned.
46+
if packet is not None:
47+
# Received a packet!
48+
# Print out the raw bytes of the packet:
49+
print("Received (raw header):", [hex(x) for x in packet[0:4]])
50+
print("Received (raw payload): {0}".format(packet[4:]))
51+
print("Received RSSI: {0}".format(rfm9x.last_rssi))
52+
if time.monotonic() - now > transmit_interval:
53+
now = time.monotonic()
54+
counter = counter + 1
55+
# send a mesage to destination_node from my_node
56+
rfm9x.send(
57+
bytes(
58+
"message number {} from node {}".format(counter, rfm9x.node), "UTF-8"
59+
),
60+
keep_listening=True,
61+
)
62+
button_pressed = None

examples/rfm9x_node1_ack.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Example to send a packet periodically between addressed nodes with ACK
2+
# Author: Jerry Needell
3+
#
4+
import time
5+
import board
6+
import busio
7+
import digitalio
8+
import adafruit_rfm9x
9+
10+
# set the time interval (seconds) for sending packets
11+
transmit_interval = 10
12+
13+
# Define radio parameters.
14+
RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your
15+
# module! Can be a value like 915.0, 433.0, etc.
16+
17+
# Define pins connected to the chip.
18+
# set GPIO pins as necessary -- this example is for Raspberry Pi
19+
CS = digitalio.DigitalInOut(board.CE1)
20+
RESET = digitalio.DigitalInOut(board.D25)
21+
22+
# Initialize SPI bus.
23+
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
24+
# Initialze RFM radio
25+
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, RADIO_FREQ_MHZ)
26+
27+
# enable CRC checking
28+
rfm9x.enable_crc = True
29+
# set delay before sending ACK
30+
rfm9x.ack_delay = 0.1
31+
# set node addresses
32+
rfm9x.node = 1
33+
rfm9x.destination = 2
34+
# initialize counter
35+
counter = 0
36+
ack_failed_counter = 0
37+
# send startup message from my_node
38+
rfm9x.send_with_ack(bytes("startup message from node {}".format(rfm9x.node), "UTF-8"))
39+
40+
# Wait to receive packets.
41+
print("Waiting for packets...")
42+
# initialize flag and timer
43+
time_now = time.monotonic()
44+
while True:
45+
# Look for a new packet: only accept if addresses to my_node
46+
packet = rfm9x.receive(with_ack=True, with_header=True)
47+
# If no packet was received during the timeout then None is returned.
48+
if packet is not None:
49+
# Received a packet!
50+
# Print out the raw bytes of the packet:
51+
print("Received (raw header):", [hex(x) for x in packet[0:4]])
52+
print("Received (raw payload): {0}".format(packet[4:]))
53+
print("RSSI: {0}".format(rfm9x.last_rssi))
54+
# send reading after any packet received
55+
if time.monotonic() - time_now > transmit_interval:
56+
# reset timeer
57+
time_now = time.monotonic()
58+
counter += 1
59+
# send a mesage to destination_node from my_node
60+
if not rfm9x.send_with_ack(
61+
bytes("message from node node {} {}".format(rfm9x.node, counter), "UTF-8")
62+
):
63+
ack_failed_counter += 1
64+
print(" No Ack: ", counter, ack_failed_counter)

examples/rfm9x_node1_bonnet.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Example to send a packet periodically between addressed nodes
2+
# Author: Jerry Needell
3+
#
4+
import board
5+
import busio
6+
import digitalio
7+
8+
# Import the SSD1306 module.
9+
import adafruit_ssd1306
10+
import adafruit_rfm9x
11+
12+
# Button A
13+
btnA = digitalio.DigitalInOut(board.D5)
14+
btnA.direction = digitalio.Direction.INPUT
15+
btnA.pull = digitalio.Pull.UP
16+
17+
# Button B
18+
btnB = digitalio.DigitalInOut(board.D6)
19+
btnB.direction = digitalio.Direction.INPUT
20+
btnB.pull = digitalio.Pull.UP
21+
22+
# Button C
23+
btnC = digitalio.DigitalInOut(board.D12)
24+
btnC.direction = digitalio.Direction.INPUT
25+
btnC.pull = digitalio.Pull.UP
26+
27+
# Create the I2C interface.
28+
i2c = busio.I2C(board.SCL, board.SDA)
29+
30+
# 128x32 OLED Display
31+
reset_pin = digitalio.DigitalInOut(board.D4)
32+
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, reset=reset_pin)
33+
# Clear the display.
34+
display.fill(0)
35+
display.show()
36+
width = display.width
37+
height = display.height
38+
39+
40+
# set the time interval (seconds) for sending packets
41+
transmit_interval = 10
42+
43+
# Define radio parameters.
44+
RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your
45+
# module! Can be a value like 915.0, 433.0, etc.
46+
47+
# Define pins connected to the chip.
48+
CS = digitalio.DigitalInOut(board.CE1)
49+
RESET = digitalio.DigitalInOut(board.D25)
50+
51+
# Initialize SPI bus.
52+
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
53+
54+
# Initialze RFM radio
55+
56+
# Attempt to set up the rfm9x Module
57+
try:
58+
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, RADIO_FREQ_MHZ)
59+
display.text("rfm9x: Detected", 0, 0, 1)
60+
except RuntimeError:
61+
# Thrown on version mismatch
62+
display.text("rfm9x: ERROR", 0, 0, 1)
63+
64+
display.show()
65+
66+
# enable CRC checking
67+
rfm9x.enable_crc = True
68+
69+
# set node addresses
70+
rfm9x.node = 1
71+
rfm9x.destination = 2
72+
# initialize counter
73+
counter = 0
74+
# send a broadcast message from my_node with ID = counter
75+
rfm9x.send(
76+
bytes("Startup message {} from node {}".format(counter, rfm9x.node), "UTF-8")
77+
)
78+
79+
# Wait to receive packets.
80+
print("Waiting for packets...")
81+
button_pressed = None
82+
while True:
83+
# Look for a new packet: only accept if addresses to my_node
84+
packet = rfm9x.receive(with_header=True)
85+
# If no packet was received during the timeout then None is returned.
86+
if packet is not None:
87+
# Received a packet!
88+
# Print out the raw bytes of the packet:
89+
print("Received (raw header):", [hex(x) for x in packet[0:4]])
90+
print("Received (raw payload): {0}".format(packet[4:]))
91+
print("Received RSSI: {0}".format(rfm9x.last_rssi))
92+
# Check buttons
93+
if not btnA.value:
94+
button_pressed = "A"
95+
# Button A Pressed
96+
display.fill(0)
97+
display.text("AAA", width - 85, height - 7, 1)
98+
display.show()
99+
if not btnB.value:
100+
button_pressed = "B"
101+
# Button B Pressed
102+
display.fill(0)
103+
display.text("BBB", width - 75, height - 7, 1)
104+
display.show()
105+
if not btnC.value:
106+
button_pressed = "C"
107+
# Button C Pressed
108+
display.fill(0)
109+
display.text("CCC", width - 65, height - 7, 1)
110+
display.show()
111+
# send reading after any button pressed
112+
if button_pressed is not None:
113+
counter = counter + 1
114+
# send a mesage to destination_node from my_node
115+
rfm9x.send(
116+
bytes(
117+
"message number {} from node {} button {}".format(
118+
counter, rfm9x.node, button_pressed
119+
),
120+
"UTF-8",
121+
),
122+
keep_listening=True,
123+
)
124+
button_pressed = None

examples/rfm9x_node2.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Example to send a packet periodically between addressed nodes
2+
# Author: Jerry Needell
3+
#
4+
import time
5+
import board
6+
import busio
7+
import digitalio
8+
import adafruit_rfm9x
9+
10+
# Define radio parameters.
11+
RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your
12+
# module! Can be a value like 915.0, 433.0, etc.
13+
14+
# Define pins connected to the chip.
15+
CS = digitalio.DigitalInOut(board.CE1)
16+
RESET = digitalio.DigitalInOut(board.D25)
17+
18+
# Initialize SPI bus.
19+
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
20+
21+
# Initialze RFM radio
22+
rfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, RADIO_FREQ_MHZ)
23+
24+
# enable CRC checking
25+
rfm9x.enable_crc = True
26+
# set node addresses
27+
rfm9x.node = 2
28+
rfm9x.destination = 1
29+
# initialize counter
30+
counter = 0
31+
# send a broadcast message from my_node with ID = counter
32+
rfm9x.send(bytes("startup message from node {} ".format(rfm9x.node), "UTF-8"))
33+
34+
# Wait to receive packets.
35+
print("Waiting for packets...")
36+
# initialize flag and timer
37+
time_now = time.monotonic()
38+
while True:
39+
# Look for a new packet: only accept if addresses to my_node
40+
packet = rfm9x.receive(with_header=True)
41+
# If no packet was received during the timeout then None is returned.
42+
if packet is not None:
43+
# Received a packet!
44+
# Print out the raw bytes of the packet:
45+
print("Received (raw header):", [hex(x) for x in packet[0:4]])
46+
print("Received (raw payload): {0}".format(packet[4:]))
47+
print("Received RSSI: {0}".format(rfm9x.last_rssi))
48+
# send reading after any packet received
49+
counter = counter + 1
50+
# after 10 messages send a response to destination_node from my_node with ID = counter&0xff
51+
if counter % 10 == 0:
52+
time.sleep(0.5) # brief delay before responding
53+
rfm9x.identifier = counter & 0xFF
54+
rfm9x.send(
55+
bytes(
56+
"message number {} from node {} ".format(counter, rfm9x.node),
57+
"UTF-8",
58+
),
59+
keep_listening=True,
60+
)

0 commit comments

Comments
 (0)