You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

PyModbus服务器写入值无法被客户端读取的问题求助

PyModbus服务器写入值无法被客户端读取的问题求助

我最近在用PyModbus搭建Modbus TCP服务器,遇到了一个头疼的问题:我用block.setValues往服务器里写入了值,但客户端就是读不到。我实在搞不清哪里错了,网上相关资料也不多,连ChatGPT和Copilot都帮不上忙。

最开始我想生成随机数模拟噪声,用plt显示,但这对我来说更难,就先放弃了。

编辑1:我试了在启动TCP服务器之前先设置值,这时候客户端居然能读到了!这说明StartTcpServer是阻塞的,程序会卡在这一步直到我停止程序,这是为什么?该怎么解决?

编辑2:后来Copilot告诉我,PyModbus里的StartTcpServer是阻塞调用,服务器运行期间不会把控制权交还给程序。而且我发现从客户端修改值是可行的,之后读取也正常,看来我得改成从客户端写入的方式了,但还是想先解决服务器端主动更新值的问题。

服务器代码

from pymodbus.server import StartTcpServer
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
from pymodbus.device import ModbusDeviceIdentification
import random
import time


# Datenblock initialisieren
block = ModbusSequentialDataBlock(0, [0]*100)
store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block)
context = ModbusServerContext(slaves=store, single=True)

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


def update_data():
    while True:
        # Zufällige Werte im Register ändern (z.B. für 100 Werte)
        for i in range(0,10):
            block.setValues(i, random.randint(0,255))
        print("Daten aktualisiert...")
        print(block.values)
        time.sleep(5)  # Warte 1 Sekunde vor der nächsten Aktualisierung


if __name__ == '__main__':
    # Starte den Server
    #print("Starte Modbus-Server...")

    # Server starten - der Server läuft hier in einer Blockschleife
    StartTcpServer(context, identity=identity, address=("localhost", 5020))

    # Daten regelmäßig aktualisieren (die Server-Logik läuft hier im Hintergrund)
    while True:
        update_data()  # Daten regelmäßig aktualisieren

客户端代码

from pymodbus.client import ModbusTcpClient
import time

# Modbus-Server-Adresse und -Port
SERVER_IP = 'localhost'
SERVER_PORT = 5020

# Erstelle den Modbus-TCP-Client
client = ModbusTcpClient(SERVER_IP, port=SERVER_PORT)


def read_data():
    while True:
        list=[]
        for i in range(0,10):
            result = client.read_holding_registers(i)

            if result.isError():
                print("Fehler beim Auslesen der Register.")
            else:
                # Ausgabe der Werte
                list.append(result.registers)

        print("Gelesene Werte:", list)

        # Warte 5 Sekunden bevor die nächsten Daten ausgelesen werden
        time.sleep(5)


if __name__ == "__main__":
    # Verbindung zum Server aufbauen
    if client.connect():
        print(f"Verbunden mit Modbus-Server {SERVER_IP}:{SERVER_PORT}")
        read_data()  # Starte das regelmäßige Auslesen der Daten
    else:
        print(f"Verbindung zum Server {SERVER_IP}:{SERVER_PORT} konnte nicht hergestellt werden.")

现在客户端读取到的都是全0的列表,比如[ [0], [0], ...],我试过读线圈寄存器和保持寄存器,都不行。目前我只想先把读取的问题解决,这样后面才能继续开发,求各位大佬帮忙!

备注:内容来源于stack exchange,提问作者Fff

火山引擎 最新活动