我使用Python minimalmodbus模块运行一台带有USB-RS485适配器的Raspberry Pi 4,该适配器连接到Panasonic IntelisBox。首先,我通过以下功能检查连接:
import minimalmodbus
def openandcheckModbuscom():
print('---openandcheckModbuscom----------------')
# call the Modbus interface
ser = serial.Serial('/dev/ttyUSB0') # open serial port
if ser.is_open:
print('Serial port is open with the following settings:')
print(ser.is_open) # TRUE if port is open
print(ser.name) # print actual port name
print(ser.baudrate) # print port baudrate
else:
print('Serial port not open yet, sorry :-(')
ser.close()
当执行时,它返回:TRUE,/dev/ttyUSB0和9600,所以我认为一切都很好。接下来,我想从接口中获得更多数据,并将数据保存在数据库中,所以我运行:
def readHPstatus():
print('---readHPstatus----------------')
# call the Modbus interface
ser = serial.Serial('/dev/ttyUSB0') # open serial port
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', 1)
# Read various temperatures
outdoortemp = instrument.read_register(1, 0)
print(outdoortemp)
outgoingtemp = instrument.read_register(2, 0)
print(outgoingtemp)
ingoingtemp = instrument.read_register(3, 0)
print(ingoingtemp)
tanktemp = instrument.read_register(32, 0)
print(tanktemp)
setpointtemp = instrument.read_register(33, 0)
print(setpointtemp)
cur.execute("INSERT INTO HPstatus VALUES (?, ?, ?, ?, ?, ?,);", (Rightnow, outdoortemp, outgoingtemp, ingoingtemp, tanktemp, setpointtemp))
ser.close()
但这只返回没有连接到接口的错误消息。为什么,当我刚刚收到端口和波特率的确认。。。?我该如何开始第二部分?
完整错误消息:
Traceback (most recent call last):
File "/home/cpoll/pycode/pollvp010.py", line 260, in <module>
readHPstatus()
File "/home/cpoll/pycode/pollvp010.py", line 179, in readHPstatus
outdoortemp = instrument.read_register(1, 0) # Registernumber, number of decimals
File "/home/cpoll/.local/lib/python3.9/site-packages/minimalmodbus.py", line 480, in read_register
returnvalue = self._generic_command(
File "/home/cpoll/.local/lib/python3.9/site-packages/minimalmodbus.py", line 1245, in _generic_command
payload_from_slave = self._perform_command(functioncode, payload_to_slave)
File "/home/cpoll/.local/lib/python3.9/site-packages/minimalmodbus.py", line 1322, in _perform_command
response_bytes = self._communicate(request_bytes, number_of_bytes_to_read)
File "/home/cpoll/.local/lib/python3.9/site-packages/minimalmodbus.py", line 1490, in _communicate
raise NoResponseError("No communication with the instrument (no answer)")
minimalmodbus.NoResponseError: No communication with the instrument (no answer)
10月11日修订
修订代码:
import sqlite3
import requests
import datetime
import json
import serial
import minimalmodbus
def readHPstatus():
print('---readHPstatus----------------')
# call the Modbus interface
ser = serial.Serial('/dev/ttyUSB0')
minimalmodbus.MODE_RTU
minimalmodbus.BYTEORDER_BIG
# print(minimalmodbus._getDiagnosticString())
IntesisBox = minimalmodbus.Instrument('/dev/ttyUSB0', 1, debug = True) # port name, slave address (in decimal)
IntesisBox.serial.baudrate = 9600
IntesisBox.serial.parity = minimalmodbus.serial.PARITY_NONE
IntesisBox.serial.bytesize = 8
IntesisBox.serial.stopbits = 2
IntesisBox.serial.timeout = 0.5
IntesisBox.clear_buffers_before_each_transaction = True
IntesisBox.close_port_after_each_call = True
if ser.is_open:
print('Serial port is open with the following settings:')
print('__Serial port at device:', ser.name)
print('__Serial port baudrate: ', ser.baudrate)
# Read various temperatures
OutdoorTemp = IntesisBox.read_register(1, 0)
print('Outdoor Temperature: ', OutdoorTemp)
OutGoingTemp = IntesisBox.read_register(2, 0)
print('Outgoing Temperature:', OutGoingTemp)
InGoingTemp = IntesisBox.read_register(3, 0)
print('Ingoing Temperature: ', InGoingTemp)
TankTemp = IntesisBox.read_register(32, 0)
print('Tank Temperature: ', TankTemp)
SetpointTemp = IntesisBox.read_register(33, 0)
print('Setpoint Temperature:', SetpointTemp)
cur.execute("INSERT OR IGNORE INTO HPstatus VALUES (?, ?, ?, ?, ?, ?)", (Rightnow, OutdoorTemp, OutGoingTemp, InGoingTemp, TankTemp, SetpointTemp))
else:
print('Serial port not open yet, sorry :-(')
ser.close()
print('---END-------------------n')
运行代码输出:
---readHPstatus----------------
MinimalModbus debug mode. Create serial port /dev/ttyUSB0
Serial port is open with the following settings:
__Serial port at device: /dev/ttyUSB0
__Serial port baudrate: 9600
MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): 01 03 00 01 00 01 D5 CA (8 bytes)
MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0
MinimalModbus debug mode. No sleep required before write. Time since previous read: 152782414.06 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Closing port /dev/ttyUSB0
MinimalModbus debug mode. Response from instrument: 01 03 02 00 00 B8 44 (7 bytes), roundtrip time: 0.0 ms. Timeout for reading: 500.0 ms.
Outdoor Temperature: 0
MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): 01 03 00 02 00 01 25 CA (8 bytes)
MinimalModbus debug mode. Opening port /dev/ttyUSB0
MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0
MinimalModbus debug mode. No sleep required before write. Time since previous read: 6.31 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Closing port /dev/ttyUSB0
MinimalModbus debug mode. Response from instrument: 01 03 02 00 00 B8 44 (7 bytes), roundtrip time: 0.0 ms. Timeout for reading: 500.0 ms.
Outgoing Temperature: 0
MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): 01 03 00 03 00 01 74 0A (8 bytes)
MinimalModbus debug mode. Opening port /dev/ttyUSB0
MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0
MinimalModbus debug mode. No sleep required before write. Time since previous read: 5.67 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Closing port /dev/ttyUSB0
MinimalModbus debug mode. Response from instrument: 01 03 02 00 00 B8 44 (7 bytes), roundtrip time: 0.0 ms. Timeout for reading: 500.0 ms.
Ingoing Temperature: 0
MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): 01 03 00 20 00 01 85 C0 (8 bytes)
MinimalModbus debug mode. Opening port /dev/ttyUSB0
MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0
MinimalModbus debug mode. No sleep required before write. Time since previous read: 6.64 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Closing port /dev/ttyUSB0
MinimalModbus debug mode. Response from instrument: 01 03 02 00 00 B8 44 (7 bytes), roundtrip time: 0.0 ms. Timeout for reading: 500.0 ms.
Tank Temperature: 0
MinimalModbus debug mode. Will write to instrument (expecting 7 bytes back): 01 03 00 21 00 01 D4 00 (8 bytes)
MinimalModbus debug mode. Opening port /dev/ttyUSB0
MinimalModbus debug mode. Clearing serial buffers for port /dev/ttyUSB0
MinimalModbus debug mode. No sleep required before write. Time since previous read: 7.87 ms, minimum silent period: 4.01 ms.
MinimalModbus debug mode. Closing port /dev/ttyUSB0
MinimalModbus debug mode. Response from instrument: 01 03 02 00 00 B8 44 (7 bytes), roundtrip time: 0.0 ms. Timeout for reading: 500.0 ms.
Setpoint Temperature: 0
---END-------------------
首先删除这些行:
ser = serial.Serial('/dev/ttyUSB0') # open serial port
...
ser.close()
Minimalmodbus已经在为您实例化串行端口。关于你的第一个代码片段,你说:
执行时,它返回:TRUE、/dev/ttyUSB0和9600,所以我认为一切都很好。
嗯。。。如果一切正常,你的意思是你可以设置你的串行端口,你是对的,但正如我上面所说的,minimalmodbus正在创建串行端口本身的一个实例,其波特率默认为19200,所以你需要在创建仪器后添加以下行:
instrument.serial.baudrate = 9600
然后,根据IntelisBox手册(第7页(:
PAW-AW-MBS-H实现Modbus RTU(从(接口,连接至EIA-485行它执行8N2通信(8个数据位,无奇偶校验和2个停止位(可用波特率(2400 bps、4800 bps、9600 bps-默认值-、19200 bps、38400 bps、5760076800个基点和115200个基点(。它还支持8N1通信(8个数据位,无奇偶校验和1个停止位(
据我所知,该设备应该可以与8N1和8N2一起工作,没有任何问题,但您可能想更改minimalmodbus的配置并尝试一下:
instrument.serial.stopbits = 2
如果以上都没有帮助,你可能应该注意英国人的评论,检查所有的DIP开关,并在编写任何代码之前使用QModMaster之类的工具来调试你的设置。
最后但同样重要的是,确保接线正确。对于Modbus,您实际上需要三根导线:A、B和GND。有关更多详细信息,请参阅我的回答。看一下你的USB-to-RS485的照片,我可以看到它是一款没有GND线的产品。见鬼,IntelisBox上也没有。。。您可能需要检查该液压装置上的GND位置(无论是什么(,并将其连接到RPi接头上的一个接地引脚。
读到你问题的标题,我猜你对串行端口如何工作的理解有点错误。请注意,你在第一个代码片段上所做的一切都发生在连接到RPi的本地串行端口上。你的Intesis是而不是给你的包,因为它根本没有给你任何东西,因此日志上的这一行:
minimalmodbus.NoResponseError: No communication with the instrument (no answer)
尽管有些设备能够自动协商其波特率,但您的设备肯定不能。然而,其他一些设备将其设置存储在可通过Modbus访问的寄存器中,包括波特率,但您的设备也不是这样。所以,恐怕你的设备给你的唯一方法就是看看DIP开关的位置。