4、Python Modbus库安装:pymodbus库安装、serial库配置、虚拟串口工具使用

好,咱们进入实战前的最后一道准备工序——装工具。

说实话,我见过太多学员卡在这一步。不是装不上,而是装完发现串口不通,或者版本冲突。今天咱们一步步来,把坑提前填上。

4.1 pymodbus库安装

pymodbus是目前Python生态里最成熟的Modbus库。我个人习惯用pip安装,简单直接。

pip install pymodbus

如果你用的是Python 3.10及以上版本,建议指定版本安装,避免一些老接口的兼容问题:

pip install pymodbus==3.6.8
我的经验: 我在项目中遇到过pymodbus 2.x和3.x的API差异很大。3.x版本重构了异步接口,如果你之前看过老教程,记得确认版本。我建议统一用3.x,官方已经停止维护2.x了。

安装完成后,验证一下:

python -c "import pymodbus; print(pymodbus.__version__)"

能打印出版本号,就算成了。如果报错,多半是pip源的问题,换个国内镜像:

pip install pymodbus -i https://pypi.tuna.tsinghua.edu.cn/simple

4.2 serial库配置

pymodbus底层依赖pyserial来操作串口。这个库其实不用单独装,pymodbus会自动把它拉下来。但为了保险,我建议显式安装一次:

pip install pyserial

为什么要单独提这个?

嗯,这里要注意。有些Linux系统自带的python环境里,serial模块是系统级的,和pip安装的pyserial可能冲突。我曾经在一台工控机上调试,死活import不了serial,最后发现是系统自带的python3-serial包和pip包重名了。

解决办法很简单:卸载系统包,只用pip的。

sudo apt remove python3-serial
pip install pyserial

验证串口是否可用:

python -c "import serial; print(serial.__version__)"
避坑指南: 我曾经在Windows上遇到串口号大于COM10时,pyserial无法识别。原因是Windows的串口命名规则问题。解决办法是在设备管理器里把串口号改到COM1-COM9之间,或者用\\.\COM10这种格式。

4.3 虚拟串口工具使用

你想想看,做工业通讯开发,最头疼的是什么?

是没有真实设备!总不能每次调试都搬一台PLC或者变频器到电脑前吧?

虚拟串口工具就是干这个的。它能在你的电脑上创建一对虚拟串口,比如COM3和COM4,这两端数据是互通的。你可以在一个终端里跑Modbus主站,另一个终端里跑从站模拟器,完全模拟真实通讯。

4.3.1 Windows平台:Virtual Serial Port Emulator

我个人推荐VSPE(Virtual Serial Port Emulator),免费版够用。下载安装后,操作很简单:

  1. 打开VSPE,点击「Create new device」
  2. 选择「Pair」模式
  3. 设置一对串口号,比如COM3和COM4
  4. 点击「Create」

搞定之后,你的电脑上就多了一对物理上不存在的串口。但任何往COM3发数据,COM4都能收到,反之亦然。

4.3.2 Linux平台:socat

Linux下更简单,一条命令搞定:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

执行后会输出两个设备路径,比如/dev/pts/2和/dev/pts/3。这两个就是虚拟串口。

我的习惯: 我一般会在调试脚本里写一个自动创建虚拟串口的函数,用subprocess调用socat。这样每次跑测试前自动创建,测试完自动销毁,省得手动操作。

4.3.3 验证虚拟串口是否工作

打开两个终端,一个用minicom或putty连COM3,另一个连COM4。在COM3这边随便敲几个字符,COM4那边能显示出来,就说明通了。

或者用Python验证:

# 终端1:监听COM4
python -c "import serial; s=serial.Serial('COM4', 9600); print(s.read(10))"

# 终端2:往COM3发数据
python -c "import serial; s=serial.Serial('COM3', 9600); s.write(b'hello')"

终端1能打印出b'hello',就说明虚拟串口工作正常。

4.4 完整环境验证

最后,咱们把pymodbus和虚拟串口结合起来,跑一个最简单的Modbus RTU通讯:

# 从站模拟器(终端1)
from pymodbus.server import StartSerialServer
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

store = ModbusSlaveContext(zero_mode=True)
context = ModbusServerContext(slaves=store, single=True)
StartSerialServer(context, port='COM4', baudrate=9600)

# 主站读取(终端2)
from pymodbus.client import ModbusSerialClient

client = ModbusSerialClient(method='rtu', port='COM3', baudrate=9600)
client.connect()
result = client.read_holding_registers(0, 1, slave=1)
print(f"读取结果: {result.registers}")
client.close()

如果一切顺利,你会看到主站成功读取到从站的寄存器数据。虽然寄存器里默认是0,但至少证明整个链路通了。

核心要点:
  • pymodbus和pyserial必须版本匹配,建议用pip统一安装
  • 虚拟串口是调试利器,没有真实设备也能完整模拟Modbus通讯
  • Windows用VSPE,Linux用socat,各取所需
  • 验证环境时,先测串口通断,再测Modbus协议层

好了,环境搭好了,下一章咱们就开始写真正的Modbus通讯代码。到时候你会觉得,前面这些准备工作,值!