我无法从Arduino读取串行数据并将其发送到UI。我发现将所有串行数据拆分为3个单独的变量是一件麻烦事,因此使用左侧和中间来获取特定的数字。现在的问题是,我得到的数字保持不变,尽管我可以在LCD显示屏上看到它们发生变化 这是代码的一部分:
void Dolle::serialReceived(){
ba = serial->readAll();
serialBuffer += QString::fromStdString(ba.toStdString());
QString bufferSplit = serialBuffer;
QString hum = bufferSplit.left(2);
QString temp = bufferSplit.mid(2, 2);
QString gas = bufferSplit.mid(4, 4);
if((hum.size()==2) && (temp.size()==2) && (gas.size()==4)){
ui->humLabel->setText("Humidity: "+hum+" %");
ui->tempLabel->setText("Temperature: "+temp+(char(176))+ "C");
ui->gasLabel->setText("Gas level: "+gas);
qDebug() << hum << temp << gas;
}
}
答案 0 :(得分:1)
有几个问题:
您正在追加serialBuffer
,但您永远不会将其清空。 QIODevice
已经为您维护了一个可调整大小的内部循环缓冲区,因此不需要第二个缓冲区。
您将通过QString
从二进制表示转换为std::string
。这完全没必要。
您并未明确二进制数据中使用的字符编码。
重复更新用户界面,而不是每readyRead
个信号最多更新一次。
你正在使用魔法常数。您应该使用UTF-8编码您的源代码,或使用命名的QChar
常量。
您使用字符串运算符手动构建字符串,这会阻碍国际化和可维护性。
您正在使用空格作为一种机制来对齐UI中的显示。也许你应该以不同的方式设计你的UI,这样就不需要这样的黑客了。
我认为你的字符串是以某种方式分开的 - 也许每个都在一个单独的行中?在任何情况下,只要它们可用,您应该继续从设备读取完整的分隔字符串。对于行分隔数据,QIODevice::readLine
方法可以轻松实现:
void Dolle::serialReceived() {
QString validLine;
while (serial->canReadLine()) {
auto binLine = serial->readLine();
auto line = QString::fromLatin1(binLine);
if (line.length() < 8)
continue;
validLine = line;
}
if (validLine.isEmpty()) return;
auto hum = line.left(2);
auto temp = line.mid(2, 2);
auto gas = line.mid(4, 4);
ui->humLabel->setText(QStringLiteral("Humidity: %1%").arg(hum));
ui->tempLabel->setText(QStringLiteral("Temperature: %1°C").arg(temp));
ui->gasLabel->setText(QStringLiteral("Gas level: %1").arg(gas));
}
假设您的数据不是以行分隔的数据,而是以固定大小的块的形式到达。你会以类似的方式处理它们:
void Dolle::serialReceived() {
QString validPacket;
while (serial->bytesAvailable() >= 8) {
auto bin = serial->read(8);
auto packet = QString::fromLatin1(bin);
if (packet.length() < 8)
continue;
validPacket = packet;
}
...
}