如何使用pymodbus配置支持跨系统32位数据读写的Modbus服务器
Got it, let's walk through exactly how to set up your pymodbus server to match your requirements. I'll break this down step by step so you can get up and running quickly.
配置pymodbus Modbus服务器实现32位数据读写
1. 先搞定环境依赖
First, make sure you have pymodbus installed. Run this command in your terminal:
pip install pymodbus
2. 完整服务器代码实现
Here's a ready-to-use server script that binds to your specified IP (152.168.96.11), supports 32-bit data read/write, and lets your client interact with specific addresses:
from pymodbus.server import StartTcpServer from pymodbus.datastore import ModbusSequentialDataBlock, ModbusServerContext from pymodbus.datastore.store import ModbusSlaveContext def setup_modbus_server(): # 1. 定义存储区:这里用Holding Registers(常用作读写数据) # 预分配100个寄存器,足够测试32位数据(每个32位占2个寄存器) holding_registers = ModbusSequentialDataBlock(0, [0]*100) # 2. 创建从站上下文,设置允许读写所有功能码 slave_context = ModbusSlaveContext( di=None, # 不使用离散输入 co=None, # 不使用线圈 hr=holding_registers, # 绑定holding寄存器 ir=None # 不使用输入寄存器 ) # 3. 创建服务器上下文 server_context = ModbusServerContext(slaves=slave_context, single=True) # 4. 启动TCP服务器,绑定到指定IP和默认Modbus端口502 print("Starting Modbus server on 152.168.96.11:502...") StartTcpServer( context=server_context, address=("152.168.96.11", 502), allow_reuse_address=True ) def convert_32bit_to_registers(value): """把32位整数拆分为两个16位寄存器值(高16位在前)""" high_byte = (value >> 16) & 0xFFFF low_byte = value & 0xFFFF return [high_byte, low_byte] def convert_registers_to_32bit(registers): """把两个16位寄存器值合并为32位整数""" if len(registers) != 2: raise ValueError("需要两个16位寄存器来组成32位数据") return (registers[0] << 16) | registers[1] if __name__ == "__main__": setup_modbus_server()
3. 关键配置说明
- 绑定指定IP: 启动服务器时用
address=("152.168.96.11", 502),确保服务器只监听你本地系统的这个IP,完全匹配你的要求。 - 32位数据处理: Modbus没有原生的32位寄存器,所以我们用连续的两个16位holding寄存器来模拟。比如要读写32位数据到起始地址
0,实际是操作寄存器0和1。我写的转换函数可以帮你快速处理数据格式。 - 读写权限: 配置
ModbusSlaveContext时,我们把holding寄存器设为可读写,这样你的客户端可以直接对指定地址进行读写操作。
4. 测试与验证
To make sure everything works, you can either:
- Use a Modbus client tool (like modpoll) to connect to
152.168.96.11:502and test reading/writing 32-bit data. For example, to write a 32-bit value12345678to starting address 0, you'd write the split 16-bit values to registers 0 and 1. - Or use a simple pymodbus client script for testing:
from pymodbus.client import ModbusTcpClient def test_client(): client = ModbusTcpClient("152.168.96.11", port=502) client.connect() # 写入32位数据:比如写入12345678到起始地址0 value_32bit = 12345678 high, low = (value_32bit >> 16) & 0xFFFF, value_32bit & 0xFFFF client.write_registers(address=0, values=[high, low]) # 读取32位数据 response = client.read_holding_registers(address=0, count=2) if not response.isError(): read_value = (response.registers[0] << 16) | response.registers[1] print(f"读取到的32位数据: {read_value}") client.close() if __name__ == "__main__": test_client()
注意事项
- 确保服务器和客户端在同一网段,且服务器的502端口没有被防火墙拦截。
- 如果客户端使用的是其他功能码(比如输入寄存器),你可以调整
ModbusSlaveContext的配置来支持。 - 如果你需要持久化数据,可以把
ModbusSequentialDataBlock替换为支持磁盘存储的实现,不过测试阶段用内存存储就足够了。
内容的提问来源于stack exchange,提问作者Chandra Sekhar K




