如何将无符号字符数组存储为浮点值?

How to store a unsigned char array to float value?

我正在尝试使用 RS232 串行通信从 Arduino & Raspberry Pi 获取传感器数据。我搜索了这个小东西,并在下面 link 找到了与此相关的东西,但无法得到完整的想法。

os(内核)有一个 4096 字节的内部缓冲区。如果此缓冲区已满并且新字符到达串行端口,则缓冲区中最旧的字符将被覆盖,因此将为 lost。成功调用 RS232_OpenComport() 后,os 将开始缓冲传入字符。

这些值正确地从 Arduino 传到 Raspberry Pi(下面附上输出),它存储在一个指向 unsigned char[] 的指针中,它被定义为 unsigned char *buf[4096]。

int main()
{
  int i, n,
      cport_nr=0,        /* /dev/ttyS0 (COM1 on windows) */
      bdrate=9600;       /* 9600 baud */

  unsigned char buf[4096];

  char mode[]={'8','N','1',0};

  while(1)
  {
    n = RS232_PollComport(cport_nr, buf, 4095);

    if(n > 0)
    {
      buf[n] = 0;

      for(i=0; i < n; i++)
      {
        if(buf[i] < 32)  /* replace unreadable control-codes by dots */
        {
          buf[i] = '.';
        }
      }

      printf("received %i bytes: %s\n", n, (char *)buf);
    }
}

现在我想将这些值存储在另一个 float/double 变量中,以便我可以对其执行进一步的操作。如何将值 suppose 0.01 存储到 float/double 中,稍后用于创建内容。

首先,如果使用其他ASCII字符(例如space)来分隔数字会更好,因为.点是浮点数的一部分。然后,您可以从原始 unsigned char 数组构造 std::string 对象,将其拆分为多个字符串并将每个 string 转换为 float.

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

int main() {
    // imagine that this buff is already after read and preprocessing
    unsigned char buff[1024] = "13.60  13.60  -11.12  -0.3  and let's say that the rest is garbage";
    int n = 28;  // let's say that you received 28 bytes
    std::string strBuff(reinterpret_cast<char*>(buff), n); // construct a string from buff using just first 28 bytes
    std::vector<std::string> numbers;
    boost::split(numbers, strBuff, boost::is_any_of(" "), boost::token_compress_on);
    for (const auto& n : numbers) {
        try {
            std::cout << std::stof(n) << std::endl;
        } catch (const std::exception& e) {
            std::cout << n << " is not convertible to float: " << e.what() << std::endl;
        }
    }
    return 0;
}

我采用了 this answer 的字符串拆分方法,但您可以使用任何适合您的方法。

我使用 reinterpret_cast 因为 std::string 接受 char 而不是 unsigned char 作为 CTor arg。

从屏幕截图的输出来看,您发送的似乎是数字的字符串表示形式,而不是实际数字。你只需要检测那些你刚用 . 替换的 "unreadable control-codes",因为它们可能会告诉你一个数字何时结束,另一个数字何时开始。只需让 QSerialPort * serial; 成为合适的 class 成员即可。

此外,检查打开端口时是否有错误:serial->open(QIODevice::ReadWrite); 然后,在 serialreceived() 中插入一些 qDebug() 以查看插槽是否被调用以及 canReadLine() 有效。你应该使用 QByteArray 来读取你的数据。如果响应中有任何不符合字符串的字符,则生成的 QString 将过早终止,请使用 readLine() 代替 readAll(),如下所示:

QByteArray data = serial -> readLine();
qDebug() < data.toHex(' '); // prints the hex representation of your char array
QString str(data);
qDebug() << str;