Как конвертировать входящие шестнадцатеричные значения из последовательного порта в C? - PullRequest
0 голосов
/ 25 октября 2018

Обзор: Я хочу использовать Visual Studio (в C) для считывания значения HEX с прямым порядком байтов 24-байтового пакета данных с датчика через последовательный COM-порт.Мне нужно обновлять последовательное чтение всякий раз, когда новые данные отправляются в порт, и интерпретировать некоторые байты данных как значения с плавающей запятой.Как я могу прочитать о COM-порте, когда доступны последовательные данные, организовать байты и преобразовать их в числа с плавающей запятой / полезную информацию?

Подробности: Входящие пакеты известны 24длина байта и начало / конец с известными символами ("{" и "}"), что помогает узнать, сколько байтов нужно перехватить и как их разбить.Байты 7-10 содержат данные о концентрации газа 1 в шестнадцатеричном формате с прямым порядком байтов, байты 11-14 содержат данные о концентрации газа 2 в шестнадцатеричном формате с прямым порядком байтов.Пример пакета показан ниже:

Пример 24-байтового шестнадцатеричного пакета 1

Другой пример аналогичного пакета (предоставленного таблицей данных датчика) показан ниже:

Пример 24-байтового HEX-пакета 2

Псевдокод, который я выделил для всей операции, выделен следующим образом:

If serial data is available{

    //read serial packet into char array
    Char serialString[24]  = read serial until newline character () 

    startBracketHexChar = serialString[0] //”{“ part of packet
    Gas1HexChar= serialString[6-9]      //gas measurement 1 data from packet
    Gas2HexChar = serialString[10-13]   //gas measurement 2 data from packet
    tempHexChar = serialString[14-17]   //temp measurement from packet
    endBracketHexChar = serialString[23]        //”}” part of bracket

    //if packet is as expected…
    if (startBracketHexChar == ‘{‘ && endBrackHexChar == ‘}’){  

        Gas1Float = char.to.float(Gas1HexChar)  //convert char to float type
        Gas2Float = char.to.float(Gas2HexChar)  //convert char to float type
        tempFloat = char.to.float(tempHexChar)  //convert char to float type
        gas1textBox.Text = Gas1Float;           //display gas 1 reading 
        gas2textBox.Text = Gas2Float;           //display gas 2 reading 
        temptextBox.Text = tempFloat;           //display temp reading
    }
    else {
        ErrortextBox.Text = “Packet error”; //unexpected packet error
    }
}

Iмне кажется, я очень ошибочен в своих предположениях в псевдокоде о чтении массива Gas1HexChar (может быть, его нужно читать символ за символом и объединять, а не в один кусок массива?) и преобразовывать его (икота при вызове строки символа в Hex)значение, а затем преобразование этого шестнадцатеричного значения в число с плавающей точкой?) - здесь мои знания и опыт очень ограничены, и предложения по реализации будут чрезвычайно полезны.

1 Ответ

0 голосов
/ 25 октября 2018

Хорошо, не волнуйтесь, это не так уж сложно.

Я переработал ваш псевдокод, чтобы он компилировался как фрагмент кода C.Я полагаю, что основная часть вашего вопроса о том, как получить и собрать многобайтовое значение.В приведенных ниже кодовых блоках это функция decode.

При работе с бинарным пакетом, как у вас, гораздо лучше использовать unsigned char вместо простого char.Это делает переключение легче / более правильным.

Вы сказали, что пакет newline завершен, но это не показано на диаграмме.И, поскольку мы имеем дело с двоичными данными [как вы подтвердили в своих главных комментариях], любой допустимый байт в части данных пакета может быть 0x0A (т. Е. Символ новой строки), поэтому мы можем't просто читайте char-by-char до тех пор, пока мы не увидим новую строку.

Если действительно есть новая строка в конце, нам может понадобиться прочитать 25 байтов и простопроверьте последний символ.

У меня нет окон :-), поэтому я не знаю особенностей доступа к COM-порту, но я закодировал функции, которые вы можете заполнить.


В любом случае, код приведен ниже [прошу прощения за чистую стирку]:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

typedef struct {
    char Text[100];
} TextBox_t;

FILE *stream;

TextBox_t gas1textBox;
TextBox_t gas2textBox;
TextBox_t temptextBox;
TextBox_t ErrortextBox;

// serial_data_is_available -- check for data ready
int
serial_data_is_available(void)
{

    return 1;
}

// serial_get -- get single byte from device
unsigned char
serial_get(void)
{

    return rand();
}

// serial_buf -- assemble packet buffer
int
serial_buf(unsigned char *buf,int buflen)
{
    int idx;

    for (idx = 0;  idx < buflen;  ++idx)
        buf[idx] = serial_get();

    return idx;
}

// decode -- get a binary value
uint32_t
decode(unsigned char *buf,int beg,int end)
{
    uint32_t acc = 0;

    for (int idx = end;  idx >= beg;  --idx) {
        acc <<= 8;
        acc |= buf[idx];
    }

    return acc;
}

// floatget -- get a float value
float
floatget(unsigned char *buf,int beg,int end)
{
    union {
        float fval;
        uint32_t val;
    } join;

    join.val = decode(buf,beg,end);

    return join.fval;
}

// process_packet -- process a single packet
void
process_packet(void)
{
    // for raw binary data, unsigned is better
    unsigned char buf[24];

    // read serial packet into char array
    serial_buf(buf,sizeof(buf));

    // "{" part of packet
    char start = buf[0];

    // "}" part of bracket
    char end = buf[23];

    //if packet is as expected…
    if ((start == '{') && (end == '}')){
        // gas measurement 1 data from packet
        float Gas1Float = floatget(buf,6,9);

        // gas measurement 2 data from packet
        float Gas2Float = floatget(buf,10,13);

        // temp measurement from packet
        float tempFloat = floatget(buf,14,17);

        sprintf(gas1textBox.Text,"%f",Gas1Float);
        sprintf(gas2textBox.Text,"%f",Gas2Float);
        sprintf(temptextBox.Text,"%f",tempFloat);
    }
    else {
        strcpy(ErrortextBox.Text,"Packet error"); //unexpected packet error
    }
}

void
loop(void)
{

    while (1) {
        if (serial_data_is_available())
            process_packet();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...