ros串口通讯是非常重要的通讯手段,通常跟下位机或者各种usb口外设都是通过串口进行通讯的。

那么我们跟着教程来学习一下如何读取手机通过无线串口发送给电脑的数据。

这里我通过一个usb-ttl工具将蓝牙连接到电脑上,然后通过手机连接蓝牙给蓝牙发送数据,然后电脑从usb-ttl工具读取数据并显示。

1.首先,ros里面有相应的串口包给我们用。我们调用串口包编程会非常方便。下载串口库:

sudo apt-get install ros-melodic-serial

我的ros版本是melodic,如果跟我版本不一样,讲melodic替换成相应的版本代号。

2.创建一个ros功能包并且添加相应的依赖。主要依赖roscpp和serial包

catkin_create_pkg serial_demo roscpp serial

ros串口通讯(读取串口数据)_ubuntu

3.在serial_demo功能包的src文件夹里面,我们创建一个serial_demo.cpp的c++程序。

然后将以下代码复制进入(记得更改下方程序中波特率跟蓝牙波特率一致,同时更改到正确的串口):

//serial_demo.cpp
#include <ros/ros.h>
#include <serial/serial.h>
#include <iostream>

int main(int argc, char** argv)
{
ros::init(argc, argv, "serial_port");
//创建句柄(虽然后面没用到这个句柄,但如果不创建,运行时进程会出错)
ros::NodeHandle n;

//创建一个serial对象
serial::Serial sp;
//创建timeout
serial::Timeout to = serial::Timeout::simpleTimeout(100);
//设置要打开的串口名称
sp.setPort("/dev/ttyUSB0");
//设置串口通信的波特率
sp.setBaudrate(9600);
//串口设置timeout
sp.setTimeout(to);

try
{
//打开串口
sp.open();
}
catch(serial::IOException& e)
{
ROS_ERROR_STREAM("Unable to open port.");
return -1;
}

//判断串口是否打开成功
if(sp.isOpen())
{
ROS_INFO_STREAM("/dev/ttyUSB0 is opened.");
}
else
{
return -1;
}

ros::Rate loop_rate(500);
while(ros::ok())
{
//获取缓冲区内的字节数
size_t n = sp.available();
if(n!=0)
{
uint8_t buffer[1024];
//读出数据
n = sp.read(buffer, n);

for(int i=0; i<n; i++)
{
//16进制的方式打印到屏幕
std::cout << std::hex << (buffer[i] & 0xff) << " ";
}
std::cout << std::endl;
//把数据发送回去
sp.write(buffer, n);
}
loop_rate.sleep();
}

//关闭串口
sp.close();

return 0;
}

修改CMakeList文件,添加选项

add_executable(serial_demo src/serial_demo.cpp)

add_dependencies(serial_demo ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(serial_demo
${catkin_LIBRARIES}
)

4.然后编译执行即可:

ros串口通讯(读取串口数据)_ros_02

但是他这边显示的是16禁止格式的数据。

如果我想显示字符或者字符串的话怎么修改呢?

ros串口通讯(读取串口数据)_数据_03

找到程序第58行,将其注释掉,然后在第59行添加一句输出字符的代码就行:

std::cout<<buffer[i];

可以看出来,已经正确输出了从手机端发送过来的字符:

ros串口通讯(读取串口数据)_串口_04