【问题标题】:Communication Arduino-C++ do not read Arduino通讯 Arduino-C++ 不读Arduino
【发布时间】:2013-09-20 20:31:01
【问题描述】:

我有以下代码:

QSerialPort arduPort("COM5");
arduPort.setBaudRate(QSerialPort::Baud9600);
arduPort.setDataBits(QSerialPort::Data8);
arduPort.setParity(QSerialPort::NoParity);
arduPort.setStopBits(QSerialPort::OneStop);
arduPort.setFlowControl(QSerialPort::NoFlowControl);
arduPort.open(QSerialPort::ReadWrite);
cout<<arduPort.isReadable()<<endl;
cout<<arduPort.isWritable()<<endl;
arduPort.write("a");
QByteArray s=arduPort.readAll();

cout<<QString(s).toStdString()<<endl;

以及 Arduino 中的下一个代码:

int inByte = 0;

void setup()
{
    Serial.begin(9600);
    while(!Serial){;}
    int i=0;
}

void loop()
{
     if(Serial.read()=='a')
         Serial.write('b');  
}

首先我向 Arduino 发送一个“a”,ARduino 必须以“b”响应。但是当我阅读 Arduino 的端口时,我只收到 ''。

有人知道为什么我收到的是 '' 而不是 'b' 吗?感谢您的宝贵时间。

【问题讨论】:

  • 首先用IDE的串口监视器试试这个。完成此测试后,您将知道是 Arduino 代码还是您的 PC 代码是罪魁祸首。
  • 那么这不是 Arduino 问题,而是您的 C++ 代码的问题。由于您没有提供很多有关它的详细信息,因此没有千里眼的人将无法回答这个问题。显然,它必须与 QSerialPort 类以及您如何调用它有关。
  • 您需要哪些详细信息?
  • 您只能在打开端口后设置串口参数,就像原生操作一样。我们可以考虑为明年夏天的发布缓存它,但它对 Qt 5.1 来说太麻烦了。除非我遗漏了一些如何实现缓存的东西。诚然,我们可以更好地记录现状。我将尝试尽快对 gerrit 进行文档更改。 :) 以下是跟踪此案的相关报告:bugreports.qt-project.org/browse/QTBUG-33774 给您带来的不便深表歉意。

标签: c++ arduino qtserialport


【解决方案1】:

在 Qt 5.2 之前不太可能在打开之前设置端口。原因是原始设计对于该类来说太低级了,而该类是面向对象的。想了很久要不要改,最后还是决定改了。

我刚刚提交了一个更改,现在正在接受代码审查,这将使您的原始概念也可以工作。

您可以在这里找到详细信息:

Make it possible to set the port values before opening

可以在此处阅读更改摘要:

可以在打开之前设置端口值

这个补丁还改变了 open 方法的行为。我们不使用端口 检测不再为好。这是一个破碎的概念,而且非常 不太可能有人依赖它。如果有人这样做,他们会 无论如何都会遇到麻烦,不必要地收到嘈杂的警告等等。

另一个选项也被认为可以选择保留此行为作为 默认值,但这会使 API 过于复杂,但收益不大。

默认端口设置现在也是正常的 9600,8,N,1,并且没有流量控制。 另外请注意在open方法中串口是自动关闭的 如果任何设置失败。

请更新您的 Qt 版本(至少到 Qt 5.2),或者您可以自己向后移植更改。然后,可以编写此代码,实际上甚至推荐:

QSerialPort arduPort("COM5");
arduPort.setBaudRate(QSerialPort::Baud9600);
arduPort.setDataBits(QSerialPort::Data8);
arduPort.setParity(QSerialPort::NoParity);
arduPort.setStopBits(QSerialPort::OneStop);
arduPort.setFlowControl(QSerialPort::NoFlowControl);
arduPort.open(QSerialPort::ReadWrite);

【讨论】:

  • lpapp,我没有投反对票,该评论是 SO 审查过程的结果,当我审查它时,它是关于您提交的更改请求的两句话,第二句话是是链接(现在是您当前答案的第 2-4 段),在我看来 没有 回答问题(仅链接的原因不是我的,而是 Makyen 的,并且答案应该是独立的尽可能)。所以我没有反对意见可以删除,但是,鉴于您现在在答案中提供了更多的肉,它看起来更好。
【解决方案2】:

波特率:这不是 QT 设置的!!!!!!!原来你只能设置 打开端口后的波特率..否则它会留在 第一次插入电缆时的值为 0。

是的,这是真的。但它已被修复,将在 Qt 5.3 中提供

fDtrControl:Putty 设置为 1,Qt 设置为 0。

没有。 Qt 在打开时不要触摸 DTR 信号。该信号只有在设置为 DTR_CONTROL_HANDSHAKE 时才会被清除。因为 QtSerialPort 不支持 DTR/DSR 流控制。因此,无论如何,您都可以通过 QSerialPort::setDataTerminalReady(bool) 来控制 DTR。

PS:我的意思是当前的 Qt 5.3 版本

fOutX 和 fInX:两者都被 Putty 设置为 1,被 Qt 设置为 0。

该标志仅在您使用 QSerialPort::Software 流控制 (Xon/Xoff) 时使用。但是您使用的是 QSerialPort::NoFlowControl (我可以从您的代码 sn-p 中看到),所以,好吧。因此,请检查您是否也将 Putty 与“无”流控制一起使用。

在设置所有参数时,我认为最好 将错误策略设置为“跳过”。

请仅使用 QSerialPort::Ignore 策略(默认)。因为其他政策已被弃用(所有政策),并且将来会被删除。

更新:

dcb.fRtsControl = RTS_CONTROL_ENABLE;

啊,您的 Arduino 似乎希望 RTS 信号默认启用。在这种情况下,您应该使用 QSerialPort::setRequestToSend(bool)。但只有在 QSerialPort::NoFlowControl 模式下才有可能。

即打开端口后,RTS 将始终处于 RTS_CONTROL_DISABLE 或 RTS_CONTROL_HANDSHAKE(取决于您的 FlowControl 设置, QSerialPort::setFlowControl() )。

【讨论】:

    【解决方案3】:

    更新:请参阅此答案的底部以获取答案。 TL;DR:您已经设置了波特率(以及可能所有其他设置)在您打开之后港口。

    我相信这是 QSerialPort 的 Windows 实现中的一个错误。我还不能确定原因,但我有以下症状:

    1. 使用 ASCII 演示加载 Arduino(在我的例子中是 Uno;Leonardo 的行为可能非常不同)。拔下并重新插入 Arduino。请注意,TX 灯不亮。

    2. 使用 Putty 或 Arduino 串口监视器连接到它。这会重置 Arduino,然后打印 ASCII 表。 TX 灯按预期持续亮起。

    3. 拔下/重新插入 Arduino,这次使用 QSerialPort 程序连接到它。这一次,尽管端口打开正常,但 TX 灯永远不会亮起,并且永远不会触发 readyRead()。另请注意,Arduino 未重置,因为默认情况下 QSerialPort 不会更改 DTR。如果您执行QSerialPort::setDataTerminalReady(false); 然后暂停 10 毫秒然后设置它true按预期重置 Arduino,但它仍然不传输。

    4. 请注意,如果您有一个连续传输数据的 Arduino 程序(ASCII 示例停止),如果您使用 putty 打开端口使其开始传输,然后使用 QSerialPort 打开它而不拔掉电缆它会工作的!但是,一旦您拔下/插入电缆,它就会再次停止工作。

    这让我怀疑腻子正在设置一些 arduino 所需的串行端口选项,并在您重新插入电缆时重置。 QSerialPort 显然不会改变这个值。

    据我所知,这是 Putty 使用的设置:

    dcb.fBinary = TRUE;
    dcb.fDtrControl = DTR_CONTROL_ENABLE;
    dcb.fDsrSensitivity = FALSE;
    dcb.fTXContinueOnXoff = FALSE;
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;
    dcb.fErrorChar = FALSE;
    dcb.fNull = FALSE;
    dcb.fRtsControl = RTS_CONTROL_ENABLE;
    dcb.fAbortOnError = FALSE;
    dcb.fOutxCtsFlow = FALSE;
    dcb.fOutxDsrFlow = FALSE;
    dcb.Parity = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
    dcb.BaudRate = ...;
    dcb.ByteSize = ...;
    

    QSerialPort:

    dcb.fBinary = TRUE;
    dcb.fDtrControl = unchanged!
    dcb.fDsrSensitivity = unchanged!
    dcb.fTXContinueOnXoff = unchanged!
    dcb.fOutX = FALSE;
    dcb.fInX = FALSE;
    dcb.fErrorChar = FALSE;
    dcb.fNull = FALSE;
    dcb.fRtsControl = RTS_CONTROL_DISABLE;
    dcb.fAbortOnError = FALSE;
    dcb.fOutxCtsFlow = FALSE;
    dcb.fOutxDsrFlow = unchanged!
    dcb.Parity = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
    dcb.BaudRate = ...;
    dcb.ByteSize = ...;
    

    所以我认为它一定是那些使 Arduino 认为它没有连接的未更改值之一。来自DCB documentation 我怀疑fTxContinueOnXoff

    好的,我要写一个小程序来读取这些设置,看看有什么变化。

    更新 1

    好的,我编写了我的程序并做出了以下发现。运行 putty 和我的 Qt 程序后的区别是:

    • 波特率:这不是 QT 设置的!!!!!!! 事实证明,您只能在打开端口后设置波特率。。否则,当您第一次插入电缆时,它会保留为之前的值 0。
    • fDtrControl:Putty 设置为 1,Qt 设置为 0。
    • fOutX 和 fInX:两者都被 Putty 设置为 1,被 Qt 设置为 0。

    在打开后移动我所有的set...() 函数调用后,它运行良好。我不必摆弄 DtrControl 或 Out/InX。 (虽然我也手动将 DTR 设置为高。)

    更新 2

    在设置所有参数时,我认为将错误策略设置为“跳过”是个好主意。不要这样做!忽略它!否则,它会搞砸一切,并为您的所有通信增加奇怪的延迟。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多