2016-11-03 360 views
0

我正在使用python庫最小Modbus讀取電能表(RS-485)。Modbus,python和最小modbus

我試圖使用該函數在一次

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,6,19884,6,24584,6,19884]

到目前爲止,我試圖將數據轉換回原始格式失敗。我非常感謝這裏的幫助。

非常感謝,

布萊恩

回答

1

我已經遇到這樣的問題,採用MODBUS umodbus而不是最小的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 

這個例子可能需要根據您的確切需求進行一些調整,但它可能會有所幫助。