Python 使用Pymodbus将RS232 Ascii转换为Modbus TCP

Python 使用Pymodbus将RS232 Ascii转换为Modbus TCP,python,raspberry-pi,modbus,pymodbus,Python,Raspberry Pi,Modbus,Pymodbus,我正在尝试使用将RS252 Ascii字符串数据从传感器转换为Modbus TCP输入/保持寄存器,服务器是向客户端记录器请求的主报告数据,我不确定我需要做什么才能使其正常工作。我目前能够读取数据并使用此工具将其记录到csv文件中 #!/usr/bin/env python # Log data from serial port import argparse import serial import datetime import time import os parser = arg

我正在尝试使用将RS252 Ascii字符串数据从传感器转换为Modbus TCP输入/保持寄存器,服务器是向客户端记录器请求的主报告数据,我不确定我需要做什么才能使其正常工作。我目前能够读取数据并使用此工具将其记录到csv文件中

#!/usr/bin/env python
# Log data from serial port


import argparse
import serial
import datetime
import time
import os


parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("-d", "--device", help="device to read from", default="/dev/ttyUSB0")
parser.add_argument("-s", "--speed", help="speed in bps", default=9600, type=int)
args = parser.parse_args()

outputFilePath = os.path.join(os.path.dirname(__file__),
                 datetime.datetime.now().strftime("%Y-%m-%d") + ".csv")

with serial.Serial(args.device, args.speed) as ser, open(outputFilePath,'w') as outputFile:
    print("Logging started. Ctrl-C to stop.") 
    try:
        while True:
            time.sleep(0.2) 
            x = (ser.read(ser.inWaiting())) 
            data = x.decode('UTF-8')
            if data !="":
                outputFile.write(time.strftime("%Y/%m/%d %H:%M ") + " " + data  )
                outputFile.flush()

    except KeyboardInterrupt:
        print("Logging stopped")

来自传感器的字符串从设备中取出,如下所示:

 0.00 0.0 0.0 346.70 25.14
我需要将每一个部件作为自己的Modbus寄存器,我正在尝试在Raspberry Pi Zero上使用pymodbus。传感器每秒更新4次,我能够将数据分解成几个部分,我只是想;我还没有做到这一点,因为我不确定我需要在回调脚本中做什么,我还不太精通Python,但我还在学习。我确实了解Modbus TCP,并在Arduino系统上使用过它。任何帮助都将不胜感激。

您需要的是,您可以使用它来填充寄存器。您必须关注函数
def updatening\u writer
,进行串行读取、处理并写入您选择的寄存器。这个例子在第一次尝试时很难阅读和理解。我已经修改了文件以满足您的需要。但是这里有一些关键的概念,它们将有助于理解代码

另外请注意,该示例使用基于twisted的异步服务器,如果您是twisted新手,或者有一些限制不允许您在目标上使用twisted,那么您也可以通过简单线程实现同样的效果。设计大致如下

  • 在单独的线程中启动更新函数
  • 在末尾启动TCP服务器(阻塞)
  • 一旦服务器运行并更新了值,您就可以使用客户端读取值并将其解析回float

    from pymodbus.client.sync import ModbusTcpClient as Client
    from pymodbus.payload import BinaryPayloadDecoder, Endian
    client = Client(<IP-ADDRESS>, port=5020)
    
    # Each 32 bit float is stored in 2 words, so we will read 10 registers 
    raw_values = client.read_holding_registers(0, 10, unit=1)
    if not registers.isError():
        registers = raw_values.registers
        decoder = BinaryPayloadDecoder.fromRegisters(registers, 
        wordorder=Endian.Big, byteorder=Endian.Big)
    
        for _ in range(5):
            print(decoder.decode_32bit_float())
    
    
    从pymodbus.client.sync导入ModbusTcpClient作为客户端
    从pymodbus.payload导入二进制PayloadDecoder,Endian
    客户端=客户端(,端口=5020)
    #每个32位浮点存储在2个字中,因此我们将读取10个寄存器
    原始值=客户端。读取保存寄存器(0,10,单位=1)
    如果不是,则注册.isError():
    寄存器=原始值。寄存器
    解码器=二进制PayloadDecoder.fromRegisters(寄存器,
    wordorder=Endian.Big,byteorder=Endian.Big)
    对于范围(5)内的uu:
    打印(解码器.解码\u 32位\u浮点())
    
    非常感谢您,我将尽快对此进行测试。我已经为此挣扎了一个多星期,这是我得到的最好的答案。调试:pymodbus.server.async:客户端连接[IPv4Address(type='TCP',host='192.168.1.102',port=5020]调试:pymodbus.server.async:接收的数据:0x0 0x1 0x0 0x0 0x0 0x0 0x6 0x0 0x3 0x9c 0x41 0x0 0xa调试:pymodbus.framer.socket\u framer:处理:0x0 0x1 0x0 0x0 0x0 0x6 0x0 0x3 0x9c 0x41 0x0 0xa调试:pymodbus.工厂:工厂请求[3]DEBUG:pymodbus.server.async:Datastore无法完成请求:“dict”对象没有属性“validate”错误:pymodbus.pdu:Exception Response(131,3,slavefilure)DEBUG:pymodbus.server.async:send:00010000003008304traceback(最近一次调用):文件“/usr/local/lib/python2.7/dist packages/twisted/internet/base.py”,第1267行,在运行self.mainLoop()文件“/usr/local/lib/python2.7/dist packages/twisted/internet/base.py”的第1276行,在运行untillcurrent.rununtillcurrent()文件“/usr/local/lib/python2.7/dist packages/twisted/internet/base.py”的第902行,在rununtillcurrent call.func(*call.args,**call.kw)(第1/2部分)文件中“/usr/local/lib/python2.7/dist packages/twisted/internet/task.py”,第239行,在调用d=defer.maybeDeferred(self.f,*self.a,**self.kw)时----File“/usr/local/lib/python2.7/dist packages/twisted/internet/defer.py”,第151行,在maybeDeferred result=f(*args,**kw)文件“updateing_server.py”中,在更新_writer上下文第82行[slave_id].setValues(寄存器、地址、寄存器)异常。AttributeError:“dict”对象没有属性“setValues”(第2/2部分)您使用的pymodbus版本是什么,这应该适用于pymodbus==2.2.0rc4
    from pymodbus.client.sync import ModbusTcpClient as Client
    from pymodbus.payload import BinaryPayloadDecoder, Endian
    client = Client(<IP-ADDRESS>, port=5020)
    
    # Each 32 bit float is stored in 2 words, so we will read 10 registers 
    raw_values = client.read_holding_registers(0, 10, unit=1)
    if not registers.isError():
        registers = raw_values.registers
        decoder = BinaryPayloadDecoder.fromRegisters(registers, 
        wordorder=Endian.Big, byteorder=Endian.Big)
    
        for _ in range(5):
            print(decoder.decode_32bit_float())