1

我一直在使用 pymodbus 在我的 Raspberry Pi 3B 上解码错误。使用 MAX14854G 作为 RS-485 收发器设计了一块电路板,连接到 RPI3 的 UART 引脚(8 和 10)。目前使用 RS-485 电缆和 modbus 模拟器(Modbus 模拟器 --> RS485 电缆 --> RS-485 HAT 板 UART --> Raspberry Pi 3B)对其进行测试。

框图:

在此处输入图像描述

附加信息:我通过交换 ttyS0 和 ttyAMA0 并禁用串行控制台和蓝牙来使用 UART (ttyAMA0) 的全部功能:

$ sudo systemctl disable serial-getty@ttyAMA0.service
$ sudo systemctl disable serial-getty@ttyS0.service
$ sudo systemctl disable serial-getty@serial0.service
$ sudo systemctl disable serial-getty@serial1.service

这是我的代码+错误+日志:

In [1]: import pymodbus
   ...: import serial
   ...: import serial.rs485
   ...: from pymodbus.pdu import ModbusRequest
   ...: from pymodbus.client.sync import ModbusSerialClient as ModbusClient
   ...: from pymodbus.transaction import ModbusRtuFramer
   ...: from pymodbus.register_read_message import ReadInputRegistersResponse
   ...: 
   ...: import logging
   ...: logging.basicConfig()
   ...: log = logging.getLogger()
   ...: log.setLevel(logging.DEBUG)

In [2]: msys = ModbusClient(method='rtu',port='/dev/ttyAMA0',stopbits=1,bytesize=8,parity='O',baudrate=9600,timeout=2)

In [3]: msys.inter_char_timeout = 0.05

In [4]: HR2 = msys.read_holding_registers(0,1,unit=1)
DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x1 0x3 0x0 0x0 0x0 0x1 0x84 0xa
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x1 0x3 0x0 0x0 0x0 0x1 0x84
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'

In [5]: HR2
Out[5]: 
pymodbus.exceptions.ModbusIOException('No Response received from the remote unit/Unable to decode response',
                                  3)

In [6]: print(HR2)
Modbus Error: [Input/Output] No Response received from the remote unit/Unable to decode response

In [7]: print(HR2.registers)
---------------------------------------------------------------------------
 AttributeError                            Traceback (most recent call last)
<ipython-input-7-02134bc1ab17> in <module>()
----> 1 print(HR2.registers)

AttributeError: 'ModbusIOException' object has no attribute 'registers'

这是解码问题还是 Raspberry Pi 3B 的 UART 设置不正确?在禁用串行控制台之前,我什至无法连接到设备。基于 Modbus 模拟器,有数据流量。

在此处输入图像描述

4

2 回答 2

1

响应不正确。对于函数3(即read out words),响应应如下所示[SlaveNb] [FnNb] [NbBytes] [Data] [CRC16]。您的要求是正确的,您要求1 word从 address 开始0

响应应该是01 03 02 XX XX YY YY数据02字节数,XX XX数据,YY YYCRC16。您应该注意到,您的NbBytes字段响应为 0,但字数应加倍。

顺便说一句,您的回复看起来像是请求的回声。你不是接线有误吗?可能你循环了 rx&tx?

于 2018-12-17T13:28:20.953 回答
0

我不确定我是否理解您的设置,但在我看来,您正试图从 RS485 总线读取来自 Pi 侧的驱动启用信号始终为高电平。

您需要在发送完 Modbus 查询后立即将驱动器启用切换为低电平,以便能够读取来自总线的响应。

您需要实现硬件或软件方式来切换它。看这里:RS485 的背景

编辑:如果您想改用libmodbus ,请参阅此问答,包括您的代码中缺少的 GPIO 线切换(它不是 Python,但您应该能够很容易地从 C 库中包装它):

使用libmodbus的解决方案

于 2019-05-13T09:42:30.910 回答