Qt modbus串口流控处理 [英] Qt modbus serial port flow control handling

查看:113
本文介绍了Qt modbus串口流控处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a small program using QModbusDevice over the serial port (using the QModbusRtuSerialMaster class) and have some problems.

其中一个问题好像是串口的流量控制不对.检查串行端口嗅探器,我看到工作客户端在发送请求时将 RTS 设置为开启,然后将 RTS 关闭以接收回复.当我使用 QModbusRtuSerialMaster 发送不会发生的消息时.

One of the problems seems to be that the flow control of the serial port is incorrect. Checking in a serial port sniffer I see that a working client sets RTS on when it sends requests, and then RTS off to receive replies. When I use QModbusRtuSerialMaster to send messages that doesn't happen.

与工作客户端相比,消息发送正确(有时是另一个问题的主题).只是控制流不起作用,导致服务器无法回复.

The message is sent correctly (sometimes, subject for another question) compared to the working client. It's just the control flow that doesn't work and which causes the servers to be unable to reply.

我已经将有问题的 COM 端口的 Windows 端口设置设置为硬件流控制,但没关系,嗅探器仍然报告没有流控制.

I have set the Windows port settings for the COM-port in question to hardware flow control but it doesn't matter, the sniffer still reports no flow control.

有没有办法让 QModbusRtuSerialMaster 按照我的意愿设置流量控制?或者有没有办法手动处理流量控制(这是工作客户端所做的)?或者是跳过 Qt modbus 类并直接使用串口自行编写的唯一解决方案?

Is there a way to get QModbusRtuSerialMaster to set the flow control as I would like? Or is there a way to manually handle the flow control (which is what the working client does)? Or is the only solution to skip the Qt modbus classes and make up my own using the serial port directly?

我正在做的事情的简短摘要...

A short summary of what I'm doing...

首先初始化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 线路的自动切换,因为它希望您的硬件自行完成(而是使用专用线路).

QtModbus does not implement an automatic toggling for the RTS line because it expects your hardware to do it on its own (with a dedicated line instead).

大多数 RS485 转换器(甚至是便宜的转换器)都应该是这种情况.如果你有一个单独的收发器,比如 这个,你只需要 RTS 线 带有 DE/~RE 输入.

This should be the case for most RS485 converters (even cheap ones). You would only need the RTS line if you have a separate transceiver like this one with a DE/~RE input.

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

If you were on Linux and had some specific hardware you could try to use the RS485 mode to toggle the RTS line for you automatically. But you don't seem to be on Linux and the supported hardware is certainly very limited.

您也可以使用 port.setRequestToSend(true) 手动切换线路,请参阅 此处.但请注意,根据您所谈论的设备的时序需求,此软件解决方案可能不太可靠.这个特殊问题已经被详细讨论了 这里.也请查看我的答案中的链接,我使用 libmodbus 做了一些基准测试,结果显示效果不错.

You can also toggle the line manually with port.setRequestToSend(true), see here. But note that depending on the timing needs of the device you are talking too, this software solution might not be very reliable. This particular problem has been discussed at length here. Take a look at the links on my answer too, I made some benchmarks with libmodbus that show good results.

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

Enabling or disabling flow control on the driver won't have any effect on this issue because this is not actually a flow control problem but a direction control one. Modbus runs on two-wire half-duplex links very often, and that means you need a way to indicate which device is allowed to talk on the bus at all times. The RTS (flow control) from an RS232 port can be used for this purpose as a software workaround.

最后,如果您只将收发器替换为 一个,支持硬件方向控制.如果您有一个带有 FTDI 引擎的串行端口,您应该能够为此使用 TXEN 线.有时,此硬件线未直接布线且可在引脚上使用,但您可以使用 MProg 重新布线.

In the end, it would be much less of a headache if you just replace your transceiver with one that supports hardware direction control. If you have a serial port with an FTDI engine you should be able to use the TXEN line for this purpose. Sometimes this hardware line is not directly routed and available on a pin but you can reroute it with MProg.

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

I would like to highlight that you did not mention if you are running your Modbus on RS485. I guess it's fair to assume you are, but if you have only a couple of devices next to each other you might use RS232 (even on TTL levels) and forget about direction control (you would be running full-duplex with three wires: TX, RX and GND).

这篇关于Qt modbus串口流控处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆