Linux系统下使用cutecom进行串口通信(二)
目录一、Serial库1)简介2)类的成员和方法二、程序及解析三、测试结果在Linux系统下使用cutecom进行串口通信(一)中简要介绍了cutecom的安装及使用方法,本文将结合ros程序(C++),进一步探究Linux系统下的串口通信。一、Serial库1)简介2)类的成员和方法二、程序及解析三、测试结果...
在 Linux系统下使用cutecom进行串口通信(一)中简要介绍了cutecom的安装及使用方法,本文将结合ros程序(C++),进一步探究Linux系统下的串口通信。
一、Serial库
1)安装
前人栽树,后人乘凉。在ros中,前辈们早就将串口通信编成了库,直接使用如下命令行安装:
$ sudo apt-get install ros-rosdistro-serial
添加头文件,引入serial库:
$ #include <serial/serial.h>
当然,为了保证能够找到serial.h文件,还需修改CMakeLists,将serial库包含进来:
find_package(catkin REQUIRED COMPONENTS
serial
)
在package.xml中添加:
<build_depend>serial</build_depend>
<build_export_depend>serial</build_export_depend>
<exec_depend>serial</exec_depend>
笔者在创建功能包时直接包含了serial,所以CMakelists.txt和package.xml文件无需再次添加编译规则:
$ catkin_create_package [PACKAGE_NAME] roscpp rospy serial
2)类的方法
串口通信并不复杂,掌握其中参数的设置就能够正常使用了。想要使用serial库,需要创建一个对象:
$ serial::Serial sp;
执行构造函数时会对参数进行初始化:
Serial (const std::string &port = "",
uint32_t baudrate = 9600,
Timeout timeout = Timeout(),
bytesize_t bytesize = eightbits,
parity_t parity = parity_none,
stopbits_t stopbits = stopbits_one,
flowcontrol_t flowcontrol = flowcontrol_none);
具体serial的函数调用的方法:
方法 | 说明 | 备注 |
---|---|---|
sp.setPort("/dev/ttyUSB0") | 设置串口名称 | Linux下usb口名称 |
sp.setBaudrate(115200) | 设置波特率为115200 | 保证波特率一致 |
serial::Timeout to = serial::Timeout::simpleTimeout(1000) sp.setTimeout(to) | 设置Timeout | 默认 |
sp.setBytesize(serial::bytesize_t(8)) | 设置数据位 | fivebits = 5; sixbits = 6; sevenbits = 7; eightbits = 8 |
sp.setParity(serial::parity_t(0)) | 设置奇偶校验 | parity_none = 0; parity_odd = 1; parity_even = 2; parity_mark = 3; parity_space = 4 |
sp.setStopbits(serial::stopbits_t(1)) | 设置停止位 | stopbits_one = 1; stopbits_two = 2, stopbits_one_point_five = 3 |
sp.setFlowcontrol(serial::flowcontrol_t(0)) | 设置串口流控 | flowcontrol_none = 0; flowcontrol_software = 1; flowcontrol_hardware = 2 |
sp.open() | 打开串口 | 在设置参数后打开 |
sp.isOpen() | 判断串口是否打开 | 返回bool类型 |
sp.available() | 获取缓冲区内的字节数 | 返回size_t类型 |
sp.read(buffer, n) | 读取数据 | 从缓冲区读取n个数据, 放入uint8_t类型的buffer数组 |
sp.write(buffer, n) | 写入数据 | 将uint8_t类型的buffer数组中的前n个数据, 写入缓冲区 |
sp.flush() | 清空串口存储空间 | 写入数据后即时清空 |
sp.close() | 关闭串口 | 程序结束前关闭 |
除此之外还有一些其他的函数,具体可参考serial的头文件。
二、程序及解析
使用trycatch语句尝试打开串口:
try {
//设置串口属性,并打开串口
sp.setPort("/dev/ttyUSB0");
sp.setBaudrate(115200);
serial::Timeout to = serial::Timeout::simpleTimeout(1000);
sp.setTimeout(to);
sp.open();
} catch (serial::IOException& e) {
ROS_ERROR_STREAM("Unable to open port ");
return -1;
}
//检测串口是否已经打开,并给出提示信息
if(sp.isOpen()) {
ROS_INFO_STREAM("Serial Port initialized");
} else {
return -1;
}
当终端输入如下信息时,说明串口能够正常使用:
Serial Port initialized
1)node→cutecom
假设发送两个数据:x和y。串口数据格式为:x用4个字节表示,y用两个字节表示,先发低位后发高位。为了保证数据能够被准确解析,在实际数据前增加标志位数据0xaa,0xbb和0xcc。编码程序如下所示:
int serSize = 10;
uint8_t serData[serSize]; //定义串口数据存放数组,注意防止数据溢出
int error = 3;
serData[0] = 0xaa;
serData[1] = 0xbb;
serData[2] = 0xcc;
int32_t x_32 = int32_t(30123.0);
char *pt0 = (char*)&x_32;
serData[0+error] = pt0[0];
serData[1+error] = pt0[1];
serData[2+error] = pt0[2];
serData[3+error] = pt0[3];
int16_t y_16 = int16_t(1575.0);
char *pt1 = (char*)&y_16;
serData[4+error] = pt1[0];
serData[5+error] = pt1[1];
sp.write(serData, serSize);
运行程序,并打开cutecom,即可观察到数据。
2)cutecom→node
由cutecom发送串口数据,数据格式同1)node→cutecom。发送的数据如下:
aa bb cc ab 75 00 00 27 06
解码程序如下所示:
int serSize = 10;
uint8_t serData[serSize]; //定义串口数据存放数组,注意防止数据溢出
double x_;
double y_;
ser.read(serData,serSize);//从缓冲区中读取80位数据,存放到定义好的数组中
for (int i =0; i < 2 * serSize; i++) {
if (serData[i] == 0xaa) {
if (serData[i+1] == 0xbb) {
if (serData[i+2] == 0xcc) {
x_ = comb32(serData[i+6], serData[i+5], serData[i+4], serData[i+3]) * 1.0;
y_ = comb16(serData[i+8], serData[i+7]) * 1.0;
}
}
}
}
ROS_INFO("x_: %f, y_: %f", x_, y_);
按照通信协议格式解析数据,需要用到解析函数comb16()和comb32()。我用的是师兄kailon写的,具体如下:
int16_t comb16(uint8_t high, uint8_t low) //数据解析2个8位->16位
{
int16_t temp = 0;
temp = ((int16_t)high << 8);
temp |= ((int16_t)low);
return temp;
}
int32_t comb32(uint8_t first, uint8_t second, uint8_t third, uint8_t fourth) //数据解析4个8位->32位
{
int32_t temp = 0;
temp = ((int32_t)first << 24);
temp |= ((int32_t)second << 16);
temp |= ((int32_t)third << 8);
temp |= ((int32_t)fourth);
return temp;
}
三、测试结果
1)node→cutecom
串口数据为:
aa bb cc ab 75 00 00 27 06
2)cutecom→node
更多推荐
所有评论(0)