第1章:核心库入门——工欲善其事,必先利其器

各位同学,大家好。我是你们这门课的老朋友。

说实话,每次开始一个新项目,我最头疼的不是写代码,而是选工具。工具选对了,后面顺风顺水;选错了,那真是欲哭无泪。今天咱们要聊的这五个库,就是我这些年做医疗贴片测试项目时,反复打磨出来的「黄金组合」。

你想想看,一个贴片从产线上下来,我们要控制仪器测它、要跟它串口通信、要处理测回来的数据、要把数据画成图、最后还得有个界面让操作员用。这五个环节,一个都不能少。而这五个库,恰好就是干这些活的。

5.1 PyVISA:跟仪器「对话」的万能翻译官

先说说PyVISA。这玩意儿说白了,就是让你用Python去控制那些老贵的测试仪器。示波器、万用表、信号发生器,只要支持VISA协议,都能搞定。

我记得第一次用PyVISA的时候,是在调试一个贴片的阻抗测试。当时手动按仪器按钮按到手酸,后来用PyVISA写了个脚本,一键搞定。那种感觉,嗯,就像从手动挡换成了自动挡。

核心概念:PyVISA是一个Python库,它封装了VISA(Virtual Instrument Software Architecture)协议。你不需要关心底层是GPIB、USB还是以太网,PyVISA帮你统一了接口。

安装很简单,一行命令:

pip install pyvisa pyvisa-py

来个最基础的例子,看看怎么读取万用表的电压值:

import pyvisa

# 创建资源管理器
rm = pyvisa.ResourceManager()

# 列出所有可用的仪器
print(rm.list_resources())
# 输出类似:('USB0::0x1234::0x5678::INSTR',)

# 连接仪器
inst = rm.open_resource('USB0::0x1234::0x5678::INSTR')

# 发送命令,读取电压
voltage = inst.query('MEAS:VOLT:DC?')
print(f'当前电压:{voltage} V')

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

避坑指南:我曾经犯过一个低级错误——忘记调用close()。结果仪器一直被占用,其他程序连不上。后来我习惯用with语句来自动管理资源,推荐你也这么做。

5.2 PySerial:串口通信的老司机

接下来是PySerial。医疗贴片很多都通过串口跟电脑通信,比如发个指令让贴片开始测量,或者读取贴片返回的数据。

PySerial用起来非常直观。说白了,就是把串口当成一个文件来读写。你往里面写数据,它帮你发出去;它收到数据,你读出来就行。

import serial
import time

# 打开串口
ser = serial.Serial(
    port='COM3',        # Windows下是COM口,Linux下是/dev/ttyUSB0
    baudrate=115200,    # 波特率
    timeout=1           # 超时时间
)

# 发送指令
ser.write(b'START_MEASURE\n')

# 等待响应
time.sleep(0.5)
response = ser.readline()
print(f'贴片返回:{response.decode().strip()}')

# 关闭串口
ser.close()

注意:串口通信最怕的就是波特率不匹配。我曾经调试一个贴片,死活收不到数据,折腾了半天才发现是波特率设错了。所以,拿到设备第一件事,确认波特率、数据位、停止位这些参数。

5.3 NumPy:数据处理的瑞士军刀

NumPy,这个不用我多说了吧?做数据处理的,没人不知道它。在医疗贴片测试中,我们经常要处理大量的测量数据,比如电压序列、温度曲线、阻抗谱等等。NumPy就是干这个的。

我个人习惯,所有从仪器读回来的原始数据,第一步先转成NumPy数组。为什么?因为后面所有的计算、统计、滤波,NumPy都给你准备好了。

import numpy as np

# 假设从仪器读回来1000个电压值
raw_data = [1.23, 1.25, 1.22, ...]  # 原始列表

# 转成NumPy数组
data = np.array(raw_data)

# 基本统计
print(f'平均值:{np.mean(data):.3f} V')
print(f'标准差:{np.std(data):.3f} V')
print(f'最大值:{np.max(data):.3f} V')
print(f'最小值:{np.min(data):.3f} V')

# 滤波:移动平均
window_size = 10
filtered = np.convolve(data, np.ones(window_size)/window_size, mode='valid')

为什么用NumPy?因为纯Python的列表做数学运算太慢了。NumPy底层用C语言实现,速度能快几十倍。你想想看,测一个贴片可能产生几万个数据点,不用NumPy,等它算完黄花菜都凉了。

5.4 Matplotlib:让数据「说话」

数据算出来了,然后呢?你得把它画出来。Matplotlib就是Python里最经典的数据可视化库。在医疗贴片测试中,我们经常要画波形图、趋势图、散点图,甚至3D图。

我一般用Matplotlib做两件事:一是开发阶段快速看数据,二是生成测试报告里的图表。

import matplotlib.pyplot as plt
import numpy as np

# 生成模拟数据
x = np.linspace(0, 10, 1000)
y = np.sin(x) + 0.1 * np.random.randn(1000)

# 画图
plt.figure(figsize=(10, 6))
plt.plot(x, y, label='测量信号', color='blue', alpha=0.7)
plt.xlabel('时间 (s)')
plt.ylabel('电压 (V)')
plt.title('贴片输出信号')
plt.grid(True, alpha=0.3)
plt.legend()
plt.show()

小技巧:我习惯在画图时加上网格和坐标轴标签。别小看这两步,在测试现场,操作员可能只有几秒钟来判断一个贴片是否合格。图表清晰,一眼就能看出问题。

5.5 PyQt5:给测试工具穿上「衣服」

最后是PyQt5。前面四个库都是干「幕后」工作的,而PyQt5负责的是「台前」——也就是用户界面。一个专业的测试工具,不能只有命令行,得有个像样的界面。

PyQt5是Qt框架的Python绑定。Qt本身是C++写的,PyQt5把它包装成了Python接口。你用它拖拖拽拽就能做出一个界面,而且跨平台,Windows、Linux、macOS都能跑。

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('医疗贴片测试工具')
        self.setGeometry(100, 100, 400, 300)
        
        # 添加一个按钮
        self.btn = QPushButton('开始测试', self)
        self.btn.setGeometry(150, 100, 100, 30)
        self.btn.clicked.connect(self.on_click)
        
        # 添加一个标签
        self.label = QLabel('等待测试...', self)
        self.label.setGeometry(150, 150, 200, 30)
    
    def on_click(self):
        self.label.setText('测试进行中...')

app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

注意:PyQt5的界面线程和后台工作线程要分开。我曾经犯过一个错误——在界面线程里直接做耗时操作,结果界面卡死了。后来我学会了用QThread来处理后台任务,界面始终保持流畅。

小结:五虎上将,各司其职

好了,这一章的内容就到这里。咱们总结一下:

  • PyVISA:控制仪器,读取测量数据
  • PySerial:串口通信,跟贴片「聊天」
  • NumPy:数据处理,计算统计指标
  • Matplotlib:数据可视化,画图看趋势
  • PyQt5:界面开发,给工具做「皮肤」

这五个库,就像五虎上将,各有所长。后面的章节,我们会一个一个深入进去,把它们用到极致。你准备好了吗?

下一章,咱们先从PyVISA开始,手把手教你控制一台真实的仪器。