最近使用一个新的设备时,接的也是USB口,但是设备类型好像有点不同,了解了一下,他们所用的协议有所不同,以前最常用的ttyUSB调用的驱动是drivers/usb/serial/usb-serial.c,而ttyACM调用的驱动是drivers/usb/class/cdc_acm.c
在Ubuntu中打开/dev/ttyUSB*设备和/dev/ttyACM设备,都可以用下面的串口程序:
#include <ros/ros.h>
#include <serial/serial.h>
#include <iostream>
#include <fstream>
#include <time.h>
#include <sstream>
using namespace std;
int main(int argc, char **argv)
{
ros::init(argc, argv, "serial_port_open");
ros::NodeHandle nh;
// 创建一个serial对象
serial::Serial sp;
// 创建timeout
serial::Timeout to = serial::Timeout::simpleTimeout(100);
// 设置要打开的串口名称
sp.setPort("/dev/ttyACM0");
// 设置串口通信的波特率
sp.setBaudrate(115200);
// 串口设置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/ttyACM0 is opened.");
}
else
{
return -1;
}
ros::Rate loop_rate(2);
unsigned char data1[1] = {0xa1}; // send data
unsigned char data2[1] = {0xb1};
uint8_t buffer[1024];
while (ros::ok())
{
size_t n = sp.available();
// Send data
sp.write(data1, 1);
// Receive data
n = sp.read(buffer, n);
for (int i = 0; i < n; i++)
{
// 16进制的方式打印到屏幕
std::cout << std::hex << (buffer[i] & 0xff) << " ";
}
ros::spinOnce();
loop_rate.sleep();
}
// close serial port
sp.close();
return 0;
}
其中,sp.setPort("/dev/ttyACM0");
中的串口编号,根据实际情况修改就可以了,如果是/dev/ttyUSB*
,就改成/dev/ttyUSB*
,如果是/dev/ttyACM*
类型的,就写成/dev/ttyACM*
data1[1]
和data2[1]
定义的是16进制的数值,这些是发给单片机的,所以这里面的内容跟单片机的通信协议有关,这里需要也是需要根据实际情况进行修改。
n = sp.read(buffer, n);
返回的buffer,即数据,也是需要根据与单片机的通信协议来确定的,根据实际情况进行解码就可以了