【发布时间】:2016-03-20 16:32:52
【问题描述】:
所以,我已经构建了一个基本的 QT GUI,我想通过 USB 与 Arduino Nano 建立通信。我通过 GUI 发送一个数字,Arduino 接收该数字并处理它。
当我将代码上传到 Arduino 并立即打开 GUI 并开始进程时,通信工作正常。但是,当我将 Arduino 与 USB 断开连接(或重新启动我的 PC - 我都尝试过)并重新连接它以将其与 GUI 一起使用时,Arduino 的行为就像它什么也没收到一样。
更具体地说,在第一种情况下,Serial.available() 在正确接收数字时返回“1”,但在后一种情况下,它返回“0”,因此它什么也不做。
我尽可能简化了代码,试图找出问题所在,但问题仍然存在。
所以这里是主要的 QT GUI 代码:
depth_ = insertDepthEdit->text().toInt(); // user input from GUI
myThread *mThread;
mThread = new myThread(this, depth_);
connect(mThread, SIGNAL(valueRead(QString)), this, SLOT(onTextChange(QString)));
//valueRead is the signal emitted from Arduino
//onTextChange the function that processes the received string
mThread->start();
mThread->wait(100);
mThread->quit();
Arduino 线程代码(也是 QT):
void myThread::run() {
QSerialPort serial;
serial.setPortName("COM3");
serial.setBaudRate(QSerialPort::Baud9600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
serial.open(QIODevice::ReadWrite);
if (serial.isOpen() && serial.isWritable()) {
qDebug() << "Ready to write..." << endl;
QByteArray ba(QString::number(depth_).toStdString().c_str());
qDebug() << ba << endl;
serial.write(ba);
if (serial.bytesToWrite() > 0) {
serial.flush();
if (serial.waitForBytesWritten(1000)) {
qDebug() << "data has been sent" << endl;
}
}
if (serial.flush()) {
qDebug() << "ok" << endl;
}
}
else {
qDebug() << "Error";
}
if (serial.isOpen() && serial.isReadable()) {
qDebug() << "Ready to read..." <<endl;
while (serial.waitForReadyRead(5000)) {
QByteArray inByteArray = serial.readLine();
input_ = QString(inByteArray);
qDebug() << input_;
qDebug() << "ok" << endl;
emit valueRead(input_);
}
}
serial.close();
}
最后是 Arduino 代码:
int c = 0;
const int ledPin = 13;
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.print(Serial.available());
while (Serial.available() > 0) {
digitalWrite(ledPin, HIGH);
delay(5);
c = Serial.read() - '0';
Serial.flush();
}
delay(1000);
digitalWrite(ledPin, LOW);
delay(500);
}
当我将代码上传到 Arduino 时,无论我关闭 GUI 并重新启动它,它都能正常运行。仅当 Arduino 断电时才会出现此问题,例如:当我将其从 USB 断开或重新启动 PC 时。
~~~~~~~~~~~~~~~~~~~~~~~~~~编辑~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~
重新连接后COM端口保持不变,当我通过GUI发送数据时,Arduino Rx LED正常闪烁。
~~~~~~~~~~~~~~~~~~~~~~~~~~编辑2~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~
好的,所以,我尝试使用 Arduino 串行文档中的代码,但问题仍然存在。当我上传代码时,Arduino 正确接收字符并打开 LED,但是一旦我断开它然后重新连接它,它什么也不做,LED 保持低电平,因为它永远不会进入“if”。
这是我使用的代码:
int incomingByte = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
digitalWrite(13, HIGH);
incomingByte = Serial.read();
}
}
~~~~~~~~~~~~~~~~~~~~~~编辑3~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
所以我有以下3种情况:
使用场景 A:
- 上传代码
- 运行图形界面
- 发送数据 - 正确接收
- 断开并重新连接
- 再次运行 GUI
- 发送数据 - RX 闪烁但 Serial.available 返回 0
使用场景 B:
- 上传代码
- 跑布雷斯
- 发送数据 - 正确接收
- 断开并重新连接
- 再次运行 Brays
- 发送数据 - 正确接收
使用场景C(最有趣的):
- 上传代码
- 运行图形界面
- 发送数据 - 正确接收
- 断开并重新连接
- 这次跑布雷斯
- 发送数据 - 正确接收
- 在 Brays 之后再次运行 GUI
- 发送数据 - 正确接收
我也把 QT GUI 代码弄得这么简单,但问题依然存在:
void myThread::run()
{
QSerialPort *serial = new QSerialPort();
serial->setPortName("COM3");
serial->setBaudRate(QSerialPort::Baud9600);
serial->setDataBits(QSerialPort::Data8);
serial->open(QIODevice::WriteOnly);
if (serial->isOpen() && serial->isWritable())
{
QByteArray ba(QString::number(depth_).toStdString().c_str());
serial->write(ba);
serial->flush();
serial->close();
}
delete serial;
}
~~~~~~~~~~~~~~~~~~~~~~编辑4~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
经过一番努力和好奇,我意识到问题的根源不是 Arduino 代码,而是与 QT 或 Windows 有关的东西。我添加了 Jeff 推荐的延迟,并注意到每次它正常运行时,Rx 都会闪烁并且 LED 变高,如代码所示。但是,重新连接后,问题仍然存在,但我注意到,这一次,在单击“发送”发送字符后,LED 闪烁了几毫秒(可能表示错误??)和然后在 1 秒延迟后,Rx 闪烁表示接收到数据,LED 保持低电平,因为 Serial.available 保持为 0。
所以,我接下来尝试的是一次删除一行代码,看看是什么导致了问题。最后我得到了真正空白的 Arduino 代码,只是空的设置和循环方法,以及以下 QT GUI 代码:
void myThread::run()
{
QSerialPort *serial1 = new QSerialPort();
serial1->setPortName("COM5");
serial1->open(QIODevice::WriteOnly);
serial1->close();
}
总而言之,现在发生的事情是:
- 上传代码到 Arduino
- 运行图形界面
- 发送数据
- 什么都没有发生(正常行为)
- 断开 Arduino 与 USB 的连接并重新连接
- 运行图形界面
- 发送数据
- Arduino LED 瞬间闪烁一次(可能表示某种错误)
【问题讨论】:
-
Arduino LED 是否闪烁表示正在接收数据?
-
是的,它正常闪烁,即使在重新连接后也是如此。只有 serial.available() 返回 0。
-
你从 Arduino 得到什么输出?
-
对不起,当我说LED闪烁时,我的意思是Rx LED闪烁,当我发送数据时。正确的 LED,连接在数字引脚 13 上的那个,我在上面的代码中定义为“ledpin”不会闪烁,因为它永远不会变成高电平,因为它永远不会进入 while 循环,变量 c 保持为零。关于您建议的答案,我会尝试您发布的代码并尽快发布有关情况的更新。
-
为什么从“COM3:”变成了“COM5:”?另外,我注意到只有您的第一个示例设置了 Data8、OneStop 和 NoParity。您需要在打开端口时设置所有参数,否则它们可能会停留在最后的设置或随机设置。如果字符的长度或奇偶校验不正确,Arduino 可能会忽略它。
标签: c++ qt arduino serial-port