首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pymodbus TCP `read_holding_registers`返回陈旧/旧数据

Pymodbus TCP `read_holding_registers`返回陈旧/旧数据
EN

Stack Overflow用户
提问于 2018-08-17 17:27:20
回答 1查看 2.8K关注 0票数 3

我已经开始使用pymodbus读取modbus的值,以便存储在离站点的数据库中。我一直在努力解决一个问题,即响应中收到的值与我在Jace上看到的值不一样。

我也尝试过modbus-tk,并且得到了同样不正确的响应,所以一定是我的Python代码中的什么东西导致了这个问题。从遗留系统(VB.Net)中检索到的数据与我在Jace上看到的输出相同。

这是从modbus检索数据的简单函数。我们在4016040162有两个寄存器,第一个是读取366,它是正确的,第二个是读取367 (这是我有问题的一个)。我还在其他寄存器中看到了相同的问题,即使我可以在Jace上看到这个值增加了,读取也不会更新。

代码语言:javascript
复制
# -*- coding: utf-8 -*-

from __future__ import division, print_function, unicode_literals

from pymodbus.client.sync import ModbusTcpClient
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder

def get_modbus_register_data(ip_address, register, device, count=2):
        """
        Retrieve modbus data.
        """
        client = ModbusTcpClient(ip_address, timeout=10)
        client.connect()

        # Read registers
        response = client.read_holding_registers(
            address=register,  # 40162
            count=count,       # 2
            unit=device)       # 4

        decoder = BinaryPayloadDecoder.fromRegisters(
            registers=response.registers,
            byteorder=Endian.Big,
            wordorder=Endian.Little)

        value = decoder.decode_32bit_float()

        client.close()

        return value # 366 and it should be 367

Pymodbus调试日志

代码语言:javascript
复制
DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x4 0x3 0x0 0xa0 0x0 0x2
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x0 0x1 0x0 0x0 0x0 0x7 0x4 0x3 0x4 0x0 0x0 0x43 0xb7
DEBUG:pymodbus.framer.socket_framer:Processing: 0x0 0x1 0x0 0x0 0x0 0x7 0x4 0x3 0x4 0x0 0x0 0x43 0xb7
DEBUG:pymodbus.factory:Factory Response[ReadHoldingRegistersResponse: 3]
DEBUG:pymodbus.transaction:Adding transaction 1
DEBUG:pymodbus.transaction:Getting transaction 1
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'

更新

在三居的帮助下,有人向我指出,我使用的偏移量可能是不正确的。确实是这样,通过将偏移量更改1 (40162 - 40001 = 161),我能够从寄存器中检索正确的值,wordorder需要更改为Endian.Big

更新代码

代码语言:javascript
复制
def get_modbus_register_data(ip_address, register, device, count=2):
        """
        Retrieve modbus data.
        """
        client = ModbusTcpClient(ip_address, timeout=10)
        client.connect()

        # Read registers
        response = client.read_holding_registers(
            address=register,  # 40161
            count=count,       # 2
            unit=device)       # 4

        decoder = BinaryPayloadDecoder.fromRegisters(
            registers=response.registers,
            byteorder=Endian.Big,
            wordorder=Endian.Big)

        value = decoder.decode_32bit_float()

        client.close()

        return value # 367
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-08-23 04:00:26

使用pymodbus时,您必须注意pymodbus是如何处理偏移量的,偏移量0映射要注册40001,因此40162的偏移量是40162-40001,也就是0xa1,对于40160,偏移量也是0x9f。有关更多信息,请参阅message.ReadHoldingRegistersRequest

还请注意,BinaryPayloadDecoder假定的默认BinaryPayloadDecoder是用于byteorderEndian.Little和用于wordorderEndian.Big。如果这些orders不正确,您将得到错误的解码值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51900315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档