3、开发环境搭建:Python工控环境配置

工控开发,环境搭不好,后面全是坑。我见过太多人花一整天装库、调版本,最后发现连串口都打不开。说白了,工控环境跟Web开发不一样,它跟硬件绑定,跟操作系统底层打交道,一步错步步错。

这一章,我带你把Python工控环境从头捋一遍。从虚拟环境管理,到pySerial和modbus-tk的安装,再到依赖管理的实战技巧。嗯,都是我在产线上踩过坑之后总结出来的。

3.1 虚拟环境管理:别让依赖打架

你想想看,一个项目用pySerial 3.4,另一个项目用pySerial 3.5。如果全装到系统Python里,早晚出问题。我有个同事,就因为全局装了太多库,最后连pip list都卡半天。

虚拟环境就是给每个项目一个独立的Python解释器空间。 我习惯用Python自带的venv模块,轻量、干净、不依赖第三方工具。

创建虚拟环境(Windows/Linux通用):

# 创建虚拟环境
python -m venv industrial_env

# 激活虚拟环境
# Windows:
industrial_env\Scripts\activate

# Linux/Mac:
source industrial_env/bin/activate

# 退出虚拟环境
deactivate

激活后,命令行前面会出现(industrial_env)的标识。这时候你安装的所有库,都只在这个环境里生效。我曾经在一条产线上同时维护三个工控项目,每个项目用不同的modbus库版本,全靠虚拟环境隔离,从来没出过冲突。

我的习惯: 每个工控项目根目录下放一个.venv文件夹,用.gitignore把它排除掉。这样团队成员拉代码后,各自创建自己的虚拟环境,互不影响。

3.2 pySerial:串口通信的基石

工控里最常用的通信方式是什么?串口。PLC、变频器、传感器,十有八九都走RS232或RS485。pySerial就是Python操作串口的标配库。

安装很简单:

pip install pyserial

注意,库名是小写的pyserial,但导入时用import serial。我第一次用的时候就搞混了,pip install serial装了个完全不一样的东西,折腾了半天才发现。

一个典型的串口连接代码:

import serial
import serial.tools.list_ports

# 列出所有可用串口
ports = serial.tools.list_ports.comports()
for port in ports:
    print(f"端口: {port.device}, 描述: {port.description}")

# 打开串口
ser = serial.Serial(
    port='COM3',        # Windows用COM口,Linux用/dev/ttyUSB0
    baudrate=9600,      # 波特率,工控常用9600、19200、115200
    bytesize=8,         # 数据位,通常8位
    parity='N',         # 校验位:N无校验,E偶校验,O奇校验
    stopbits=1,         # 停止位,通常1位
    timeout=1           # 超时时间,单位秒
)

# 发送数据
ser.write(b'\x01\x03\x00\x00\x00\x01\x84\x0A')

# 读取数据
response = ser.read(8)
print(response.hex())

# 关闭串口
ser.close()

避坑指南: 我曾经在调试一台老式PLC时,发现数据总是对不上。查了半天,原来是PLC的停止位是2位,而我默认用了1位。工控设备五花八门,通信参数一定要跟设备手册一一核对,少一个都不行。

3.3 modbus-tk:Modbus协议实现

Modbus是工控领域的事实标准协议。pySerial只负责收发原始字节,而modbus-tk帮你把Modbus协议的数据帧封装好,你直接读写寄存器就行。

安装:

pip install modbus-tk

实现一个Modbus RTU主站(读取从站数据):

import modbus_tk
import modbus_tk.defines as cst
from modbus_tk import modbus_rtu
import serial

# 创建串口连接
logger = modbus_tk.utils.create_logger("console")

try:
    # 连接串口
    master = modbus_rtu.RtuMaster(
        serial.Serial(port='COM3', baudrate=9600, bytesize=8, parity='N', stopbits=1)
    )
    master.set_timeout(1.0)
    master.set_verbose(True)

    # 读取从站1的保持寄存器,起始地址0,读取10个寄存器
    data = master.execute(1, cst.READ_HOLDING_REGISTERS, 0, 10)
    print(f"读取到的数据: {data}")

    # 写入单个寄存器(从站1,地址0,写入值100)
    master.execute(1, cst.WRITE_SINGLE_REGISTER, 0, output_value=100)

    master.close()

except Exception as e:
    print(f"通信失败: {e}")

关键点说明:

  • execute的第一个参数是从站地址(1-247),第二个参数是功能码
  • 常用功能码:READ_HOLDING_REGISTERS(03)、READ_INPUT_REGISTERS(04)、WRITE_SINGLE_REGISTER(06)
  • 寄存器地址从0开始,但有些设备手册从1开始编号,记得减1

我记得有一次,现场工程师说设备没反应。我远程一看,代码里从站地址写的是0。Modbus协议里地址0是广播地址,所有从站都会响应,但不会回复数据。改成实际地址后,数据就正常了。这种细节,手册上写得清清楚楚,但一忙起来就容易忽略。

3.4 依赖管理最佳实践

项目做完了,怎么把环境完整地交给别人?靠嘴说「你装一下pySerial和modbus-tk」?不行。版本不对,环境就崩了。

我推荐的做法:

  1. 生成requirements.txt:
# 在虚拟环境中执行
pip freeze > requirements.txt

生成的文件内容大概长这样:

pyserial==3.5
modbus-tk==1.1.2
pyserial==3.5
  1. 别人拿到项目后,一键安装:
pip install -r requirements.txt

我的经验: 别用pip freeze > requirements.txt直接导出全部依赖。它会把虚拟环境里所有库都列出来,包括很多间接依赖。我习惯手动维护requirements.txt,只写项目直接依赖的库和版本,比如:

pyserial>=3.4,<4.0
modbus-tk>=1.1.0,<2.0

这样版本范围更灵活,也更容易排查问题。

3.5 知识体系总览

下面这张图,把开发环境搭建的核心逻辑串起来了。从虚拟环境隔离,到串口通信,再到Modbus协议封装,最后用依赖管理收尾。你照着这个流程走,基本不会出大问题。

Python工控环境搭建知识体系 虚拟环境 python -m venv pySerial 串口通信基础 modbus-tk Modbus协议封装 依赖 各层关键操作 1. 虚拟环境:python -m venv env_name → source env/bin/activate → pip install 2. pySerial:serial.Serial(port, baudrate, bytesize, parity, stopbits, timeout) 3. modbus-tk:master.execute(slave_id, function_code, start_addr, quantity) 4. 依赖管理:pip freeze > requirements.txt → pip install -r requirements.txt 核心原则:环境隔离 → 通信可靠 → 协议标准 → 依赖可复现

3.6 常见问题与排查思路

问题现象 可能原因 解决方法
serial.serialutil.SerialException 串口被占用或不存在 检查设备管理器,确认COM口编号;关闭其他占用串口的软件
modbus_tk.modbus.ModbusError 从站无响应或功能码不支持 检查从站地址、通信参数;用串口调试工具抓包确认
pip安装失败 网络问题或Python版本不兼容 换国内镜像源:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple
虚拟环境激活后pip仍指向全局 PATH环境变量顺序问题 检查which pip路径,确保在虚拟环境的Scripts目录下

最后提醒一句: 工控环境最怕「能用就行」的心态。串口参数差一个比特,数据就全乱了。依赖版本差一个小数点,代码就跑不起来。我见过太多因为环境问题导致的现场故障,其实只要前期花10分钟把环境搭规范,后面能省一整天排查时间。

专注资料整理