首页 > 解决方案 > 关于pymodbusTCP服务器实现的问题

问题描述

我们有一个模拟器(客户端)和控制器(服务器)。控制器通过 ModbusTCP 向模拟器发送命令信号。我想在我的电脑上模拟这个控制器。

我做了什么

  1. 为了测试,我在我的电脑上编写了 pymodbus 服务器脚本,在另一台电脑上编写了 pymodbus 客户端脚本。从客户端 PC 读取保持和输入寄存器没有问题。

  2. 我将我的 clinet pc 连接到控制器(服务器),以了解我必须向实际客户端(模拟器)发送什么样的值。我发现有 8 个寄存器(从 0 到 7)用于存储整数值。

  3. 我试图在我的电脑(服务器)和模拟器计算机(客户端)之间建立连接。我能够建立连接并向客户端发送响应。

问题

  1. 我没有关于这个客户端(模拟器)的信息,因为我们无权访问客户端脚本。

  2. 我发现这个客户端不仅发送了读取请求,还发送了写入请求。

  3. 当我使用保持寄存器时,我得到一个错误“非法数据地址”。但是输入寄存器没有显示任何错误。出于这个原因,我使用 input_register 来保存一个特定的整数。

  4. 我在 input_register 上存储了一些值,但服务器 input_registers 由客户端(模拟器)编写,如下所示。

来自客户端(模拟器)的写入请求

使用 modpoll 软件轮询服务器(PC)

问题

  1. 为什么来自客户端(模拟器)的写入请求会覆盖我的 input_register?据我所知, input_register 仅用于阅读。我假设我在 input_register 上存储变量时犯了一个错误。

  2. 当我在控制器和模拟器之间建立连接时,wireshark 和 modpoll 显示客户端(模拟器)读取寄存器(从 0 到 7)。但是当我在我的服务器(PC)和客户端(模拟器)之间建立连接时,我的服务器响应具有不同的注册号,如下所示。寄存器号从1000开始。为什么模拟器要求不同的寄存器起始号?例如)从 0:控制器,从 1000:PC(服务器)

来自服务器(PC)的第一个响应

  1. 更新!我的服务器可以响应值,但注册号错误。我更改了起始寄存器号(0 --> 1000)。我附上图片。

来自服务器(PC)的响应

请就这个问题给我建议。我会尽我最大的努力来解决这个问题。

'''

from pymodbus.server.sync import StartTcpServer
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext


from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock, ModbusSparseDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

from pymodbus.transaction import ModbusRtuFramer, ModbusBinaryFramer
#%%
import logging
FORMAT = ('%(asctime)-15s %(threadName)-15s'
          ' %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)
#%%


#%%
def run_server():
    store = ModbusSlaveContext( 
    ir=ModbusSequentialDataBlock(0, [28692,28692,28692,28692,28692,65508,65508,65508
    ]),zero_mode=True)
    context = ModbusServerContext(slaves=store, single=True)
    StartTcpServer(context, address=("192.168.1.231", 502))

    identity = ModbusDeviceIdentification()
    identity.VendorName = 'Pymodbus'
    identity.ProductCode = 'PM'
    identity.VendorUrl = 'http://github.com/riptideio/pymodbus/'
    identity.ProductName = 'Pymodbus Server'
    identity.ModelName = 'Pymodbus Server'
    identity.MajorMinorRevision = '1.0'    

#%%
if __name__ == "__main__":
    run_server()

'''

亲爱的 MarcosG,我附上了来自wireshark 的屏幕截图,如下所示。

来自 clinet(simulator) 的写入请求 - 如您所见,clinet(simulator) 发送写入请求,注册号从 256 开始。

从服务器(控制器)读取响应 - 服务器(控制器)响应 clinet 的读取请求。它发送一个响应和注册号从 256 开始。

使用 modpoll 软件轮询服务器 - 我们可以查看服务器寄存器上的值,如您所见,值存储在寄存器中从 0 到 7。这​​些值来自控制器杠杆。如果我调整杠杆,这些值会发生变化。

请求的 address_exel_File - 我们还有一个模拟器(bridge2)。它显示与控制器(服务器)和 pc(服务器)相同的注册号。

问题:存储值的服务器的实际寄存器是从0到7。但是,客户端和服务器与包含“0”值的不同寄存器(从256)通信。但是在模拟器上调整船的参数是没有问题的。

最好的问候卞圣洙

标签: tcpservermodbus

解决方案


推荐阅读