Как сохранить массив без знака в плавающем значении? - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь получить данные датчика от Arduino & Raspberry Pi, используя последовательную связь RS232. Я искал эту маленькую вещь и нашел что-то связанное по этой ссылке ниже, но не смог получить полную идею.

ОС (ядро) имеет внутренний буфер 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 в число с плавающей запятой / double, которое позже используется для создания вещи.

Ответы [ 2 ]

1 голос
/ 08 мая 2019

Из вывода на скриншоте выглядит, как будто вы посылаете строковое представление чисел, а не фактических чисел.Вам просто нужно обнаружить те «нечитаемые контрольные коды», которые вы просто заменяете на ., поскольку они, вероятно, сообщат вам, когда число заканчивается, а другое начинается.Просто сделайте 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;
0 голосов
/ 07 мая 2019

Во-первых, будет лучше, если вы используете какой-либо другой символ 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;
}

Я взял метод разделения строк из этого ответа , но вы можете использовать все, что вам подходит.

Я использовал reinterpret_cast, потому что std::string принимает char вместо unsigned char в качестве аргумента CT или

...