我一直在使用pymodbus在Raspberry Pi 3B上解码错误。使用MAX14854G作为RS-485收发器设计了一块板,该板连接到RPI3的UART引脚(8&10)。当前正在使用RS-485电缆和Modbus仿真器(Modbus Simulator-> 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模拟器,可以进行数据通信。
答案 0 :(得分:1)
响应不正确。对于功能3
(即read out words
),响应应类似于[SlaveNb] [FnNb] [NbBytes] [Data] [CRC16]
。您的请求是正确的,您要从地址1 word
开始的0
。
响应应为01 03 02 XX XX YY YY
,其中02
是数据字节数,XX XX
是数据,YY YY
是CRC16。您应该注意到,您的NbBytes
字段的响应值为0,但字数应加倍。
顺便说一句,您的回复看起来像是请求的回声。接线没错吗可能您循环了rx&tx?
答案 1 :(得分:0)
我不确定我是否了解您的设置,但在我看来,您正在尝试从RS485总线读取数据,而Pi端的驱动器使能信号始终为高。
您需要在发送完Modbus查询后立即将驱动器启用开关切换为低电平,以便能够从总线读取响应。
您需要实现硬件或软件方式来切换它。在这里看看:background on RS485
编辑:如果您想使用 libmodbus 来查看此问题和答案,包括GPIO线切换,您的代码中缺少了(不是Python,但您应该能够很容易地从C库包装它):