serial_device.cpp

#include "serial_device.h"

namespace roborts_sdk {
SerialDevice::SerialDevice(std::string port_name,
int baudrate) :
port_name_(port_name),
baudrate_(baudrate),
data_bits_(8),
parity_bits_('N'),
stop_bits_(1) {} SerialDevice::~SerialDevice() {
CloseDevice();
} bool SerialDevice::Init() { DLOG_INFO << "Attempting to open device " << port_name_ << " with baudrate " << baudrate_;
if (port_name_.c_str() == nullptr) {
port_name_ = "/dev/ttyUSB0";
}
if (OpenDevice() && ConfigDevice()) {
FD_ZERO(&serial_fd_set_);
FD_SET(serial_fd_, &serial_fd_set_);
DLOG_INFO << "...Serial started successfully.";
return true;
} else {
DLOG_ERROR << "...Failed to start serial "<<port_name_;
CloseDevice();
return false;
}
} bool SerialDevice::OpenDevice() { serial_fd_ = open(port_name_.c_str(), O_RDWR | O_NOCTTY);
if (serial_fd_ < 0) {
DLOG_ERROR << "cannot open device " << serial_fd_ << " " << port_name_;
return false;
} return true;
} bool SerialDevice::CloseDevice() {
close(serial_fd_);
serial_fd_ = -1;
return true;
} bool SerialDevice::ConfigDevice() {
int st_baud[] = {B4800, B9600, B19200, B38400,
B57600, B115200, B230400, B921600};
int std_rate[] = {4800, 9600, 19200, 38400, 57600, 115200,
230400, 921600, 1000000, 1152000, 3000000};
int i, j;
/* save current port parameter */
if (tcgetattr(serial_fd_, &old_termios_) != 0) {
DLOG_ERROR << "fail to save current port";
return false;
}
memset(&new_termios_, 0, sizeof(new_termios_)); /* config the size of char */
new_termios_.c_cflag |= CLOCAL | CREAD;
new_termios_.c_cflag &= ~CSIZE; /* config data bit */
switch (data_bits_) {
case 7:new_termios_.c_cflag |= CS7;
break;
case 8:new_termios_.c_cflag |= CS8;
break;
default:new_termios_.c_cflag |= CS8;
break; //8N1 default config
}
/* config the parity bit */
switch (parity_bits_) {
/* odd */
case 'O':
case 'o':new_termios_.c_cflag |= PARENB;
new_termios_.c_cflag |= PARODD;
break;
/* even */
case 'E':
case 'e':new_termios_.c_cflag |= PARENB;
new_termios_.c_cflag &= ~PARODD;
break;
/* none */
case 'N':
case 'n':new_termios_.c_cflag &= ~PARENB;
break;
default:new_termios_.c_cflag &= ~PARENB;
break; //8N1 default config
}
/* config baudrate */
j = sizeof(std_rate) / 4;
for (i = 0; i < j; ++i) {
if (std_rate[i] == baudrate_) {
/* set standard baudrate */
cfsetispeed(&new_termios_, st_baud[i]);
cfsetospeed(&new_termios_, st_baud[i]);
break;
}
}
/* config stop bit */
if (stop_bits_ == 1)
new_termios_.c_cflag &= ~CSTOPB;
else if (stop_bits_ == 2)
new_termios_.c_cflag |= CSTOPB;
else
new_termios_.c_cflag &= ~CSTOPB; //8N1 default config /* config waiting time & min number of char */
new_termios_.c_cc[VTIME] = 1;
new_termios_.c_cc[VMIN] = 18; /* using the raw data mode */
new_termios_.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
new_termios_.c_oflag &= ~OPOST; /* flush the hardware fifo */
tcflush(serial_fd_, TCIFLUSH); /* activite the configuration */
if ((tcsetattr(serial_fd_, TCSANOW, &new_termios_)) != 0) {
DLOG_ERROR << "failed to activate serial configuration";
return false;
}
return true; } int SerialDevice::Read(uint8_t *buf, int len) {
int ret = -1; if (NULL == buf) {
return -1;
} else {
ret = read(serial_fd_, buf, len);
DLOG_INFO<<"Read once length: "<<ret;
while (ret == 0) {
LOG_ERROR << "Connection closed, try to reconnect.";
while (!Init()) {
usleep(500000);
}
LOG_INFO << "Reconnect Success.";
ret = read(serial_fd_, buf, len);
}
return ret;
}
} int SerialDevice::Write(const uint8_t *buf, int len) {
return write(serial_fd_, buf, len);
}
}

serial_device.h

#ifndef ROBORTS_SDK_SERIAL_DEVICE_H
#define ROBORTS_SDK_SERIAL_DEVICE_H
#include <string>
#include <cstring> #include <termios.h>
#include <fcntl.h>
#include <unistd.h> #include "../utilities/log.h"
#include "hardware_interface.h" namespace roborts_sdk {
/**
* @brief serial device class inherited from hardware interface
*/
class SerialDevice: public HardwareInterface {
public:
/**
* @brief Constructor of serial device
* @param port_name port name, i.e. /dev/ttyUSB0
* @param baudrate serial baudrate
*/
SerialDevice(std::string port_name, int baudrate);
/**
* @brief Destructor of serial device to close the device
*/
~SerialDevice();
/**
* @brief Initialization of serial device to config and open the device
* @return True if success
*/
virtual bool Init() override ;
/**
* @brief Serial device read function
* @param buf Given buffer to be updated by reading
* @param len Read data length
* @return -1 if failed, else the read length
*/
virtual int Read(uint8_t *buf, int len) override ;
/**
* @brief Write the buffer data into device to send the data
* @param buf Given buffer to be sent
* @param len Send data length
* @return < 0 if failed, else the send length
*/
virtual int Write(const uint8_t *buf, int len) override ; private:
/**
* @brief Open the serial device
* @return True if open successfully
*/
bool OpenDevice();
/**
* @brief Close the serial device
* @return True if close successfully
*/
bool CloseDevice(); /**
* @brief Configure the device
* @return True if configure successfully
*/
bool ConfigDevice(); //! port name of the serial device
std::string port_name_;
//! baudrate of the serial device
int baudrate_;
//! stop bits of the serial device, as default
int stop_bits_;
//! data bits of the serial device, as default
int data_bits_;
//! parity bits of the serial device, as default
char parity_bits_;
//! serial handler
int serial_fd_;
//! set flag of serial handler
fd_set serial_fd_set_;
//! termios config for serial handler
struct termios new_termios_, old_termios_;
};
}
#endif //ROBORTS_SDK_SERIAL_DEVICE_H
//简单初始化
device_ = std::make_shared<SerialDevice>("/dev/ttyUSB0", 921600);
device_ ->Init();

基于ROS的串口底层写法的更多相关文章

  1. 基于STM32F10x的串口(USART)输入输出编程

    1 前言 STM32有强大的固件库,绝大部分函数都可以有库里面的函数组合编写.固件库可以到ST官网(www.st.com)上下载,也可以搜索“STM32 固件库 v3.5”下载到固件库.本文章就是基于 ...

  2. 基于ROS的分布式机器人远程控制平台

    基于ROS的分布式机器人远程控制平台   1 结构说明 HiBot架构主要使用C/S架构,其中HibotServer为服务器,Muqutte为消息服务器中间件,HiBotClient为运行在机器人上的 ...

  3. ROS 设置串口USB软连接

    原创:未经同意,请勿转载 我们在windows 通过USB连接串口,在设备串口中可以观测到COM0或者COMx.当我们插入不同的USB口时会显示不同的COM. 在UBUNTU下,ROS下接收串口信息时 ...

  4. Ubuntu16.04 + ROS下串口通讯

    本文参考https://blog.csdn.net/weifengdq/article/details/84374690 由于工程需要,需要Ubuntu16.04 + ROS与STM32通讯,主要有两 ...

  5. 基于ROS和beaglebone的串口通信方式,使用键盘控制移动机器人

    一.所需工具包 1.ROS键盘包:teleop_twist_keyboard  2.ROS串口通讯包:serial $ cd ~/catkin_ws/src $ git clone https://g ...

  6. [转]基于ROS平台的移动机器人-4-通过ROS利用键盘控制小车移动

    原文出处: https://blog.csdn.net/Forrest_Z/article/details/55002484 准备工作 1.下载串口通信的ROS包 (1)cd ~/catkin_ws/ ...

  7. 基于ROS和python,通过TCP通信协议,完成键盘无线控制移动机器人运动

    一.所需工具包 1.ROS键盘包:teleop_twist_keyboard 2.TCP通讯包:socket $ cd ~/catkin_ws/src $ git clone https://gith ...

  8. 【Delphi】基于状态机的串口通信

    通信协议 串行通信接口(如RS232.RS485等)作为计算机与单片机交互数据的主要接口,广泛用于各类仪器仪表.工业监测及自动控制领域中. 通信协议是需要通信的双方所达成的一种约定,它对包括数据格式. ...

  9. 基于Android的串口聊天室 (基于tiny4412) 一

    一.平台介绍 硬件平台: tiny4412ADK + S700 4GB Flash Android版本:Android-5.0.2 Linux版本: Linux-3.0.86 Bootloader:S ...

  10. 基于433MHz无线串口,多发一收解决方案

    一.无线发展背景 随着科学技术的飞速发展,智能家居.智慧农业.智慧城市如雨后春笋.而这些行业的发展离不开无线的应用. 传统的有线连接不仅仅是成本高,包括布线安装.维护等也是成本巨大.并且机动性也很差, ...

随机推荐

  1. 交叉编译GDB

    PC主机安装必要软件 sudo apt-get install bison flex expect-dev build-essential m4 autoconf automake texi2html ...

  2. C++初阶(stack+queue)

    stack stack介绍 stack是一种先进后出的数据结构,只有一个出口,类似于栈.stack容器哦允许新增元素,移除元素,取得栈顶元素,但是除了最顶端之后,没有任何其他办法可以存取stack的其 ...

  3. 总结uni-app遇到的坑持续跟新

    1.uni.navigateTo跳转没有反应 官方示例 //在起始页面跳转到test.vue页面并传递参数 uni.navigateTo({ url: 'test?id=1&name=unia ...

  4. 关于虚拟机使用桥接网络访问不到物理机IP的问题解决

    问题描述 物理机可以ping 到虚拟机IP,虚拟机 ping 不到物理机IP 解决方法 关闭物理机防火墙,重启虚拟机

  5. Spring01:概述、工厂模式解耦、Spring中的IOC

    四天课程安排 第一天:Spring框架的概述.Spring中基于XML的IOC配置 第二天: Spring中基于注解的IOC和IOC的案例(单表增删改查,持久层随意) 第三天:Spring中的AOP和 ...

  6. USB转TTL串口 (CH340 G)

    为什么USB要转TTL串口[1]? 单片机串口基本采用TTL电平. 家用电脑很少有串口,但是有USB接口 USB的电平与TTL电平不兼容. 所以需要将USB电平转化为TTL电平. USB是什么? 接口 ...

  7. SQLMap入门——获取数据库中的表名

    查询完数据库后,查询指定数据库中所有的表名 python sqlmap.py -u http://localhost/sqli-labs-master/Less-1/?id=1 -D xssplatf ...

  8. easygui 之integerbox()、enterbox()、multenterbox() 三种输入函数的使用

    1.integerbox()函数:只可输入整数的输入框,默认输入范围为0-99 integerbox(msg="", title=" ", default=No ...

  9. Ubuntu:Docker启动与停止

    安装完成Docker后,默认已经启动了docker服务,如需手动控制docker服务的启停,可执行如下命令 启动docker sudo service docker start 停止docker su ...

  10. python画社交网络图

    安装依赖包 pip3 install networkx 在图书馆的检索系统中,关于图书的信息里面有一个是图书相关借阅关系图.跟这个社交网络图是一样的,反映了不同对象间的关联性.利用python画社交网 ...