当主站请求保存Arduino从站的注册表值时,如何解决Pymodbus异常
How to solve Pymodbus exception when Master requests for holding registry values of the Arduino Slave
我目前正在尝试从我的Arduino从站接收数据到我的计算机。我成功地创建了一个Arduino奴隶。但是,当我尝试使用Pymodbus库从计算机接收数据时,我的代码无法从Arduino接收数据并引发ModbusIOException。对于我的项目的规格,我正在尝试使用Arduino构建一个Modbus RTU,以模拟以随机数作为读数的传感器。Arduino代码使用Andre Sarmento的Modbus-Arduino库。
https://github.com/andresarmento/modbus-arduino
我已经检查了我的Arduino奴隶是否正常工作。我尝试通过Modbus Master模拟器(QModMaster)读取数据,它工作得很好。这可能证明问题本身来自主控码的代码。此外,串行连接似乎工作正常,因为 self.client.connect() 返回 True。
这些是QModMaster配置的屏幕截图。
从属配置 串行端口配置
主站的 Python 代码:
class ModbusRTU:
def __init__(self, graph_name, port, baudrate=9600,
stopbits=1, bytesize=8, parity='N',
timeout=1):
self.graph_name = graph_name
self.client = ModbusSerialClient(method='rtu',
port=port,
baudrate=baudrate,
parity=parity,
timeout=timeout)
self.connection = self.client.connect()
result = self.client.read_holding_registers(address=0,
count=2,
unit=1)
print(result.registers)
if __name__ == '__main__':
modbus = ModbusRTU(graph_name='/dev/ttyACM0',
port='/dev/ttyACM0', baudrate=9600,
stopbits=1, bytesize=8, parity='N',
timeout=1)
print(modbus.check_connection())
模拟从站和传感器的 Arduino 代码:
#include <Modbus.h>
#include <ModbusSerial.h>
ModbusSerial mb;
const int READING = 0;
const int DECIMAL = 1;
void setup() {
mb.config(&Serial, 9600, SERIAL_8N1);
mb.setSlaveId(1);
mb.addHreg(READING);
mb.addHreg(DECIMAL);
}
void loop() {
mb.task();
mb.Hreg(READING, random(1, 201));
mb.Hreg(DECIMAL, random(0, 4));
}
在打印results.registers
时,它应该是一个整数列表。但是,它只是引发一个ModbusIOException,其中包含以下消息:
'ModbusIOException' object has no attribute 'registers'
File "/home/kebaranas/PythonProjects/ThirsyWell/tools/utilities.py", line 21, in __init__
print(result.registers)
File "/home/kebaranas/PythonProjects/ThirsyWell/tools/utilities.py", line 29, in <module>
timeout=1)
它也给出了这个信息。
Modbus Error: [Input/Output] Modbus Error: [Invalid Message] Incomplete message received, expected at least 2 bytes (0 received)
在print(result.registers)
之前,请尝试以下代码片段:
if not result.isError():
print(result.registers)
else:
print("error: {}".format(result))
另外,填写其他ModbusSerialClient()
参数。
以下是代码片段的更新:
from pymodbus.client.sync import ModbusSerialClient
class ModbusRTU:
def __init__(self, graph_name, port, baudrate=9600,
stopbits=1, bytesize=8, parity='N',
timeout=1):
self.graph_name = graph_name
self.client = ModbusSerialClient(
method='rtu',
port=port,
baudrate=baudrate,
parity=parity,
timeout=timeout,
stopbits=stopbits,
bytesize=bytesize
)
self.connection = self.client.connect()
result = self.client.read_input_registers(address=1,
count=2,
unit=1)
if not result.isError():
print(result.registers)
else:
print("error: {}".format(result))
if __name__ == '__main__':
modbus = ModbusRTU(
graph_name='/dev/ttyACM0',
port='/dev/ttyACM0', baudrate=9600,
stopbits=1, bytesize=8, parity='N',
timeout=1
)
您正在从站中定义保持寄存器,但您正在尝试将它们读取为输入寄存器,请尝试更改此行:
result = self.client.read_input_registers(address=1, count=2, unit=1)
自:
result = self.client.read_holding_registers(address=1, count=2, unit=1)
请注意,Modbus 规范定义了这两种不同类型的寄存器:保持和输入,具体取决于它们所在的内存区域。
我已经找到了解决方案,感谢少数人的帮助。QModMaster使用一个名为libmodbus的库。由于Arduino模拟从站和传感器与QModMaster配合使用,因此更改以前的库并使用libmodbus会更容易。幸运的是,libmodbus 有一个 python 等价物,它是 pylibmodbus。这是库 https://github.com/stephane/pylibmodbus 的链接。
from pylibmodbus import ModbusRtu
class ModbusRTU:
def __init__(self, port, baudrate=9600, databit=8, parity='None',
stopbit=1, timeout=1000):
self.parity = {'Odd': 'O', 'Even': 'E', 'None': 'N'}
self.modbus = ModbusRtu(device=port.encode('ascii'),
data_bit=databit, baud=baudrate,
parity=self.parity[parity]
.encode('ascii'),
stop_bit=stopbit)
self.modbus.set_response_timeout(timeout/1000)
self.modbus.connect()
self.modbus.set_slave(1)
result = self.modbus.read_registers(0, 2)
print(result)
self.modbus.close()
if __name__ == '__main__':
main = ModbusRTU('/dev/ttyACM0', baudrate=9600, databit=8,
parity='None', stopbit=1)
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- Ardunio UNO解决了多个重叠的定时器循环
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 两个文件使用彼此的功能-如何解决
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 如何解决"invalid conversion from 'char' to 'const char*'"
- 在java中解决这段代码时面临循环中的问题
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 难以理解某些人解决IOI问题的源代码
- visual c++,如何获取解决方案目录中的代码
- 如何解决错误:SCIP C++中的 SCIP 阶段无效 <10>
- 节俭并发:未解决的外部问题
- IpOpt拒绝解决不受约束的问题
- 如何解决这个超硬恒星的创造问题
- 循环无限运行C++解决骑士之旅问题
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- 为什么这段代码不起作用,我该如何解决?