Skip to content

Commit

Permalink
Dev (#16)
Browse files Browse the repository at this point in the history
* Add callback and debug functionality

* Update README.md

* Update doc strings

* Update setup.py
  • Loading branch information
PowerBroker2 authored Jun 12, 2020
1 parent c00690c commit 228fc41
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 18 deletions.
53 changes: 50 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ if __name__ == '__main__':
###################################################################
while not link.available():
if link.status < 0:
if link.status == -1:
if link.status == CRC_ERROR:
print('ERROR: CRC_ERROR')
elif link.status == -2:
elif link.status == PAYLOAD_ERROR:
print('ERROR: PAYLOAD_ERROR')
elif link.status == -3:
elif link.status == STOP_BYTE_ERROR:
print('ERROR: STOP_BYTE_ERROR')
else:
print('ERROR: {}'.format(link.status))

###################################################################
# Parse response list
Expand Down Expand Up @@ -128,3 +130,48 @@ void loop()
}
}
```

# Example Python Script with Callback Functionality
Note that you can specify many callbacks, but only one per packet ID
```Python
import time
from pySerialTransfer import pySerialTransfer as txfer


def hi():
'''
Callback function that will automatically be called by link.tick() whenever
a packet with ID of 0 is successfully parsed.
'''

print("hi")

'''
list of callback functions to be called during tick. The index of the function
reference within this list must correspond to the packet ID. For instance, if
you want to call the function hi() when you parse a packet with an ID of 0, you
would write the callback list with "hi" being in the 0th place of the list:
'''
callback_list = [ hi ]


if __name__ == '__main__':
try:
link = txfer.SerialTransfer('COM17')

link.set_callbacks(callback_list)
link.open()
time.sleep(2) # allow some time for the Arduino to completely reset

while True:
link.tick()

except KeyboardInterrupt:
link.close()

except:
import traceback
traceback.print_exc()

link.close()
```
89 changes: 76 additions & 13 deletions pySerialTransfer/pySerialTransfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,29 @@ class InvalidSerialPort(Exception):
pass


CONTINUE = 2
NEW_DATA = 1
NO_DATA = 0
CRC_ERROR = -1
PAYLOAD_ERROR = -2
STOP_BYTE_ERROR = -3
class InvalidCallbackList(Exception):
pass


CONTINUE = 3
NEW_DATA = 2
NO_DATA = 1
CRC_ERROR = 0
PAYLOAD_ERROR = -1
STOP_BYTE_ERROR = -2

START_BYTE = 0x7E
STOP_BYTE = 0x81

MAX_PACKET_SIZE = 0xFE

find_start_byte = 0
find_overhead_byte = 1
find_payload_len = 2
find_payload = 3
find_crc = 4
find_end_byte = 5
find_id_byte = 1
find_overhead_byte = 2
find_payload_len = 3
find_payload = 4
find_crc = 5
find_end_byte = 6


def msb(val):
Expand Down Expand Up @@ -90,7 +95,7 @@ def serial_ports():


class SerialTransfer(object):
def __init__(self, port, baud=115200, restrict_ports=True):
def __init__(self, port, baud=115200, restrict_ports=True, debug=True):
'''
Description:
------------
Expand All @@ -106,11 +111,15 @@ def __init__(self, port, baud=115200, restrict_ports=True):
self.txBuff = [' ' for i in range(MAX_PACKET_SIZE - 1)]
self.rxBuff = [' ' for i in range(MAX_PACKET_SIZE - 1)]

self.debug = debug
self.idByte = 0
self.bytesRead = 0
self.status = 0
self.overheadByte = 0xFF
self.callbacks = []

self.state = find_start_byte

if restrict_ports:
self.port_name = None
for p in serial_ports():
Expand Down Expand Up @@ -147,6 +156,22 @@ def open(self):
print(e)
return False
return True

def set_callbacks(self, callbacks):
'''
Description:
------------
Specify a list of callback functions to be automatically called by
self.tick() when a new packet is fully parsed. The ID of the parsed
packet is then used to determine which callback needs to be called.
:return: void
'''

if type(callbacks) == list:
self.callbacks = callbacks
else:
raise InvalidCallbackList('Parameter "callbacks" is not of type "list"')

def close(self):
'''
Expand Down Expand Up @@ -420,7 +445,11 @@ def available(self):

if self.state == find_start_byte:
if recChar == START_BYTE:
self.state = find_overhead_byte
self.state = find_id_byte

elif self.state == find_id_byte:
self.idByte = recChar
self.state = find_overhead_byte

elif self.state == find_overhead_byte:
self.recOverheadByte = recChar
Expand Down Expand Up @@ -484,6 +513,40 @@ def available(self):
self.bytesRead = 0
self.status = CONTINUE
return self.bytesRead

def tick(self):
'''
Description:
------------
Automatically parse all incoming packets, print debug statements if
necessary (if enabled), and call the callback function that corresponds
to the parsed packet's ID (if such a callback exists for that packet
ID)
:return: void
'''

if self.available():
if self.idByte < len(self.callbacks):
self.callbacks[self.idByte]()
elif self.debug:
print('ERROR: No callback available for packet ID {}'.format(self.idByte))

return True

elif self.debug and not self.status:
if self.status == CRC_ERROR:
err_str = 'CRC_ERROR'
elif self.status == PAYLOAD_ERROR:
err_str = 'PAYLOAD_ERROR'
elif self.status == STOP_BYTE_ERROR:
err_str = 'STOP_BYTE_ERROR'
else:
err_str = str(self.status)

print('ERROR: {}'.format(err_str))

return False


if __name__ == '__main__':
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
setup(
name = 'pySerialTransfer',
packages = ['pySerialTransfer'],
version = '1.2.0',
version = '2.0.0',
description = 'Python package used to transmit and receive low overhead byte packets - especially useful for PC<-->Arduino USB communication (compatible with https://github.com/PowerBroker2/SerialTransfer)',
author = 'Power_Broker',
author_email = '[email protected]',
url = 'https://github.com/PowerBroker2/pySerialTransfer',
download_url = 'https://github.com/PowerBroker2/pySerialTransfer/archive/1.2.0.tar.gz',
download_url = 'https://github.com/PowerBroker2/pySerialTransfer/archive/2.0.0.tar.gz',
keywords = ['Arduino', 'serial', 'usb', 'protocol', 'communication'],
classifiers = [],
)

0 comments on commit 228fc41

Please sign in to comment.