如何存储无符号char数组以浮点值?

时间:2019-05-07 06:30:43

标签: c++ arrays pointers char buffer

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

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

这些值已正确地从Arduino发送到Raspberry Pi(输出附加在下面),并且存储在指向unsigned char []的指针中,该指针定义为unsigned char * buf [4096]。

enter image description here

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变量中,以便可以对其执行进一步的操作。如何存储值,假设0.01到一个float / double后面,该浮点后来被用来创建东西。

2 个答案:

答案 0 :(得分:1)

从屏幕快照的输出中,您似乎正在发送数字的字符串表示形式,而不是实际的数字。您只需要检测要用.替换的那些“不可读的控制代码”,因为它们可能会告诉您数字何时结束和另一个开始。只需将QSerialPort * serial;设置为适当的班级成员即可。

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

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

答案 1 :(得分:0)

首先,最好使用其他ASCII字符(例如空格)分隔数字,因为.点是浮点数的一部分。然后,您可以从原始std::string数组构造unsigned char对象,将其拆分为多个字符串,然后将每个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作为CT或arg。