c++ - Qt modbus串口流控制处理
问题描述
我正在通过串行端口(使用QModbusRtuSerialMaster
类)使用 QModbusDevice 编写一个小程序并且遇到了一些问题。
其中一个问题似乎是串口的流控不正确。检查串行端口嗅探器,我看到一个工作客户端在发送请求时将 RTS 设置为打开,然后 RTS 关闭以接收回复。当我QModbusRtuSerialMaster
用来发送不会发生的消息时。
与工作客户端相比,消息发送正确(有时是另一个问题的主题)。只是控制流不起作用,导致服务器无法回复。
我已将有问题的 COM 端口的 Windows 端口设置设置为硬件流控制,但没关系,嗅探器仍然报告没有流控制。
有没有办法QModbusRtuSerialMaster
按照我的意愿设置流量控制?或者有没有办法手动处理流量控制(这是工作客户端所做的)?或者是跳过Qt modbus类并直接使用串行端口组成我自己的唯一解决方案?
一个简短的总结我在做什么......
首先是对象的初始化QModbusRtuSerialMaster
:
QModbusDevice* modbusDevice = new QModbusRtuSerialMaster(myMainWindow);
modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter, "COM3");
modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::NoParity);
modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, QSerialPort::Baud115200);
modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
modbusDevice->setTimeout(100);
modbusDevice->setNumberOfRetries(3);
modbusDevice->connectDevice();
然后我如何发送请求:
auto response = modbusDevice->sendReadRequest(QModbusDataUnit(QModbusDataUnit::Coils, 0, 1), 1);
解决方案
QtModbus 没有实现 RTS 线路的自动切换,因为它希望您的硬件自行完成(使用专用线路代替)。
大多数 RS485 转换器(即使是便宜的)都应该是这种情况。如果您有一个像这样带有 DE/~RE 输入的单独收发器,则只需要 RTS 线。
如果你在 Linux 上并且有一些特定的硬件,你可以尝试使用RS485 模式来自动为你切换 RTS 线。但是您似乎不在 Linux 上,支持的硬件肯定非常有限。
您也可以使用 手动切换线路port.setRequestToSend(true)
,请参见此处。但请注意,根据您所说的设备的时间需求,此软件解决方案可能不是很可靠。这个特殊的问题已经在这里详细讨论过了。也看看我的答案中的链接,我用libmodbus做了一些基准测试,结果很好。
在驱动程序上启用或禁用流控制不会对此问题产生任何影响,因为这实际上不是流控制问题,而是方向控制问题。Modbus 经常在两线半双工链路上运行,这意味着您需要一种方法来指示始终允许哪个设备在总线上通话。来自 RS232 端口的 RTS(流控制)可用于此目的,作为软件解决方法。
最后,如果您只是将收发器替换为支持硬件方向控制的收发器,那就不会那么令人头疼了。如果您有一个带有 FTDI 引擎的串行端口,您应该能够为此目的使用 TXEN 线。有时,此硬件线路不是直接布线且可在引脚上使用,但您可以使用MProg重新布线。
我想强调一下,您没有提到您是否在 RS485 上运行 Modbus。我想假设你是公平的,但如果你只有几个彼此相邻的设备,你可能会使用 RS232(即使在 TTL 电平上)而忘记方向控制(你将使用三根线运行全双工:TX 、 RX 和 GND)。
推荐阅读
- javascript - How do I retrieve and assign a textbox value?
- python - ValueError: No gradients provided for any variable....in tensorflow V.2.1.0
- python - Return Name of first record df.iloc[0] using Python numpy
- java - Getting NotLeaderForPartitionException for a very long time
- java - Java MyBatis Freemarker 动态 SQL
- string - 在 asm x86-64 intel 语法中连接两个字符串
- java - 我可以将 java-grpc 用作库而不是框架吗?
- django - 使用自定义 AuthenticationForm 覆盖 Django LoginView 错误消息
- java - 在不冻结应用程序的情况下更新 TextView
- java - 如何解决java文件无法识别其xml文件