python-3.x - 如何从串行数据中提取特定序列
问题描述
我正在尝试使用 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 而不管流从哪里开始。
解决方案
假设您用来确定序列开始的标记是一个完整字节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())
推荐阅读
- python - Apache Kafka Kerberos 使用 Python 进行身份验证
- lda - 关于“潜在狄利克雷分配的吉布斯采样器推导”的问题
- linux - Azure Linux WebApp 网络核心日志记录到磁盘工作示例
- python-3.x - 如何在我的自定义 python 包中包含自动下载?
- byte-buddy - bytebuddy - 添加类级别注释
- sql - 如何识别在 7 天内订购了 3 次或更多订单的客户。SQL/整体/红移
- rubygems - Jekyll::Drops::CollectionDrop:Class (NoMethodError) 的未定义方法 `delegate_method_as' 你的意思是?委托类
- kotlin - Kotlin 的“内部”关键字 Java 互操作
- c# - 如何在 Visual Studio 的构建时将文件或文本嵌入到 c# 项目 dll?
- python - 带有日志记录和 Click 的 Pytest 仅在 Docker 中失败并出现 ValueError