如何从串行数据中提取特定序列

时间:2019-09-12 07:37:02

标签: python-3.x pyserial

我正在尝试使用pyserial api从raspberry pi 3读取一些串行数据,我需要按特定顺序的数据,例如3xxx7xxxBxxxExxx,但是,有时数据流从Exxx3xxx7xxxBxxx开始,如何确保我始终正确读取数据顺序,无论数据如何流入。

这是从特殊泵应用程序中使用的控制卡中读取数据。

import serial
import time

ser = serial.Serial(
    port = '/dev/ttyACM0',
    baudrate = 9600,
    parity = serial.PARITY_NONE,
    stopbits = seial.STOPBITS_ONE,
    bytesize = serial.EIGHTBITS,
    timeout = 1
)

time.sleep = 1

try:
    while 1:
        if ser.inWaiting() > 0:
            data = ser.read(8)
            print(data.hex())

这有时会给我3xxx7xxxBxxxExxx的结果,而有时它是从7xxx或Exxx开始的,但是,我始终希望能够提取序列3xxx7xxxBxxxExxx,而不管流从何处开始。

1 个答案:

答案 0 :(得分:0)

假设您用来确定序列开始的标记是一个完整的字节0x30,则可以尝试以下代码。它将一次读取一个字节,直到找到开始标记。然后它将读取另外7个字节并将其附加:

import serial
import time

ser = serial.Serial(
    port = '/dev/ttyACM0',
    baudrate = 9600,
    parity = serial.PARITY_NONE,
    stopbits = seial.STOPBITS_ONE,
    bytesize = serial.EIGHTBITS,
    timeout = 1
)

time.sleep = 1

start_marker = b'\xE0'

try:
    while 1:
        if ser.inWaiting() > 0:
            data = ser.read(1)
            if data != start_marker:
                continue
            data += ser.read(7)
            print(data.hex())

编辑

尝试以下代码以匹配每个字节对的最高4位:

import serial
import time

ser = serial.Serial(
    port = '/dev/ttyACM0',
    baudrate = 9600,
    parity = serial.PARITY_NONE,
    stopbits = seial.STOPBITS_ONE,
    bytesize = serial.EIGHTBITS,
    timeout = 1
)

time.sleep = 1
data = bytes()

try:
    while 1:
        if ser.inWaiting() > 0:
            data += ser.read(1)
            if len(data) < 8:
                continue
            if len(data) > 8:
                data = data[-8:]
            if not (
                data[0] >> 4 == 0x3 and
                data[2] >> 4 == 0x7 and
                data[4] >> 4 == 0xB and
                data[6] >> 4 == 0xE
            ):
                continue
            print(data.hex())