第三章 数据采集基础:串口通信原理、使用pyserial读取传感器数据、数据格式解析

3.1 串口通信,到底是个啥?

做传感器标定,第一关就是跟硬件“对上话”。

串口通信,说白了就是让两个设备按一个约定好的节奏,一位一位地传数据。你想想看,传感器采集到的温度、压力、加速度这些物理量,最终都要变成数字信号,通过串口送到你的电脑上。我刚开始接触这行时,总觉得串口很神秘,后来拆了几个模块才明白——其实就是三根线的事:TX(发送)、RX(接收)、GND(地线)。

串口通信有几个关键参数,我列个表,你对照着看:

参数 说明 常见值
波特率 每秒传输的比特数,相当于“说话速度” 9600、115200、460800
数据位 一次传输多少个数据比特 8(最常用)
停止位 每个字节传输结束后的停止信号长度 1、2
校验位 用于检测传输错误 None、Even、Odd
重要提醒: 传感器和上位机的参数必须完全一致,否则收到的全是乱码。我曾经在调试一个激光测距传感器时,波特率设成了9600,但传感器实际是115200,折腾了半小时才发现——嗯,这种低级错误,谁还没犯过呢?

3.2 用 pyserial 读取传感器数据

Python 里操作串口,最趁手的库就是 pyserial。我个人习惯先装好库,再写代码:

pip install pyserial

然后,打开串口、读取数据,核心代码其实就几行:

import serial

# 打开串口
ser = serial.Serial(
    port='COM3',        # Windows下是COM口,Linux下是/dev/ttyUSB0
    baudrate=115200,
    bytesize=8,
    parity='N',
    stopbits=1,
    timeout=1           # 超时1秒,防止卡死
)

# 读取一行数据
data = ser.readline()
print(data)

# 用完记得关闭
ser.close()

这里有个坑——readline() 读到的是字节串(bytes),不是字符串。你直接打印出来,看到的可能是 b'\x01\x02\x03...' 这种鬼样子。别慌,后面我们会讲怎么解析。

我的小技巧: 调试时先用 ser.read(10) 读固定字节数,确认数据格式。等摸清了规律,再用 readline() 或 read_until() 按帧读取。

3.3 数据格式解析——从字节到物理量

传感器传过来的数据,通常不是直接能用的数字。比如一个温湿度传感器,可能发来的是这样的字节流:

b'\xAA\x55\x01\x1A\x02\x3C\xFF'

这串东西怎么变成温度和湿度?我一般按这几步走:

  1. 确定帧头帧尾——比如 \xAA\x55 是帧头,\xFF 是帧尾
  2. 提取有效数据——去掉帧头帧尾,中间 \x01\x1A\x02\x3C 就是数据区
  3. 按协议解析——比如第1字节是温度整数部分,第2字节是温度小数部分

举个例子,假设协议规定:温度 = 数据区第1字节 + 第2字节/100,湿度 = 第3字节 + 第4字节/100。那么:

raw_data = b'\xAA\x55\x01\x1A\x02\x3C\xFF'

# 去掉帧头帧尾
payload = raw_data[2:-1]  # 得到 b'\x01\x1A\x02\x3C'

# 解析温度
temp_int = payload[0]     # 0x01 = 1
temp_dec = payload[1]     # 0x1A = 26
temperature = temp_int + temp_dec / 100.0  # 1.26 °C

# 解析湿度
hum_int = payload[2]      # 0x02 = 2
hum_dec = payload[3]      # 0x3C = 60
humidity = hum_int + hum_dec / 100.0       # 2.60 %RH

print(f"温度: {temperature}°C, 湿度: {humidity}%RH")
避坑指南: 我曾经遇到一个传感器,数据手册上写的是大端序,但实际发出来的是小端序。结果解析出来的温度值忽高忽低,差点以为是传感器坏了。后来用逻辑分析仪抓波形才发现——嗯,永远不要100%相信数据手册,先拿已知值验证一下。

3.4 知识体系总览

下面这张图,把本章的核心逻辑串起来了。你一看就明白:

数据采集核心流程 串口通信原理 波特率/数据位/停止位 pyserial读取 open/read/close 数据格式解析 帧结构/字节解析 关键参数 • 波特率:115200 • 数据位:8 • 停止位:1 常用方法 • read() 读字节 • readline() 读行 • in_waiting 检查缓存 解析步骤 ① 找帧头帧尾 ② 提取有效数据 ③ 按协议换算

3.5 实战中的几个小建议

  • 先确认硬件连接——用示波器或逻辑分析仪看波形,比猜靠谱得多。我习惯先用串口助手(比如 SSCOM)手动发数据,确认传感器有响应,再写代码。
  • 加超时处理——串口读数据可能因为线松、干扰等原因卡住。设置 timeout 参数,配合 try-except 捕获异常,程序才不会死掉。
  • 数据校验不能省——很多传感器协议自带校验和(Checksum)或 CRC。解析时一定要校验,否则一个误码就能让你的标定数据全废掉。
一句话总结: 串口通信就是“对暗号”——参数对上了,数据才能传对。pyserial 帮你把暗号通道搭好,剩下的就是按协议把字节翻译成物理量。多练几次,你也能闭着眼写解析代码。

可可精品资料库