如何解决使用boost c ++读取串行端口,我应该如何解码数据?
我正在尝试创建一个简单的应用程序,该应用程序可以从串行端口读取数据。我有数据的结构,如下:
Byte Function Format Example Hex
0 Header ASCII Char I 49
1 Header ASCII Char W 57
2 Header ASCII Char A 41
3 Header ASCII Char P 50
4 Header ASCII Char I 49
5 Header ASCII Char x 78
6 Version uint8_t 1 1
7 Pan int32_t 0A
8 Pan int32_t 0B
9 Pan int32_t 0C
10 Pan int32_t 168496141 0D
11 Tilt int32_t 0A
12 Tilt int32_t 0B
13 Tilt int32_t 0C
14 Tilt int32_t 168496141 0D
15 Roll int32_t 0A
16 Roll int32_t 0B
17 Roll int32_t 0C
18 Roll int32_t 168496141 0D
19 Jog A int32_t 0A
20 Jog A int32_t 0B
21 Jog A int32_t 0C
22 Jog A int32_t 168496141 0D
23 Jog B int32_t 0A
24 Jog B int32_t 0B
25 Jog B int32_t 0C
26 Jog B int32_t 168496141 0D
27 Focus uint16_t 0A
28 Focus uint16_t 2571 0B
29 Iris uint16_t 0A
30 Iris uint16_t 2571 0B
31 Zoom uint16_t 0A
32 Zoom uint16_t 2571 0B
33 To One uint8_t (blip) 10 0A
34 Reverse uint8_t (blip) 10 0A
35 Pause uint8_t (blip) 10 0A
36 Forward uint8_t (blip) 10 0A
37 Reserved
38 Reserved
39 Reserved
40 Reserved
41 Reserved
42 Reserved
43 Reserved
44 Reserved
45 Checksum CheckSum8 Modulo 256
46 Footer ASCII Char ; 3B
47 Footer ASCII Char ! 21
48 Footer ASCII Char ; 3B
数据是:UART:921600波特,8N2,大端字节
我这样打开端口,并读取数据:
#include <iostream>
#include <boost/asio.hpp>
using namespace std;
using namespace boost;
int main(int argc,char* argv[])
{
asio::io_service io;
asio::serial_port port(io);
port.open("COM14");
port.set_option(asio::serial_port_base::baud_rate(921600));
char c;
std::string rsp;
while (c != ';')
{
asio::read(port,asio::buffer(&c,1));
rsp += c;
}
std::cout << rsp << std::endl;
port.close();
std::cin.get();
}
这给了我字符串:
IWVPx :ã {;
很显然,我做错了,我想是因为我将数据读取为char
。
读取串行端口数据并将其转换为可读数据的正确方法是什么?
解决方法
您可以使用提供的结构来解析数据。您看到的空格很可能是由于二进制数据的ASCII解释。这是二进制数据的线索是写者指定字节位置。这是我解析这些数据的方法。
首先,创建一个与要解析的数据相匹配的结构:
struct Data
{
char header[5];
uint8_t ver;
int32_t pan;
int32_t tilt;
int32_t roll;
int32_t joga;
int32_t jogb;
uint16_t focus;
uint16_t iris;
uint16_t zoom;
uint8_t toOne;
uint8_t reverse;
uint8_t pause;
uint8_t forward;
uint8_t reserved[8];
uint8_t checksum;
char footer[3];
}__attribute__((packed));
接下来,读入所有数据。有很多工具远远超出了描述如何实际解析这些数据的范围,因此我将不赘述。在这里,我指的是确保您的包正确对齐,获取第二个分号,检查数据缓冲区的大小是否与预期结构相同的方法。其中一些仅在发送的数据包自动发送而不是请求时才起作用。
一旦填充了缓冲区,请确保它与数据结构的大小相同,就很简单:
Data data;
memcpy( &data,buffer,sizeof(data) );
然后可以像访问结构一样访问数据。请注意,此解决方案假定机器之间的字节序一致。如果不是这样,则可能必须执行一些字节反转。
最终结果可能类似于:
int main(int argc,char* argv[])
{
asio::io_service io;
asio::serial_port port(io);
port.open("COM14");
port.set_option(asio::serial_port_base::baud_rate(921600));
uint8_t obuf[256]; // arbitrary size,larger than largest expected buffer
// perform packet alignment here
asio::read(port,asio::buffer(obuf,sizeof(Data)));
Data d = {};
memcpy( &d,obuf,sizeof(d) );
// if your endianness is different than the data sent,fix it here.
std::cin.get();
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。