C++ 从序列号&;分别保存值

C++ 从序列号&;分别保存值,c++,qt,C++,Qt,使用Arduino,我打印一个整数和一个浮点,如下所示(我在循环中执行): 另一方面,我使用Qt的“QSerialPort”读取串行数据,如下所示: serial.setPortName("COM3"); serial.open(QIODevice::ReadWrite); serial.setBaudRate(QSerialPort::Baud9600); serial.setDataBits(QSerialPort::Data8); serial.setParity(QSerialPort:

使用Arduino,我打印一个整数和一个浮点,如下所示(我在循环中执行):

另一方面,我使用Qt的“QSerialPort”读取串行数据,如下所示:

serial.setPortName("COM3");
serial.open(QIODevice::ReadWrite);
serial.setBaudRate(QSerialPort::Baud9600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);

while(!serial.isOpen()) serial.open(QIODevice::ReadWrite);

if (serial.isOpen() && serial.isWritable()){
QByteArray input, input1;

std::chrono::seconds interval(1);
for (int i = 0; i < 3; ++i){        \\Read from serial for 3 seconds
    serial.waitForBytesWritten(250);
    serial.waitForReadyRead(250);
    Sleep(490);
    input = serial.readAll();       \\First value
    }


    serial.waitForBytesWritten(250);
    serial.waitForReadyRead(250);
    Sleep(490);
    input1 = serial.readAll();      \\Second value
}
serial.setPortName(“COM3”);
serial.open(QIODevice::ReadWrite);
串行.setBaudRate(QSerialPort::Baud9600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
串行.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
而(!serial.isOpen())serial.open(QIODevice::ReadWrite);
if(serial.isOpen()&&serial.isWritable()){
QByteArray输入,输入1;
标准时间间隔:秒间隔(1);
对于(int i=0;i<3;++i){\\3秒从串行读取
序列号。WaitforBytesWrite(250);
序列号:waitForReadyRead(250);
睡眠(490);
输入=serial.readAll();\\第一个值
}
序列号。WaitforBytesWrite(250);
序列号:waitForReadyRead(250);
睡眠(490);
input1=serial.readAll();\\第二个值
}

问题是“读取器”有时先读取“tempSensor”,然后读取“LDRSensor”,有时反之亦然。我可以将“QSerialPort”设置为始终先接收tempSensor,然后再接收LDRSensor,这样我就可以将它们分别保存在不同的阵列中吗?

我想说,您的主要问题是,在发送数据时,您没有澄清数据。我建议您将数据打包成一条消息,带有一个标题和校验和(尽管老实说,校验和并不是必需的)

我建议发送(按此顺序):

  • 一个字节,用于指定消息的总大小(以字节为单位)
  • 用于指定这是温度读数还是LDR传感器读数的字节
  • 包含传感器值的int
  • 表示消息结束的字节,或校验和
如果你真的想保持简单,你可以放弃第一个和最后一个字节。消息大小可能总是5个字节,考虑到它的规则性和低干扰概率,校验和实际上是不必要的


然后,您所要做的就是在消息到达时对其进行解释,您的程序将知道到达的是什么类型的数据以及如何处理它。如果你仅仅依靠计时,你总是有失去同步的风险。

我认为你的主要问题是你没有在发送数据时澄清数据。我建议您将数据打包成一条消息,带有一个标题和校验和(尽管老实说,校验和并不是必需的)

我建议发送(按此顺序):

  • 一个字节,用于指定消息的总大小(以字节为单位)
  • 用于指定这是温度读数还是LDR传感器读数的字节
  • 包含传感器值的int
  • 表示消息结束的字节,或校验和
如果你真的想保持简单,你可以放弃第一个和最后一个字节。消息大小可能总是5个字节,考虑到它的规则性和低干扰概率,校验和实际上是不必要的


然后,您所要做的就是在消息到达时对其进行解释,您的程序将知道到达的是什么类型的数据以及如何处理它。如果你仅仅依靠计时,你总是有失去同步的风险。

我会说得很简单。您可以尝试在发送端执行以下操作:

Serial.print('T');        //start of the temperature message
Serial.print(tempSensor); //temp value
Serial.print('\n');       //end of line

Serial.print('L');        //start of the LDR message
Serial.print(LDRSensor);  //LDR value
Serial.print('\n');       //end of line

delay(1000);
在接受方:

while (your condition)
{
    while (serial.canReadLine())
    {
        QString message = serial.readLine();
        message = message.trimmed();     //remove the end of line character
        QString strVal = message.mid(1); //remove the first character
        int value = strVal.toInt();      //convert to int

        if (message.startsWith("T"))
        {
            // Temp received
        }
        else if (message.startsWith("L"))
        {
            // LDR received
        }
    }
    Sleep(10);
}

但我绝对建议你不要在一个周期内阅读,而是使用信号。

我会让它变得非常简单。您可以尝试在发送端执行以下操作:

Serial.print('T');        //start of the temperature message
Serial.print(tempSensor); //temp value
Serial.print('\n');       //end of line

Serial.print('L');        //start of the LDR message
Serial.print(LDRSensor);  //LDR value
Serial.print('\n');       //end of line

delay(1000);
在接受方:

while (your condition)
{
    while (serial.canReadLine())
    {
        QString message = serial.readLine();
        message = message.trimmed();     //remove the end of line character
        QString strVal = message.mid(1); //remove the first character
        int value = strVal.toInt();      //convert to int

        if (message.startsWith("T"))
        {
            // Temp received
        }
        else if (message.startsWith("L"))
        {
            // LDR received
        }
    }
    Sleep(10);
}

但我绝对建议您不要在一个周期内阅读,而是使用信号。

我认为最好使用信号进行阅读。你知道如何使用它们吗?此外,我还想为您从Arduino发送的消息添加更多信息,以便您知道刚刚收到的消息类型。我有点了解如何使用串行信号读取数据,但它是否可以单独接收和保存值?如果您使消息不同,您可以。但是你需要在发送和阅读部分添加一些步骤。我认为最好使用信号进行阅读。你知道如何使用它们吗?此外,我还想为您从Arduino发送的消息添加更多信息,以便您知道刚刚收到的消息类型。我有点了解如何使用串行信号读取数据,但它是否可以单独接收和保存值?如果您使消息不同,您可以。但是你需要在发送和阅读部分添加一些步骤。谢谢。并不是说它解决了问题,而是我还学习了trimmed()、mid()和startsWith()。再一次感谢你花时间把它简单化。那么你仍然有问题吗?哦,我的错!实际上我想说的是,它不仅解决了问题,而且帮助我了解了这些函数。谢谢。并不是说它解决了问题,而是我还学习了trimmed()、mid()和startsWith()。再一次感谢你花时间把它简单化。那么你仍然有问题吗?哦,我的错!实际上,我想说的是,它不仅解决了问题,还帮助我了解了这些函数。谢谢,它让我了解了如何正确地阅读序列。我刚刚接受了另一个包含代码的答案。太糟糕了,新用户的upvote没有公开改变答案的分数。再次感谢。谢谢,这给了我一个如何正确阅读连载的想法。我刚刚接受了另一个包含代码的答案。太糟糕了,新用户的upvote没有公开改变答案的分数。再次感谢。