【问题标题】:Modbus, python and minimal modbusModbus、python 和最小的 modbus
【发布时间】:2016-11-03 20:35:22
【问题描述】:

我正在使用 Python 库 Minimal Modbus 来读取电表 (RS-485)。

我正在尝试使用该函数一次读取多个寄存器

read_registers(registeraddress, numberOfRegisters, functioncode=3)

这里是python库的代码:

def read_registers(self, registeraddress, numberOfRegisters, functioncode=3):
        """Read integers from 16-bit registers in the slave.

        The slave registers can hold integer values in the range 0 to 65535 ("Unsigned INT16").

        Args:
            * registeraddress (int): The slave register start address (use decimal numbers, not hex).
            * numberOfRegisters (int): The number of registers to read.
            * functioncode (int): Modbus function code. Can be 3 or 4.

        Any scaling of the register data, or converting it to negative number (two's complement)
        must be done manually.

        Returns:
            The register data (a list of int).

        Raises:
            ValueError, TypeError, IOError

        """
        _checkFunctioncode(functioncode, [3, 4])
        _checkInt(numberOfRegisters, minvalue=1, description='number of registers')
        return self._genericCommand(functioncode, registeraddress, \
            numberOfRegisters=numberOfRegisters, payloadformat='registers')

我遇到的问题是寄存器将数据保存为Long,但此函数将它们作为int 的列表返回,并查看它似乎不正确的值。

这是我目前的脚本:

##!/usr/bin/env python

import minimalmodbus
import time
import glob
import sys
import MySQLdb

instrument = minimalmodbus.Instrument('/dev/ttyUSB1', 7)

#Debug Options

#instrument.debug = True #debug modbus

read = False

def convert(value):
        data=chr(value)
        return data

def read_registers_ime():
        data = instrument.read_registers(4096,20)
        return data

while True:
        try:
                while read == False:
                        data = read_registers_ime()
                        print data
                        time.sleep(0.11)
                        read = True

                break

        except KeyboardInterrupt:
                print "Stopped"
                sys.exit()

        except TypeError:
                print "TypeError"

        except IOError:
                print "IOError"

此时它返回以下内容:

[3, 39192, 3, 44592, 3, 44592, 0, 423, 0, 0, 0, 0, 0, 0, 6, 19884, 6, 24584, 6, 19884]

到目前为止,我尝试将数据转换回原始格式的一切都失败了。我真的很感谢这里的一些帮助。

非常感谢,

布莱恩

【问题讨论】:

    标签: python modbus


    【解决方案1】:

    我已经遇到过这种使用 umodbus 而不是最小 modbus 的 modbus 问题。我通过以下方式解决了它:

    • 成对获取寄存器
    • 使用struct 将对转换为整数

    参见下面的示例(Python 2.7):

    import struct
    
    registers = [3, 39192, 3, 44592, 3, 44592, 0, 423, 0, 0, 0, 0, 0, 0, 6, 19884, 6, 24584, 6, 19884]
    
    def grouped(iterable, group_size):
        """iterates on iterable, yielding groups of group_size elements"""
        it = iter(iterable)
        while True:
            group = [next(it) for _ in range(group_size)]
            yield group
    
    for group in grouped(registers, 2):
        bytes = b""
        for word in group:
            word_bytes = struct.pack("H", word)
            bytes += word_bytes
        bytes_hex = "0x" + "".join(["{:>02X}".format(ord(byte_)) for byte_ in bytes])
        print("{} -> {} -> {}".format(group, bytes_hex, struct.unpack("<i", bytes)[0]))
    

    打印:

    [3, 39192] -> 0x03001899 -> -1726480381
    [3, 44592] -> 0x030030AE -> -1372585981
    [3, 44592] -> 0x030030AE -> -1372585981
    [0, 423] -> 0x0000A701 -> 27721728
    [0, 0] -> 0x00000000 -> 0
    [0, 0] -> 0x00000000 -> 0
    [0, 0] -> 0x00000000 -> 0
    [6, 19884] -> 0x0600AC4D -> 1303117830
    [6, 24584] -> 0x06000860 -> 1611137030
    [6, 19884] -> 0x0600AC4D -> 1303117830
    

    此示例可能需要根据您的确切需求进行一些调整,但它可能会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-17
      • 2022-08-16
      • 2020-12-01
      • 2019-01-20
      • 1970-01-01
      • 2014-06-16
      • 2021-09-24
      相关资源
      最近更新 更多