【发布时间】:2019-01-18 03:20:57
【问题描述】:
我正在编写一个 Qt GUI 应用程序,它通过串行接收数据并将数据发送到 Arduino。它可以正确写入,但是在尝试读取时它不起作用。
我的问题是:
我有一个通过串行发送东西的 Arduino 代码,我对其进行了编程以根据接收到的数据打开和关闭引脚 13 上的 LED:
#define ARDUINO_TURNED_LED_ON "LEDON"
#define ARDUINO_TURNED_LED_OFF "LEDOFF"
#define PC_REQUESTED_LED_STATE_CHANGE u8"CHANGELED"
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(13, OUTPUT);
}
String serialCmd = "";
bool ledState=false;
void loop()
{
// put your main code here, to run repeatedly:
if (Serial.available())
{
serialCmd=Serial.readString();
if (serialCmd==PC_REQUESTED_LED_STATE_CHANGE)
{
if (ledState)
{
digitalWrite(13, LOW);
Serial.write(ARDUINO_TURNED_LED_OFF);
}
else
{
digitalWrite(13, HIGH);
Serial.write(ARDUINO_TURNED_LED_ON);
};
ledState=!ledState;
serialCmd = "";
}
}
}
我在 MainWindow 类中使用以下信号和槽:
#define ARDUINO_TURNED_LED_ON "LEDON"
#define ARDUINO_TURNED_LED_OFF "LEDOFF"
#define PC_REQUESTED_LED_STATE_CHANGE u8"CHANGELED"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/* Create Object the Class QSerialPort*/
serialPort = new QSerialPort(this);
/* Create Object the Class Arduino to manipulate read/write*/
arduino = new Arduino(serialPort);
//connect signal:
connect(serialPort, SIGNAL(readyRead()), this, SLOT(ReadData()));
}
//slot
void MainWindow::ReadData()
{
QString received = arduino->Read();
qDebug() << "received data:" << received;
if (received==ARDUINO_TURNED_LED_ON)
{
qDebug() << "led on";
}
else if (received==ARDUINO_TURNED_LED_OFF)
{
qDebug() << "led off";
}
}
还有上一个槽调用的Arduino::Read()方法:
QString Arduino::Read()
{
QString bufRxSerial;
qDebug() << "bytes available:" << serialPort->bytesAvailable();
/* Awaits read all the data before continuing */
while (serialPort->waitForReadyRead(20)) {
bufRxSerial += serialPort->readAll();
}
return bufRxSerial;
}
当写入 Arduino 时,它运行良好,LED 会发生变化,当 Qt 尝试读取回复的数据时会出现问题。
在大多数情况下,Arduino 发送一些东西,发出信号并且 serialPort->bytesAvailable() 返回一个不为零的数字,但 serialPort->waitForReadyRead(20) 超时而没有收到任何内容,并且 serialPort->readAll() 返回一个空的 QString。如果我使用 serialPort->waitForReadyRead(-1) 窗口将冻结。
最奇怪的是,在一个随机的时刻,发送了一些东西,一切正常,函数返回了所有之前无法读取的数据。
下面是一个例子:
第一次尝试(失败)
Qt 将 PC_REQUESTED_LED_STATE_CHANGE (u8"CHANGELED") 写入串口
Arduino LED 改变其状态(打开)
Arduino 将 ARDUINO_TURNED_LED_ON ("LEDON") 写入串口
Qt 从 Arduino 读取一个空的 QString
第二次尝试(失败)
Qt 将 PC_REQUESTED_LED_STATE_CHANGE (u8"CHANGELED") 写入串口
Arduino LED 改变其状态(关闭)
Arduino 将 ARDUINO_TURNED_LED_OFF ("LEDOFF") 写入串口
Qt 从 Arduino 读取一个空的 QString
第三次尝试(这是随机尝试,一切正常)
Qt 将 PC_REQUESTED_LED_STATE_CHANGE (u8"CHANGELED") 写入串口
Arduino LED 改变其状态(打开)
Arduino 将 ARDUINO_TURNED_LED_ON ("LEDON") 写入串口
Qt 从 Arduino 读取“LEDONLEDOFFLEDON”,这是以前无法读取的所有内容。
第四次尝试(失败)
Qt 将 PC_REQUESTED_LED_STATE_CHANGE (u8"CHANGELED") 写入串口
Arduino LED 改变其状态(关闭)
Arduino 将 ARDUINO_TURNED_LED_OFF ("LEDOFF") 写入串口
Qt 从 Arduino 读取一个空的 QString
第 5 次尝试(这是另一个随机尝试,一切正常)
Qt 将 PC_REQUESTED_LED_STATE_CHANGE (u8"CHANGELED") 写入串口
Arduino LED 改变其状态(打开)
Arduino 将 ARDUINO_TURNED_LED_ON ("LEDON") 写入串口
Qt 从 Arduino 读取“LEDOFFLEDON”,这是以前无法读取的所有内容。
我使用 Arduino IDE 串行监视器进行了测试,它按预期工作:我写了“CHANGELED”,然后 LED 变了,Arduino 一直回复“LEDON”或“LEDOFF”。
我可以做些什么来解决这个问题? 谢谢
编辑:完整代码可见here
【问题讨论】:
-
为什么在
serialPort->waitForReadyRead(20)中有20? -
bool QSerialPort::waitForReadyRead(int msecs = 30000):此函数阻塞,直到有新数据可供读取并且已发出 readyRead() 信号。该函数将在 mssecs 毫秒后超时;默认超时为 30000 毫秒。如果 msecs 为 -1,则此函数不会超时。如果发出了 readyRead() 信号并且有新数据可供读取,则该函数返回 true;否则返回 false(如果发生错误或操作超时)。
-
好的,你可以提供一个minimal reproducible example,你的代码应该是最少的但也是完整的
-
对不起,我会尽快编辑并放一个完整的代码
-
请提供更多代码。
标签: c++ qt arduino qt5 qtserialport