Skip to content

Implement "reliable datagram" #24

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Apr 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ Introduction
CircuitPython RFM69 packet radio module. This supports basic RadioHead-compatible sending and
receiving of packets with RFM69 series radios (433/915Mhz).

.. note:: This does NOT support advanced RadioHead features like guaranteed delivery--only 'raw' packets are currently supported.

.. warning:: This is NOT for LoRa radios!

.. note:: This is a 'best effort' at receiving data using pure Python code--there is not interrupt
Expand Down
339 changes: 215 additions & 124 deletions adafruit_rfm69.py

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions examples/rfm69_header.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Example to display raw packets including header
# Author: Jerry Needell
#
import board
import busio
import digitalio
import adafruit_rfm69

# set the time interval (seconds) for sending packets
transmit_interval = 10

# Define radio parameters.
RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your
# module! Can be a value like 915.0, 433.0, etc.

# Define pins connected to the chip.
CS = digitalio.DigitalInOut(board.CE1)
RESET = digitalio.DigitalInOut(board.D25)

# Initialize SPI bus.
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)

# Initialze RFM radio
rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, RADIO_FREQ_MHZ)

# Optionally set an encryption key (16 byte AES key). MUST match both
# on the transmitter and receiver (or be set to None to disable/the default).
rfm69.encryption_key = (
b"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08"
)

# Wait to receive packets.
print("Waiting for packets...")
# initialize flag and timer
while True:
# Look for a new packet: only accept if addresses to my_node
packet = rfm69.receive(with_header=True)
# If no packet was received during the timeout then None is returned.
if packet is not None:
# Received a packet!
# Print out the raw bytes of the packet:
print("Received (raw header):", [hex(x) for x in packet[0:4]])
print("Received (raw payload): {0}".format(packet[4:]))
print("RSSI: {0}".format(rfm69.last_rssi))
# send reading after any packet received
66 changes: 66 additions & 0 deletions examples/rfm69_node1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Example to send a packet periodically between addressed nodes
# Author: Jerry Needell
#
import time
import board
import busio
import digitalio
import adafruit_rfm69


# set the time interval (seconds) for sending packets
transmit_interval = 10

# Define radio parameters.
RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your
# module! Can be a value like 915.0, 433.0, etc.

# Define pins connected to the chip.
CS = digitalio.DigitalInOut(board.CE1)
RESET = digitalio.DigitalInOut(board.D25)

# Initialize SPI bus.
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# Initialze RFM radio
rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, RADIO_FREQ_MHZ)

# Optionally set an encryption key (16 byte AES key). MUST match both
# on the transmitter and receiver (or be set to None to disable/the default).
rfm69.encryption_key = (
b"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08"
)

# set node addresses
rfm69.node = 1
rfm69.destination = 2
# initialize counter
counter = 0
# send a broadcast message from my_node with ID = counter
rfm69.send(
bytes("Startup message {} from node {}".format(counter, rfm69.node), "UTF-8")
)

# Wait to receive packets.
print("Waiting for packets...")
now = time.monotonic()
while True:
# Look for a new packet: only accept if addresses to my_node
packet = rfm69.receive(with_header=True)
# If no packet was received during the timeout then None is returned.
if packet is not None:
# Received a packet!
# Print out the raw bytes of the packet:
print("Received (raw header):", [hex(x) for x in packet[0:4]])
print("Received (raw payload): {0}".format(packet[4:]))
print("Received RSSI: {0}".format(rfm69.last_rssi))
if time.monotonic() - now > transmit_interval:
now = time.monotonic()
counter = counter + 1
# send a mesage to destination_node from my_node
rfm69.send(
bytes(
"message number {} from node {}".format(counter, rfm69.node), "UTF-8"
),
keep_listening=True,
)
button_pressed = None
68 changes: 68 additions & 0 deletions examples/rfm69_node1_ack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Example to send a packet periodically between addressed nodes with ACK
# Author: Jerry Needell
#
import time
import board
import busio
import digitalio
import adafruit_rfm69

# set the time interval (seconds) for sending packets
transmit_interval = 10

# Define radio parameters.
RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your
# module! Can be a value like 915.0, 433.0, etc.

# Define pins connected to the chip.
# set GPIO pins as necessary -- this example is for Raspberry Pi
CS = digitalio.DigitalInOut(board.CE1)
RESET = digitalio.DigitalInOut(board.D25)

# Initialize SPI bus.
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# Initialze RFM radio
rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, RADIO_FREQ_MHZ)

# Optionally set an encryption key (16 byte AES key). MUST match both
# on the transmitter and receiver (or be set to None to disable/the default).
rfm69.encryption_key = (
b"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08"
)

# set delay before sending ACK
rfm69.ack_delay = 0.1
# set node addresses
rfm69.node = 1
rfm69.destination = 2
# initialize counter
counter = 0
ack_failed_counter = 0
# send startup message from my_node
rfm69.send_with_ack(bytes("startup message from node {}".format(rfm69.node), "UTF-8"))

# Wait to receive packets.
print("Waiting for packets...")
# initialize flag and timer
time_now = time.monotonic()
while True:
# Look for a new packet: only accept if addresses to my_node
packet = rfm69.receive(with_ack=True, with_header=True)
# If no packet was received during the timeout then None is returned.
if packet is not None:
# Received a packet!
# Print out the raw bytes of the packet:
print("Received (raw header):", [hex(x) for x in packet[0:4]])
print("Received (raw payload): {0}".format(packet[4:]))
print("RSSI: {0}".format(rfm69.last_rssi))
# send reading after any packet received
if time.monotonic() - time_now > transmit_interval:
# reset timeer
time_now = time.monotonic()
counter += 1
# send a mesage to destination_node from my_node
if not rfm69.send_with_ack(
bytes("message from node node {} {}".format(rfm69.node, counter), "UTF-8")
):
ack_failed_counter += 1
print(" No Ack: ", counter, ack_failed_counter)
128 changes: 128 additions & 0 deletions examples/rfm69_node1_bonnet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Example to send a packet periodically between addressed nodes
# Author: Jerry Needell
#
import board
import busio
import digitalio

# Import the SSD1306 module.
import adafruit_ssd1306
import adafruit_rfm69

# Button A
btnA = digitalio.DigitalInOut(board.D5)
btnA.direction = digitalio.Direction.INPUT
btnA.pull = digitalio.Pull.UP

# Button B
btnB = digitalio.DigitalInOut(board.D6)
btnB.direction = digitalio.Direction.INPUT
btnB.pull = digitalio.Pull.UP

# Button C
btnC = digitalio.DigitalInOut(board.D12)
btnC.direction = digitalio.Direction.INPUT
btnC.pull = digitalio.Pull.UP

# Create the I2C interface.
i2c = busio.I2C(board.SCL, board.SDA)

# 128x32 OLED Display
reset_pin = digitalio.DigitalInOut(board.D4)
display = adafruit_ssd1306.SSD1306_I2C(128, 32, i2c, reset=reset_pin)
# Clear the display.
display.fill(0)
display.show()
width = display.width
height = display.height


# set the time interval (seconds) for sending packets
transmit_interval = 10

# Define radio parameters.
RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your
# module! Can be a value like 915.0, 433.0, etc.

# Define pins connected to the chip.
CS = digitalio.DigitalInOut(board.CE1)
RESET = digitalio.DigitalInOut(board.D25)

# Initialize SPI bus.
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)

# Initialze RFM radio

# Attempt to set up the RFM69 Module
try:
rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, RADIO_FREQ_MHZ)
display.text("RFM69: Detected", 0, 0, 1)
except RuntimeError:
# Thrown on version mismatch
display.text("RFM69: ERROR", 0, 0, 1)

display.show()


# Optionally set an encryption key (16 byte AES key). MUST match both
# on the transmitter and receiver (or be set to None to disable/the default).
rfm69.encryption_key = (
b"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08"
)

# set node addresses
rfm69.node = 1
rfm69.destination = 2
# initialize counter
counter = 0
# send a broadcast message from my_node with ID = counter
rfm69.send(
bytes("Startup message {} from node {}".format(counter, rfm69.node), "UTF-8")
)

# Wait to receive packets.
print("Waiting for packets...")
button_pressed = None
while True:
# Look for a new packet: only accept if addresses to my_node
packet = rfm69.receive(with_header=True)
# If no packet was received during the timeout then None is returned.
if packet is not None:
# Received a packet!
# Print out the raw bytes of the packet:
print("Received (raw header):", [hex(x) for x in packet[0:4]])
print("Received (raw payload): {0}".format(packet[4:]))
print("Received RSSI: {0}".format(rfm69.last_rssi))
# Check buttons
if not btnA.value:
button_pressed = "A"
# Button A Pressed
display.fill(0)
display.text("AAA", width - 85, height - 7, 1)
display.show()
if not btnB.value:
button_pressed = "B"
# Button B Pressed
display.fill(0)
display.text("BBB", width - 75, height - 7, 1)
display.show()
if not btnC.value:
button_pressed = "C"
# Button C Pressed
display.fill(0)
display.text("CCC", width - 65, height - 7, 1)
display.show()
# send reading after any button pressed
if button_pressed is not None:
counter = counter + 1
# send a mesage to destination_node from my_node
rfm69.send(
bytes(
"message number {} from node {} button {}".format(
counter, rfm69.node, button_pressed
),
"UTF-8",
),
keep_listening=True,
)
button_pressed = None
64 changes: 64 additions & 0 deletions examples/rfm69_node2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Example to send a packet periodically between addressed nodes
# Author: Jerry Needell
#
import time
import board
import busio
import digitalio
import adafruit_rfm69

# Define radio parameters.
RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your
# module! Can be a value like 915.0, 433.0, etc.

# Define pins connected to the chip.
CS = digitalio.DigitalInOut(board.CE1)
RESET = digitalio.DigitalInOut(board.D25)

# Initialize SPI bus.
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)

# Initialze RFM radio
rfm69 = adafruit_rfm69.RFM69(spi, CS, RESET, RADIO_FREQ_MHZ)

# Optionally set an encryption key (16 byte AES key). MUST match both
# on the transmitter and receiver (or be set to None to disable/the default).
rfm69.encryption_key = (
b"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08"
)

# set node addresses
rfm69.node = 2
rfm69.destination = 1
# initialize counter
counter = 0
# send a broadcast message from my_node with ID = counter
rfm69.send(bytes("startup message from node {} ".format(rfm69.node), "UTF-8"))

# Wait to receive packets.
print("Waiting for packets...")
# initialize flag and timer
time_now = time.monotonic()
while True:
# Look for a new packet: only accept if addresses to my_node
packet = rfm69.receive(with_header=True)
# If no packet was received during the timeout then None is returned.
if packet is not None:
# Received a packet!
# Print out the raw bytes of the packet:
print("Received (raw header):", [hex(x) for x in packet[0:4]])
print("Received (raw payload): {0}".format(packet[4:]))
print("Received RSSI: {0}".format(rfm69.last_rssi))
# send reading after any packet received
counter = counter + 1
# after 10 messages send a response to destination_node from my_node with ID = counter&0xff
if counter % 10 == 0:
time.sleep(0.5) # brief delay before responding
rfm69.identifier = counter & 0xFF
rfm69.send(
bytes(
"message number {} from node {} ".format(counter, rfm69.node),
"UTF-8",
),
keep_listening=True,
)
Loading