c++ - Qt modbus串口流控处理

标签 c++ windows qt modbus

我正在通过串行端口使用 QModbusDevice 编写一个小程序(使用 QModbusRtuSerialMaster 类)并且遇到了一些问题。

其中一个问题好像是串口的流控不对。检查串行端口嗅探器,我看到工作客户端在发送请求时将 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 转换器(即使是便宜的)都应该是这种情况。如果你有一个单独的收发器,比如 this one,你只需要 RTS 线。带有 DE/~RE 输入。

如果您使用的是 Linux 并且有一些特定的硬件,您可以尝试使用 RS485 mode自动为您切换 RTS 线路。但你似乎不在 Linux 上,支持的硬件肯定非常有限。

您也可以使用 port.setRequestToSend(true) 手动切换线路,参见 here .但请注意,根据您正在通话的设备的时间需求,此软件解决方案可能不是很可靠。这个特殊问题已被详细讨论 here .也看看我的答案中的链接,我用 libmodbus 做了一些基准测试,结果很好。

在驱动程序上启用或禁用流量控制不会对此问题产生任何影响,因为这实际上不是流量控制问题,而是方向控制问题。 Modbus 经常在双线半双工链路上运行,这意味着您需要一种方法来指示允许哪个设备始终在总线上通话。来自 RS232 端口的 RTS(流量控制)可作为软件变通方案用于此目的。

最后,如果您将收发器替换为 one 就不会那么令人头疼了。支持硬件方向控制。如果你有一个带有 FTDI 引擎的串口,你应该可以使用 TXEN 线来达到这个目的。有时,此硬件线未直接路由且在引脚上可用,但您可以使用 MProg 重新路由它。 .

我想强调一下,您没有提到您是否在 RS485 上运行 Modbus。我想假设你是公平的,但如果你只有几个设备彼此相邻,你可能会使用 RS232(即使在 TTL 电平上)而忘记方向控制(你将使用三根线运行全双工:TX , RX 和 GND)。

关于c++ - Qt modbus串口流控处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57732275/

相关文章:

c++ - 如何比较和删除 3 个 vector 之间不具有相同值的元素?

c++ - 使用 set_union 和 set_intersection 时出错

linux - Linux 发行版上的 windeployqt.exe

C++ - 静态数组的性能,启动时大小可变

c++ - 使用临时函数对象进行全局初始化

c - 如何从 x86_64 windows 异常处理程序中正确调用 rtlunwind

c++ - TranslateColors() RGB 和 CMYK 的颜色范围

c - 在 Ruby 中运行已编译的 C 文件是否会捕获 C 的 printf()?

c++ - 是否可以将一个类的插槽或常规函数连接到另一个类的插槽或常规函数? (QT)

qt - 在Windows中在没有命令提示符的情况下在QT中启动外部进程