我正在尝试创建Modbus串行/ RTU客户端,它将使用Pymodbus库从串口读取数据。 Python:3.6 Pymodbus:2.1.0平台:Linux / Windows我给出了示例代码库…
以下解决方案适合我。我的设备配置如下:
的 设备配置: 强> 波特率= 9600,奇偶校验='E',字节大小= 8超时= 0.2 协议:RTU PLC使用串口转USB连接到RaspberryPI。
的 工作守则: 强>
import logging from threading import Thread from time import sleep from pymodbus.client.async.twisted import ModbusClientProtocol from pymodbus.constants import Endian from pymodbus.factory import ClientDecoder from pymodbus.payload import BinaryPayloadDecoder from pymodbus.transaction import ModbusRtuFramer from serial import EIGHTBITS from serial import PARITY_EVEN from serial import STOPBITS_ONE from twisted.internet import protocol from twisted.internet import serialport, reactor FORMAT = ('%(asctime)-15s %(threadName)-15s ' '%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s') logging.basicConfig(format=FORMAT) logger = logging.getLogger() logger.setLevel(logging.INFO) def readDevices(modbusRTUDevice): deviceIP = modbusRTUDevice["ip"] devicePort = modbusRTUDevice["port"] logger.info("Connecting to Modbus RTU device at address {0}".format(deviceIP + ":" + str(devicePort))) modbusClientFactory = CustomModbusClientFactory() modbusClientFactory.address = deviceIP modbusClientFactory.modbusDevice = modbusRTUDevice SerialModbusClient(modbusClientFactory, devicePort, reactor, baudrate=9600, bytesize=EIGHTBITS, parity=PARITY_EVEN, stopbits=STOPBITS_ONE, timeout=0.2, xonxoff=0, rtscts=0) Thread(target=reactor.run, args=(False,)).start() # @UndefinedVariable class SerialModbusClient(serialport.SerialPort): def __init__(self, factory, *args, **kwargs): serialport.SerialPort.__init__(self, factory.buildProtocol(), *args, **kwargs) class CustomModbusClientFactory(protocol.ClientFactory): modbusDevice = {} def buildProtocol(self, addr=None): modbusClientProtocol = CustomModbusClientProtocol() modbusClientProtocol.factory = self modbusClientProtocol.modbusDevice = self.modbusDevice return modbusClientProtocol def clientConnectionLost(self, connector, reason): modbusTcpDeviceIP = self.modbusDevice["ip"] modbusTcpDevicePort = self.modbusDevice["port"] logger.critical("Connection lost with device running on {0}:{1}.".format(modbusTcpDeviceIP, modbusTcpDevicePort)) logger.critical("Root Cause : {0}".format(reason)) connector.connect() def clientConnectionFailed(self, connector, reason): modbusTcpDeviceIP = self.modbusDevice["ip"] modbusTcpDevicePort = self.modbusDevice["port"] logger.critical("Connection failed with device running on {0}:{1}.".format(modbusTcpDeviceIP, modbusTcpDevicePort)) logger.critical("Root Cause : {0}".format(reason)) connector.connect() class CustomModbusClientProtocol(ModbusClientProtocol): def connectionMade(self): framer = ModbusRtuFramer(ClientDecoder(), client=None) ModbusClientProtocol.__init__(self, framer) ModbusClientProtocol.connectionMade(self) deviceIP = self.modbusDevice["ip"] devicePort = self.modbusDevice["port"] logger.info("Modbus RTU device connected at address logger{0}".format(deviceIP + ":" + str(devicePort))) reactor.callLater(5, self.read) # @UndefinedVariable def read(self): deviceIP = self.modbusDevice["ip"] devicePort = self.modbusDevice["port"] slaveAddress = self.modbusDevice["slaveAddress"] logger.info("Reading holding registers of Modbus RTU device at address {0}...".format(deviceIP + ":" + str(devicePort))) deferred = self.read_holding_registers(0, 1, unit=slaveAddress) deferred.addCallbacks(self.requestFetched, self.requestNotFetched) def requestNotFetched(self, error): logger.info("Error reading registers of Modbus RTU device : {0}".format(error)) sleep(0.5) def requestFetched(self, response): logger.info("Inside request fetched...") decoder = BinaryPayloadDecoder.fromRegisters(response.registers, byteorder=Endian.Big, wordorder=Endian.Big) skipBytesCount = 0 decoder.skip_bytes(skipBytesCount) registerValue = decoder.decode_16bit_int() skipBytesCount += 2 logger.info("Sensor updated to value '{0}'.".format(registerValue)) reactor.callLater(5, self.read) # @UndefinedVariable readDevices({"ip": "127.0.0.1", "port": "/dev/ttyUSB0", "slaveAddress": 1})
的 输出: 强>
2019-02-03 00:39:00,623 MainThread INFO TestRTU:26 Connecting to Modbus RTU device at address 127.0.0.1:/dev/ttyUSB0 2019-02-03 00:39:00,628 MainThread INFO TestRTU:73 Modbus RTU device connected at address logger127.0.0.1:/dev/ttyUSB0 2019-02-03 00:39:05,634 Thread-1 INFO TestRTU:80 Reading holding registers of Modbus RTU device at address 127.0.0.1:/dev/ttyUSB0... 2019-02-03 00:39:05,676 Thread-1 INFO TestRTU:89 Inside request fetched... 2019-02-03 00:39:05,677 Thread-1 INFO TestRTU:95 Sensor updated to value '26'.
serialport.SerialPort。 的 在里面 强> (......) 构造函数负责初始化与设备进行串行通信所需的所有参数。您只需在此更新设备设置&运行代码。 SerialModbusClient(modbusClientFactory, devicePort, reactor, baudrate=9600, bytesize=EIGHTBITS, parity=PARITY_EVEN, stopbits=STOPBITS_ONE, timeout=0.2, xonxoff=0, rtscts=0)
SerialModbusClient(modbusClientFactory, devicePort, reactor, baudrate=9600, bytesize=EIGHTBITS, parity=PARITY_EVEN, stopbits=STOPBITS_ONE, timeout=0.2, xonxoff=0, rtscts=0)