import time
import binascii
import utils
def data_recv(self):
while (True):
midd_data = []
while True:
rev_num = self.ser.inWaiting()
recv_buffer = b''
while rev_num:
recv_buffer += self.ser.read(rev_num)
time.sleep(0.1)
rev_num = self.ser.inWaiting()
if recv_buffer:
str_buffer = ''
for c in binascii.hexlify(recv_buffer):
str_buffer += chr(c)
queue_pkt = utils.hexstr_to_int_list(str_buffer)
if queue_pkt[0:2] == [0xcc, 0xcc] and queue_pkt[-1] == 0xff:
print("cctt recv: %s" % utils.int_list_to_hexstr(queue_pkt))
midd_data = []
self.data_que.put(queue_pkt)
else:
midd_data.extend(queue_pkt)
def foo(inner_midd_data):
nonlocal midd_data
for index, item in enumerate(zip(inner_midd_data[:], inner_midd_data[1:])):
if item == (0xcc, 0xcc):
payload_len = inner_midd_data[index + 2]
fixed_len = 10
data_len = payload_len + fixed_len
inner_queue_pkt = inner_midd_data[index: index + data_len]
if len(inner_queue_pkt) == data_len:
if inner_queue_pkt[-1] == 0xff:
print("cctt recv: %s" % utils.int_list_to_hexstr(inner_queue_pkt))
self.data_que.put(inner_queue_pkt)
if len(inner_midd_data[index + data_len:]) > 0:
foo(inner_midd_data[index + data_len:])
break
else:
midd_data = inner_queue_pkt
foo(midd_data)
数据帧格式
0xcc # 1 byte
0xcc # 1 byte
payload_len # payload 字节数 , 1 byte
中间略 # 4 byte
payload # payload_len byte
crc校验 # 2 byte
0xff # 1 byte
代码解析
这里的完成性判断并没有做crc校验。
对于前导数据和结束数据符合格式的,直接认为数据帧完整。
if queue_pkt[0:2] == [0xcc, 0xcc] and queue_pkt[-1] == 0xff:
对于前导数据和结束数据符不合格式的,把上帧数据多余部分与当前帧合并,遍历到指定前导符符合的数据位置,然后根据 payload长度+ 固定数据长度,获取当前数据帧数据,然后判断是否符合数据格式。这里主要是foo的递归使用。
midd_data.extend(queue_pkt)
def foo(inner_midd_data):
数据帧样例
数据帧1: CC CC 0B FD 07 00 01 00 29 01 01 00 91 11 00 00 03 21 92 9D FF CC CC 0B FD 07 00
数据帧2: 01 00 29 01 02 00 91 11 00 00 04 14 10 AF FF CC CC 0B FD 07 00 01 00 29 01 03 00 91 11 00 00 03 32 52 89 FF