requirements.txt文件包含了三个主要依赖:
- pymodbus - 用于Modbus协议的实现,版本3.0.0或更高
- pyserial - 用于串口通信,版本3.5或更高
- pyinstaller - 用于Python代码打包成exe
pymodbus>=3.0.0
pyserial>=3.5
pyinstaller>=5.13.0
主程序文件modbus_rtu_slave.py:
from pymodbus.server.sync import StartSerialServer
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
from pymodbus.datastore import ModbusSparseDataBlock
from pymodbus.transaction import ModbusRtuFramer
import logging
import sys
import traceback
# 配置日志
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
def run_modbus_rtu_slave():
try:
# 创建数据存储
store = ModbusSlaveContext(
hr=ModbusSparseDataBlock(), # 使用稀疏数据存储
ir=ModbusSparseDataBlock(), # 输入寄存器
co=ModbusSparseDataBlock(), # 线圈
di=ModbusSparseDataBlock() # 离散输入
)
# 初始化保持寄存器
for i in range(16):
store.setValues(3, i, [0]) # 3表示保持寄存器的功能码
# 初始化输入寄存器
for i in range(16):
store.setValues(4, i, [0]) # 4表示输入寄存器的功能码
# 初始化线圈
for i in range(16):
store.setValues(1, i, [0]) # 1表示线圈的功能码,设置线圈值为0(False)
# 初始化离散输入
for i in range(16):
store.setValues(2, i, [0]) # 2表示离散输入的功能码,设置离散输入值为0(False)
context = ModbusServerContext(slaves=store, single=True)
# 启动 Modbus RTU 服务器
StartSerialServer(context, framer=ModbusRtuFramer, port='COM2', baudrate=38400, timeout=0.1, log=log)
except Exception as e:
error_msg = f"错误: {str(e)}\n{traceback.format_exc()}"
print(error_msg)
# 如果是exe运行,保持窗口显示
if getattr(sys, 'frozen', False):
input("按回车键退出...")
sys.exit(1)
if __name__ == "__main__":
run_modbus_rtu_slave()
打包脚本build.py:
import PyInstaller.__main__
import sys
import os
# 确保在脚本所在目录运行
os.chdir(os.path.dirname(os.path.abspath(__file__)))
PyInstaller.__main__.run([
'modbus_rtu_slave.py', # 你的主程序文件
'--onefile', # 打包成单个文件
'--name=ModbusRTUSlave', # 输出的exe名称
# '--noconsole', # 不显示控制台窗口
# '--add-data=README.md;.', # 如果有其他需要打包的资源文件
# '--icon=icon.ico', # 如果你有图标文件的话
])