Modbus设备无缘无故地停止通信

时间:2016-09-29 19:04:37

标签: python modbus

我公司已经购买了几台具有modbus功能的室内温控器。那些来自中国。当我在Modbus RTU上与他们通信时,会发生有趣的事情。设备有时根本不回应我。然后在以下民意调查中,他们有时会做出回应但最后,经过一段时间,无论是一两个小时,他们完全停止响应,我从modbus主人那里得到了一些错误。我使用串口分析器来查看最新情况。我做了所有硬件检查点(终端电阻等)。我尝试了很多modbus主人。但即使连接了一个恒温器,也会出现问题。特别针对这个问题,我用Python开发了自己的modbus master。好的部分是,我使用minimalmodbus库,每次轮询后我都有机会关闭端口。但是,即使我的modbus主程序继续轮询,恒温器也完全停止响应。不知何故,我必须通过编程来解决这个问题。我总是不能重新启动恒温器以解决通信问题。

这是我的代码:

import os
import sys
import sqlite3
import time
import datetime
import minimalmodbus
minimalmodbus.CLOSE_PORT_AFTER_EACH_CALL=True

PORT_NAME           = '/com5'
SLAVE1_ADDRESS       = 1
SLAVE2_ADDRESS       = 2
SLAVE3_ADDRESS       = 3
BAUDRATE            = 9600 # baud (pretty much bits/s). Use 2400 or 38400 bits/s.
TIMEOUT             = 0.4 # seconds. At least 0.2 seconds required for 2400 bits/s.
MODE                = minimalmodbus.MODE_RTU

sqlite_file = 'ModbusTable.db'

instrument1 = minimalmodbus.Instrument(PORT_NAME, SLAVE1_ADDRESS, MODE)
instrument1.serial.baudrate = BAUDRATE
instrument1.serial.timeout = TIMEOUT
instrument1.debug = False
instrument1.precalculate_read_size = True

instrument2 = minimalmodbus.Instrument(PORT_NAME, SLAVE2_ADDRESS, MODE)
instrument2.serial.baudrate = BAUDRATE
instrument2.serial.timeout = TIMEOUT
instrument2.debug = False
instrument2.precalculate_read_size = True

instrument3 = minimalmodbus.Instrument(PORT_NAME, SLAVE3_ADDRESS, MODE)
instrument3.serial.baudrate = BAUDRATE
instrument3.serial.timeout = TIMEOUT
instrument3.debug = False
instrument3.precalculate_read_size = True

print ('Okuyor')


while 1:

    # Connecting to the database file
    conn = sqlite3.connect(sqlite_file)
    c = conn.cursor()

    try:
        values1 = instrument1.read_registers(40005, 2)
    except IOError:
        print ('Timestamp: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())+"Failed to read from instrument1")

    # C) Updates the pre-existing entry            
    c.execute("""UPDATE ModbusData SET SetPoint = ? ,ActualTemp = ? WHERE ID= ? """,
      (values1[0],values1[1],1))

    time.sleep(0.5)

    try:
        values2 = instrument2.read_registers(40005, 2)
    except IOError:
        print ('Timestamp: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())+"Failed to read from instrument2")

    # C) Updates the pre-existing entry            
    c.execute("""UPDATE ModbusData SET SetPoint = ? ,ActualTemp = ? WHERE ID= ? """,
      (values2[0],values2[1],2))

    time.sleep(0.5)  

    try:
        values3 = instrument3.read_registers(40005, 2)
    except IOError:
        print ('Timestamp: {:%Y-%m-%d %H:%M:%S}'.format(datetime.datetime.now())+"Failed to read from instrument3")

    # C) Updates the pre-existing entry            
    c.execute("""UPDATE ModbusData SET SetPoint = ? ,ActualTemp = ? WHERE ID= ? """,
      (values3[0],values3[1],3))

    time.sleep(0.5)

    # Committing changes and closing the connection to the database file
    conn.commit()
    conn.close()

以下是恒温器的表现:

enter image description here

如果你想出你的想法,我会非常感激。

1 个答案:

答案 0 :(得分:1)

通过截图来看,我认为您没有等待恒温器的回复。 第一个请求:来自" instrument1"的回复在您配置的时间范围内未收到。因此,您的程序向" instrument2"发送请求,但收到" instrument1"的延迟回复。您的日志的其余部分都是关于此的:一个请求接收来自先前请求的回复。