Skip to content

Allow access to RadioHead packet headers #12

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 4 commits into from
Nov 19, 2018
Merged
Changes from all commits
Commits
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
50 changes: 34 additions & 16 deletions adafruit_rfm69.py
Original file line number Diff line number Diff line change
Expand Up @@ -674,11 +674,14 @@ def frequency_deviation(self, val):
self._write_u8(_REG_FDEV_MSB, fdev >> 8)
self._write_u8(_REG_FDEV_LSB, fdev & 0xFF)

def send(self, data, timeout=2.):
def send(self, data, timeout=2.,
tx_header=(_RH_BROADCAST_ADDRESS, _RH_BROADCAST_ADDRESS, 0, 0)):
"""Send a string of data using the transmitter.
You can only send 60 bytes at a time
(limited by chip's FIFO size and appended headers).
Note this appends a 4 byte header to be compatible with the RadioHead library.
This appends a 4 byte header to be compatible with the RadioHead library.
The tx_header defaults to using the Broadcast addresses. It may be overidden
by specifying a 4-tuple of bytes containing (To,From,ID,Flags)
The timeout is just to prevent a hang (arbitrarily set to 2 seconds)
"""
# Disable pylint warning to not use length as a check for zero.
Expand All @@ -687,6 +690,7 @@ def send(self, data, timeout=2.):
# buffer be within an expected range of bounds. Disable this check.
# pylint: disable=len-as-condition
assert 0 < len(data) <= 60
assert len(tx_header) == 4, "tx header must be 4-tuple (To,From,ID,Flags)"
# pylint: enable=len-as-condition
self.idle() # Stop receiving to clear FIFO and keep it clear.
# Fill the FIFO with a packet to send.
Expand All @@ -697,10 +701,10 @@ def send(self, data, timeout=2.):
# Add 4 bytes of headers to match RadioHead library.
# Just use the defaults for global broadcast to all receivers
# for now.
self._BUFFER[2] = _RH_BROADCAST_ADDRESS # txHeaderTo
self._BUFFER[3] = _RH_BROADCAST_ADDRESS # txHeaderFrom
self._BUFFER[4] = 0 # txHeaderId
self._BUFFER[5] = 0 # txHeaderFlags
self._BUFFER[2] = tx_header[0] # Header: To
self._BUFFER[3] = tx_header[1] # Header: From
self._BUFFER[4] = tx_header[2] # Header: Id
self._BUFFER[5] = tx_header[3] # Header: Flags
device.write(self._BUFFER, end=6)
# Now send the payload.
device.write(data)
Expand All @@ -718,14 +722,27 @@ def send(self, data, timeout=2.):
if timed_out:
raise RuntimeError('Timeout during packet send')

def receive(self, timeout=0.5, keep_listening=True):
def receive(self, timeout=0.5, keep_listening=True, with_header=False,
rx_filter=_RH_BROADCAST_ADDRESS):
"""Wait to receive a packet from the receiver. Will wait for up to timeout_s amount of
seconds for a packet to be received and decoded. If a packet is found the payload bytes
are returned, otherwise None is returned (which indicates the timeout elapsed with no
reception). Note this assumes a 4-byte header is prepended to the data for compatibilty
with the RadioHead library (the header is not validated nor returned). If keep_listening
is True (the default) the chip will immediately enter listening mode after reception of
a packet, otherwise it will fall back to idle mode and ignore any future reception.
reception).
If keep_listening is True (the default) the chip will immediately enter listening mode
after reception of a packet, otherwise it will fall back to idle mode and ignore any
future reception.
A 4-byte header must be prepended to the data for compatibilty with the
RadioHead library.
The header consists of a 4 bytes (To,From,ID,Flags). The default setting will accept
any incomming packet and strip the header before returning the packet to the caller.
If with_header is True then the 4 byte header will be returned with the packet.
The payload then begins at packet[4].
rx_fliter may be set to reject any "non-broadcast" packets that do not contain the
specfied "To" value in the header.
if rx_filter is set to 0xff (_RH_BROADCAST_ADDRESS) or if the "To" field (packet[[0])
is equal to 0xff then the packet will be accepted and returned to the caller.
If rx_filter is not 0xff and packet[0] does not match rx_filter then
the packet is ignored and None is returned.
"""
# Make sure we are listening for packets.
self.listen()
Expand Down Expand Up @@ -760,13 +777,14 @@ def receive(self, timeout=0.5, keep_listening=True):
device.readinto(self._BUFFER, end=fifo_length)
packet = None
else:
# Read the 4 bytes of the RadioHead header.
device.readinto(self._BUFFER, end=4)
# Ignore validating any of the header bytes.
# Now read the remaining packet payload as the result.
fifo_length -= 4
packet = bytearray(fifo_length)
device.readinto(packet)
if (rx_filter != _RH_BROADCAST_ADDRESS and packet[0] != _RH_BROADCAST_ADDRESS
and packet[0] != rx_filter):
packet = None
if not with_header: # skip the header if not wanted
packet = packet[4:]

# Listen again if necessary and return the result packet.
if keep_listening:
self.listen()
Expand Down