更新:请参阅此答案的底部以获取答案。TL;DR:您在打开端口后设置了波特率(可能还有其他所有设置) 。
我相信这是 QSerialPort 的 Windows 实现中的一个错误。我还不能缩小原因,但我有以下症状:
使用 ASCII 演示加载 Arduino(在我的情况下为 Uno;Leonardo 的行为可能非常不同)。拔下并重新插入 Arduino。请注意,TX 灯不亮。
使用 Putty 或 Arduino 串行端口监视器连接到它。这会重置 Arduino,然后打印 ASCII 表。TX 灯按预期持续亮起。
拔下/重新插入 Arduino,这次使用 QSerialPort 程序连接到它。这一次,尽管端口打开正常,但 TX 灯永远不会亮起,readyRead()
也永远不会被触发。另请注意,Arduino 未重置,因为默认情况下 QSerialPort 不会更改 DTR。如果你这样做了,QSerialPort::setDataTerminalReady(false);
然后暂停 10 毫秒,然后设置它true
,它将按预期重置 Arduino,但它仍然不传输。
请注意,如果您有一个连续传输数据的 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 文档fTxContinueOnXoff
中。
好的,我将编写一个小程序来读取这些设置并查看发生了什么变化。
更新 1
好的,我编写了我的程序并做出了以下发现。运行 putty 和我的 Qt 程序后的区别是:
- 波特率:这不是 QT 设置的!!!!!!!!!事实证明,您只能在打开端口后设置波特率。. 否则,当您第一次插入电缆时,它会保留为先前的值 0。
- fDtrControl:Putty 设置为 1,Qt 设置为 0。
- fOutX 和 fInX:两者都被 Putty 设置为 1,被 Qt 设置为 0。
在打开后移动我所有的set...()
函数调用后,它工作得很好。我不必摆弄 DtrControl 或 Out/InX。(虽然我也手动将 DTR 设置为高。)
更新 2
在设置所有参数时,我认为将错误策略设置为“跳过”是个好主意。不要这样做!忽略它!否则,它会搞砸一切,并为您的所有通信增加奇怪的延迟。