Qt modbus串口流控处理

2024-01-25

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

问题之一似乎是串口的流量控制不正确。检查串行端口嗅探器时,我发现工作客户端在发送请求时打开 RTS,然后关闭 RTS 以接收回复。当我使用QModbusRtuSerialMaster发送未发生的消息。

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

我已将相关 COM 端口的 Windows 端口设置设置为硬件流量控制,但这并不重要,嗅探器仍然报告没有流量控制。

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


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

首先是初始化QModbusRtuSerialMaster object:

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 https://hobbycomponents.com/wired-wireless/663-max485-rs485-transceiver-module带 DE/~RE 输入。

如果您使用的是 Linux 并且有一些特定的硬件,您可以尝试使用RS485方式 https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/Documentation/serial/serial-rs485.txt?h=v5.1.7自动为您切换 RTS 线路。但你似乎不在 Linux 上,支持的硬件肯定非常有限。

您还可以使用以下命令手动切换线路port.setRequestToSend(true), see here https://stackoverflow.com/questions/40042099/serial-comms-not-working-through-qserialport-qt-but-is-working-via-terminal-t。但请注意,根据您正在谈论的设备的计时需求,该软件解决方案可能不太可靠。这个特殊问题已经被详细讨论过here https://stackoverflow.com/questions/56922031/modbus-error-invalid-message-incomplete-message-received-expected-at-least-2/56923891#56923891。也看看我的答案上的链接,我做了一些基准测试libmodbus显示出良好的结果。

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

最后,如果您只需将收发器替换为one https://rads.stackoverflow.com/amzn/click/com/B07BJJ7ZF8支持硬件方向控制。如果您有一个带有 FTDI 引擎的串行端口,您应该能够使用 TXEN 线来实现此目的。有时,该硬件线路不是直接布线且在引脚上可用,但您可以使用以下命令重新布线MProg https://www.ftdichip.com/Support/Utilities.htm#MProg.

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt modbus串口流控处理 的相关文章

  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 在 Xamarin 中隐藏软键盘

    如何隐藏软键盘以便在聚焦时显示Entry在 Xamarin forms 便携式表单项目中 我假设我们必须为此编写特定于平台的渲染器 但以下内容不起作用 我创建自己的条目子类 public class MyExtendedEntry Entr
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 找不到 assimp-vc140-mt.dll ASSIMP

    我已经从以下位置下载了 Assimp 项目http assimp sourceforge net main downloads html http assimp sourceforge net main downloads html Ass
  • C++ php 和静态库

    我创建了一个library a 其中包含 cpp 和 h 文件 其中包含很多类 嵌套类和方法 我想在 php 示例中包含这个静态库并尝试使用它 我想提一下 我是 php 新手 我已经在 test cpp 文件中测试了我的 libray a
  • 给出 5 个参数,但在终端中只得到 3 个参数

    我想将一个文件传递给一个c 程序 如果我在 IDE 中执行此操作 test string string lt test txt return argc 5 但在终端上我刚刚得到argc 3 看来 这是因为 什么是 lt 意思是 我正在使用
  • 如何在标准 WPF ListView 中启用 UI 虚拟化

    我正在使用 NET 4 5 VS2012 并且我有一个 ListView 看起来像这样
  • 运行选定的代码生成器时出错:“未将对象引用设置到对象的实例。”错误?

    我已经尝试了所有解决方案 例如修复 VS 2013 但没有用 当您通过右键单击控制器文件夹来创建控制器并添加控制器时 然后右键单击新创建的控制器的操作并选择添加视图 当我尝试创建视图时 就会发生这种情况 它不是一个新项目 而是一个现有项目
  • 如何在c的case语句中使用省略号?

    CASE expr no commas ELLIPSIS expr no commas 我在c的语法规则中看到了这样的规则 但是当我尝试重现它时 int test float i switch i case 1 3 printf hi 它失
  • .NET Core 中的跨平台文件名处理

    如何处理文件名System IO以跨平台方式运行类以使其在 Windows 和 Linux 上运行 例如 我编写的代码在 Windows 上完美运行 但它不会在 Ubuntu Linux 上创建文件 var tempFilename Dat
  • 我可以让 ungetc 取消阻止阻塞的 fgetc 调用吗?

    我想在收到 SIGUSR1 后使用 ungetc 将 A 字符重新填充到标准输入中 想象一下我有充分的理由这样做 调用 foo 时 stdin 中的阻塞读取不会被收到信号时的 ungetc 调用中断 虽然我没想到它会按原样工作 但我想知道是
  • IEnumerable.Except 不起作用,那么我该怎么办?

    我有一个 linq to sql 数据库 非常简单 我们有 3 个表 项目和用户 有一个名为 User Projects 的连接表将它们连接在一起 我已经有了一个获得的工作方法IEnumberable
  • 了解使用 Windows 本机 WPF 客户端进行 ADFS 登录

    我已经阅读了大量有关 ADFS 与 NodeJS Angular 或其他前端 Web 框架集成以及一般流程如何工作的文献 并通过 Auth0 Angular 起始代码构建了概念证明 但我不明白如何这可以与本机 WPF Windows 应用程
  • 如何获取Windows批处理的父文件夹

    我正在编写一个批处理文件 我需要获取该bat文件的父文件夹 有可能吗 注意 我的意思是批处理文件的父文件夹 而不是调用该批处理的提示的当前目录 Thanks 批处理的父文件夹位于变量中 dp0位于 例子 echo off setlocal
  • 如何在 DropDownList 中保留空格 - ASP.net MVC Razor 视图

    我在视图中通过以下方式绑定我的模型 问题是我的项目文本是格式化文本 单词之间有空格 如下所示 123 First 234 00 123 AnotherItem 234 00 123 Second 234 00 我想保留此项目文本中的空格 即
  • C++0x中disable_if在哪里?

    Boost 两者都有enable if and disable if 但 C 0x 似乎缺少后者 为什么它被排除在外 C 0x 中是否有元编程工具允许我构建disable if按照enable if 哦 我刚刚注意到std enable i
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用
  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁

随机推荐