Хорошо, не волнуйтесь, это не так уж сложно.
Я переработал ваш псевдокод, чтобы он компилировался как фрагмент кода 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();
}
}