QString编号在串行通信中保持不变

时间:2016-05-02 12:22:46

标签: c++ qt arduino

我无法从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;
  }
}

1 个答案:

答案 0 :(得分:1)

有几个问题:

  1. 您正在追加serialBuffer,但您永远不会将其清空。 QIODevice已经为您维护了一个可调整大小的内部循环缓冲区,因此不需要第二个缓冲区。

  2. 您将通过QString从二进制表示转换为std::string。这完全没必要。

  3. 您并未明确二进制数据中使用的字符编码。

  4. 重复更新用户界面,而不是每readyRead个信号最多更新一次。

  5. 你正在使用魔法常数。您应该使用UTF-8编码您的源代码,或使用命名的QChar常量。

  6. 您使用字符串运算符手动构建字符串,这会阻碍国际化和可维护性。

  7. 您正在使用空格作为一种机制来对齐UI中的显示。也许你应该以不同的方式设计你的UI,这样就不需要这样的黑客了。

  8. 我认为你的字符串是以某种方式分开的 - 也许每个都在一个单独的行中?在任何情况下,只要它们可用,您应该继续从设备读取完整的分隔字符串。对于行分隔数据,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;
      }
      ...
    }