Python Modbus错误:[无效消息]收到的消息不完整,预计至少有2个字节(收到0个字节)

Python Modbus错误:[无效消息]收到的消息不完整,预计至少有2个字节(收到0个字节),python,modbus,rs485,pymodbus3,banana-pi,Python,Modbus,Rs485,Pymodbus3,Banana Pi,问题 pymodbus主/客户端可以向从/服务器发送请求。从机/服务器将返回的东西准备就绪,并等待主机/客户机拾取它们。尽管服务器/从机已准备就绪,但主/客户端仅返回错误“Modbus错误:[输入/输出]Modbus错误:[无效消息]收到的消息不完整,预计至少2个字节(收到0)” 设置 我将笔记本电脑作为服务器/从机使用此适配器: 我将Raspberry Pi 3/BananaPi作为主/客户端,并连接了此适配器: 除了Arduino与笔记本电脑适配器交换外,我将按照本教程的大部分内容进行设置:

问题

pymodbus主/客户端可以向从/服务器发送请求。从机/服务器将返回的东西准备就绪,并等待主机/客户机拾取它们。尽管服务器/从机已准备就绪,但主/客户端仅返回错误“Modbus错误:[输入/输出]Modbus错误:[无效消息]收到的消息不完整,预计至少2个字节(收到0)”

设置

我将笔记本电脑作为服务器/从机使用此适配器:

我将Raspberry Pi 3/BananaPi作为主/客户端,并连接了此适配器:

除了Arduino与笔记本电脑适配器交换外,我将按照本教程的大部分内容进行设置: -树莓的引脚连接如本教程所示

我的笔记本电脑上有此程序作为服务器/从机:

#!/usr/bin/env python
from pymodbus.server.sync import StartTcpServer
from pymodbus.server.sync import StartUdpServer
from pymodbus.server.sync import StartSerialServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock, ModbusSparseDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
from pymodbus.transaction import ModbusRtuFramer, ModbusBinaryFramer

import logging
FORMAT = ('%(asctime)-15s %(threadName)-15s'
          ' %(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)

def run_server():

    slave_store1 = ModbusSlaveContext(co=ModbusSequentialDataBlock(0, [1]*16))
    slave_store2 = ModbusSlaveContext(di=ModbusSequentialDataBlock(0, [1]*16))
    slave_store3 = ModbusSlaveContext(ir=ModbusSequentialDataBlock(0, [5]*16))
    slave_store4 = ModbusSlaveContext(hr=ModbusSequentialDataBlock(0, [5]*16))

    slaves = {
        0x01: slave_store1,
        0x02: slave_store2,
        0x03: slave_store3,
        0x04: slave_store4,
    }

    context = ModbusServerContext(slaves=slaves, single=False)

    identity = ModbusDeviceIdentification()
    identity.VendorName = 'Pymodbus'
    identity.ProductCode = 'PM'
    identity.VendorUrl = 'http://github.com/riptideio/pymodbus/'
    identity.ProductName = 'Pymodbus Server'
    identity.ModelName = 'Pymodbus Server'
    identity.MajorMinorRevision = '2.2.0'

    # RTU:
    StartSerialServer(context, framer=ModbusRtuFramer, identity=identity, port='/dev/ttyUSB0', timeout=4, baudrate=115200, stopbits=1, bytesize=8, parity='N') 

if __name__ == "__main__":
    run_server()
服务器/从属服务器上的python版本为:

$ python3 --version
Python 3.5.2
$ python3 --version
Python 3.5.2
我用这个命令启动它:

$ python3 pymodbus_sync_serv_example_2019.07.05-1316.py
$ python3 pymodbus_sync_client_example_2019.07.05-1319.py
我作为Raspberry Pi 3/BananaPi的主/客户拥有以下信息:

#!/usr/bin/env python

import logging
FORMAT = ('%(asctime)-15s %(threadName)-15s '
'%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)

UNIT = 0x1

def run_sync_client():

    client = ModbusClient(method='rtu', port='/dev/ttyS2', timeout=4, baudrate=115200, stopbits=1, bytesize=8, parity='N')

    print(client)

    client.connect()

    log.debug("===================================")
    log.debug("Read input registers")
    log.debug("")
    rr = client.read_input_registers(1, 2, unit=3)
    print(rr)

    client.close()

if __name__ == "__main__":
    #for _ in range(10):
    run_sync_client()
测试和分析

我试过覆盆子皮3和巴纳皮。同样的结果

我试过波特率=9600,38400,现在是115200

正如您在代码中看到的,超时已经很高了

服务器/从服务器的日志:

2019-07-07 13:35:00,333 MainThread      DEBUG    sync           :45       Client Connected [/dev/ttyUSB0:/dev/ttyUSB0]
2019-07-07 13:35:00,333 MainThread      DEBUG    sync           :522      Started thread to serve client
2019-07-07 13:35:08,341 MainThread      DEBUG    rtu_framer     :180      Getting Frame - 0x4 0x0 0x1 0x0 0x2
2019-07-07 13:35:08,341 MainThread      DEBUG    factory        :137      Factory Request[ReadInputRegistersRequest: 4]
2019-07-07 13:35:08,341 MainThread      DEBUG    rtu_framer     :115      Frame advanced, resetting header!!
2019-07-07 13:35:08,342 MainThread      DEBUG    context        :64       validate: fc-[4] address-2: count-2
2019-07-07 13:35:08,342 MainThread      DEBUG    context        :78       getValues fc-[4] address-2: count-2
2019-07-07 13:35:08,342 MainThread      DEBUG    sync           :143      send: [ReadRegisterResponse (2)]- b'030404000500050846'
上面的服务器/从服务器只是在最后一行日志之后用闪烁的光标等待

主/客户端的日志:

ModbusSerialClient(rtu baud[115200])
2019-07-07 13:35:04,428 MainThread      DEBUG    pymodbus_sync_client_example_2019.07.05-1319:165      ===================================
2019-07-07 13:35:04,429 MainThread      DEBUG    pymodbus_sync_client_example_2019.07.05-1319:166      Read input registers
2019-07-07 13:35:04,430 MainThread      DEBUG    pymodbus_sync_client_example_2019.07.05-1319:167      
2019-07-07 13:35:04,430 MainThread      DEBUG    transaction    :111      Current transaction state - IDLE
2019-07-07 13:35:04,430 MainThread      DEBUG    transaction    :116      Running transaction 1
2019-07-07 13:35:04,431 MainThread      DEBUG    transaction    :215      SEND: 0x3 0x4 0x0 0x1 0x0 0x2 0x21 0xe9
2019-07-07 13:35:04,431 MainThread      DEBUG    sync           :73       New Transaction state 'SENDING'
2019-07-07 13:35:04,432 MainThread      DEBUG    transaction    :224      Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2019-07-07 13:35:08,439 MainThread      DEBUG    transaction    :234      Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 2 bytes (0 received)) 
2019-07-07 13:35:08,440 MainThread      DEBUG    rtu_framer     :235      Frame - [b''] not ready
2019-07-07 13:35:08,441 MainThread      DEBUG    transaction    :390      Getting transaction 3
2019-07-07 13:35:08,442 MainThread      DEBUG    transaction    :189      Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
Modbus Error: [Input/Output] Modbus Error: [Invalid Message] Incomplete message received, expected at least 2 bytes (0 received)
ModbusSerialClient(rtu baud[115200])
2019-07-07 23:08:55,839 MainThread      DEBUG    pymodbus_sync_client_example_2019.07.05-1319:165      ===================================
2019-07-07 23:08:55,840 MainThread      DEBUG    pymodbus_sync_client_example_2019.07.05-1319:166      Read input registers
2019-07-07 23:08:55,841 MainThread      DEBUG    pymodbus_sync_client_example_2019.07.05-1319:167      
2019-07-07 23:08:55,842 MainThread      DEBUG    transaction    :111      Current transaction state - IDLE
2019-07-07 23:08:55,842 MainThread      DEBUG    transaction    :116      Running transaction 1
2019-07-07 23:08:55,843 MainThread      DEBUG    transaction    :215      SEND: 0x3 0x4 0x0 0x1 0x0 0x2 0x21 0xe9
2019-07-07 23:08:55,843 MainThread      DEBUG    sync           :79       New Transaction state 'SENDING'
2019-07-07 23:08:55,844 MainThread      DEBUG    sync           :538      GPIO - Setting pin high
2019-07-07 23:08:55,845 MainThread      DEBUG    sync           :541      GPIO - Setting pin low
2019-07-07 23:08:55,845 MainThread      DEBUG    transaction    :224      Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2019-07-07 23:08:59,516 MainThread      DEBUG    transaction    :300      Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2019-07-07 23:08:59,518 MainThread      DEBUG    transaction    :229      RECV: 0x3 0x4 0x4 0x0 0x5 0x0 0x5 0x8 0x46
2019-07-07 23:08:59,519 MainThread      DEBUG    rtu_framer     :180      Getting Frame - 0x4 0x4 0x0 0x5 0x0 0x5
2019-07-07 23:08:59,519 MainThread      DEBUG    factory        :266      Factory Response[ReadInputRegistersResponse: 4]
2019-07-07 23:08:59,520 MainThread      DEBUG    rtu_framer     :115      Frame advanced, resetting header!!
2019-07-07 23:08:59,521 MainThread      DEBUG    transaction    :379      Adding transaction 3
2019-07-07 23:08:59,522 MainThread      DEBUG    transaction    :390      Getting transaction 3
2019-07-07 23:08:59,522 MainThread      DEBUG    transaction    :189      Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
ReadRegisterResponse (2)
主/客户端上的python版本为:

我用这个命令启动它:

$ python3 pymodbus_sync_serv_example_2019.07.05-1316.py
$ python3 pymodbus_sync_client_example_2019.07.05-1319.py
Raspberry/BananaPi上的/dev的权限为:

$ ls -l /dev/ttyS*
crw--w---- 1 root tty     249, 0 Jul  7 11:21 /dev/ttyS0
crw-rw---- 1 root dialout 249, 1 Jul  7 11:22 /dev/ttyS1
crw-rw---- 1 root dialout 249, 2 Jul  7 13:35 /dev/ttyS2
crw-rw---- 1 root dialout 249, 3 Jul  7 11:20 /dev/ttyS3
在笔记本电脑的服务器/从机上:

$ ls -l /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 Jul  7 13:35 /dev/ttyUSB0
我尝试用RS485协议发送简单的数字。它们可以从master/Raspberry/BananaPi发送到笔记本电脑,但不能从另一个方向发送

我是否为设备设置了错误的权限

我做错了什么

我错过了什么

由于RS485只以一种方式工作,我不认为pymodbus是问题所在(。。。(我的逻辑是pymodbus构建在RS485标准中,如果RS485底层不起作用,pymodbus将不起作用。这一假设正确吗?)

我知道有人在谈论树莓Pi的引脚电压为3.3V,不适用于5V引脚单元。尽管如此,所有的教程似乎都忽略了这一事实和工作或者他们只是假装它有效?TTL规格表示,所有高于2.5V的电压都将被视为高电压。因此,理论上,3.3V应该是可以的,正如教程所建议的那样

我还没有在tx/rx电线上安装任何电阻用于上拉/下拉。教程并不建议这样做


我已经用modbus温湿度传感器测试了笔记本电脑上的RS85适配器。这似乎工作完美无瑕。因此,这一事实表明,BananaPi/Raspberry Pi和RS485适配器组合+软件+设置存在某种缺陷。

首先,让我开始说,很高兴能回答这样一个精心设计的问题。不是每个人都花那么多精力解释他们做了什么以及他们是如何做到的。读完后,你的问题是一个加号问题

现在谈谈你的问题。您在遵循的教程中错过了一个非常重要的步骤。正如你所说的Modbus是半双工的,你只有两条电线,只有一个设备可以在总线上通话,所以你需要一种方法来控制总线。在USB-to-RS485/422电缆中,这是由电缆上的硬件自动完成的(特别是,您的电缆使用了无处不在的FTDI芯片,该芯片具有TXEN-TX启用信号,有关更多详细信息,请参阅),这就是您注意到电缆工作良好的原因。另一方面,你的小小的3美元收发器是可怜的兄弟,它甚至没有UART,它只是一个单端到差分转换器。这就是为什么您需要提供DE/~RE(驱动器启用/不读取启用)信号,以便可怜的家伙知道何时允许它控制总线

这是您没有从教程中得到的警告:

重要信息:在将值写入RS-485模块之前,必须将引脚DE和RE设置为高电平

这似乎很容易,但如果你想想Modbus是如何工作的。。。其实并不那么容易。这行代码:

rr = client.read_input_registers(1, 2, unit=3)
如果要成功与RS485半双工通信,应该做很多事情:控制总线(在设置中将RE/~DE信号设置为高),发送Modbus查询帧,要求在单元ID 3上设置两个寄存器,在完成查询后(3.5个字符后)立即释放总线控制(现在设置RE/~DE low)并读取从机的答案

正如我在上面提到的文章中所解释的,这个问题有几种解决方案。我更喜欢的一种(更喜欢硬件)是通过硬件来实现公交车方向控制信号(最好的方法是使用硬件实现此功能的收发器,如,但在链接中,您还可以找到使用555定时器的DIY解决方案)。现在,如果您更喜欢使用软件方式,您有一些选择。您可以调整pymodbus以根据Modbus需要切换控制线(我引用的答案中包含一些链接)或者,如果您更喜欢开箱即用的解决方案,请使用libmodbus

如果您决定使用最后一个选项,您可以找到关于如何使用Rpi上的GPIO引脚构建和安装具有半双工支持的lidmodbus的所有详细信息,如果您想继续使用Python,请安装包装器并测试基本示例。还有一些范围截图,以查看通过软件切换线路与.硬件。对于大多数内部或爱好者而言,您应该能够使用软件切换,但我不相信它用于工业或更关键的应用程序

最后,我认为有必要逐一回答您的所有问题:

more imports ...

from pymodbus.transaction import ModbusSocketFramer, ModbusBinaryFramer
from pymodbus.transaction import ModbusAsciiFramer, ModbusRtuFramer
from pymodbus.client.common import ModbusClientMixin

import RPi.GPIO as GPIO
pin_de_re = 7
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(pin_de_re, GPIO.OUT, initial=GPIO.HIGH)

# --------------------------------------------------------------------------- #
# Logging
# --------------------------------------------------------------------------- #
import logging
_logger = logging.getLogger(__name__)

...more code
# --------------------------------------------------------------------------- #
# Modbus Serial Client Transport Implementation
# --------------------------------------------------------------------------- #
    def _send(self, request):
        """ Sends data on the underlying socket
            size = self.socket.write(request)
            _logger.debug("GPIO - Setting pin high")
            GPIO.output(pin_de_re, 1)
            time.sleep(.300)
            size = self.socket.write(request)
            time.sleep(.300)
            _logger.debug("GPIO - Setting pin low")
            GPIO.output(pin_de_re, 0)
2019-07-07 23:08:43,532 MainThread      DEBUG    sync           :45       Client Connected [/dev/ttyUSB0:/dev/ttyUSB0]
2019-07-07 23:08:43,533 MainThread      DEBUG    sync           :522      Started thread to serve client
2019-07-07 23:08:47,534 MainThread      DEBUG    rtu_framer     :232      Frame check failed, ignoring!!
2019-07-07 23:08:47,535 MainThread      DEBUG    rtu_framer     :128      Resetting frame - Current Frame in buffer - 0x3 0x4 0x0 0x1 0x0 0x82
2019-07-07 23:08:59,543 MainThread      DEBUG    rtu_framer     :180      Getting Frame - 0x4 0x0 0x1 0x0 0x2
2019-07-07 23:08:59,544 MainThread      DEBUG    factory        :137      Factory Request[ReadInputRegistersRequest: 4]
2019-07-07 23:08:59,544 MainThread      DEBUG    rtu_framer     :115      Frame advanced, resetting header!!
2019-07-07 23:08:59,544 MainThread      DEBUG    context        :64       validate: fc-[4] address-2: count-2
2019-07-07 23:08:59,544 MainThread      DEBUG    context        :78       getValues fc-[4] address-2: count-2
2019-07-07 23:08:59,545 MainThread      DEBUG    sync           :143      send: [ReadRegisterResponse (2)]- b'030404000500050846'

ModbusSerialClient(rtu baud[115200])
2019-07-07 23:08:55,839 MainThread      DEBUG    pymodbus_sync_client_example_2019.07.05-1319:165      ===================================
2019-07-07 23:08:55,840 MainThread      DEBUG    pymodbus_sync_client_example_2019.07.05-1319:166      Read input registers
2019-07-07 23:08:55,841 MainThread      DEBUG    pymodbus_sync_client_example_2019.07.05-1319:167      
2019-07-07 23:08:55,842 MainThread      DEBUG    transaction    :111      Current transaction state - IDLE
2019-07-07 23:08:55,842 MainThread      DEBUG    transaction    :116      Running transaction 1
2019-07-07 23:08:55,843 MainThread      DEBUG    transaction    :215      SEND: 0x3 0x4 0x0 0x1 0x0 0x2 0x21 0xe9
2019-07-07 23:08:55,843 MainThread      DEBUG    sync           :79       New Transaction state 'SENDING'
2019-07-07 23:08:55,844 MainThread      DEBUG    sync           :538      GPIO - Setting pin high
2019-07-07 23:08:55,845 MainThread      DEBUG    sync           :541      GPIO - Setting pin low
2019-07-07 23:08:55,845 MainThread      DEBUG    transaction    :224      Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2019-07-07 23:08:59,516 MainThread      DEBUG    transaction    :300      Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
2019-07-07 23:08:59,518 MainThread      DEBUG    transaction    :229      RECV: 0x3 0x4 0x4 0x0 0x5 0x0 0x5 0x8 0x46
2019-07-07 23:08:59,519 MainThread      DEBUG    rtu_framer     :180      Getting Frame - 0x4 0x4 0x0 0x5 0x0 0x5
2019-07-07 23:08:59,519 MainThread      DEBUG    factory        :266      Factory Response[ReadInputRegistersResponse: 4]
2019-07-07 23:08:59,520 MainThread      DEBUG    rtu_framer     :115      Frame advanced, resetting header!!
2019-07-07 23:08:59,521 MainThread      DEBUG    transaction    :379      Adding transaction 3
2019-07-07 23:08:59,522 MainThread      DEBUG    transaction    :390      Getting transaction 3
2019-07-07 23:08:59,522 MainThread      DEBUG    transaction    :189      Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
ReadRegisterResponse (2)