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. php 导出图片为pdf

    require_once ROOTPATH . 'tcpdf/vendor/autoload.php';$html='';if($html){ mpdf($html); }else{ echo &qu ...

  2. 当resource bundle 的多语言文件里包含引号'时

    背景 项目中使用Spring的ReloadableResourceBundleMessageSource这个类来实现多语言,有一次字符串里包含引号'时,解析时出了问题,一起来看一下吧 例子 resou ...

  3. python自然语言处理(NLP)1------中文分词1,基于规则的中文分词方法

    python中文分词方法之基于规则的中文分词 目录 常见中文分词方法 推荐中文分词工具 参考链接 一.四种常见的中文分词方法: 基于规则的中文分词 基于统计的中文分词 深度学习中文分词 混合分词方法 ...

  4. 使用pandas处理数据和matplotlib生成可视化图表

    一.缘由 上一篇输入关键词"口红",将淘宝中的的相关商品信息全部爬取了下拉,并且以CSV的文件格式储存.我们拿到数据之后,那么就需要对数据进行处理.只是将爬取到的数据以更直观的方式 ...

  5. AIBOX视频边缘计算终端,助力识别人员违规行为!

    目前,制造业工厂工作区布局分散,生产安全质量控制难度较大.人员擅自离岗.玩手机.区域入侵.吸烟.未穿反光衣.异物占位等违法行为不能及时控制,安全风险十分巨大.如果手动检查或通过人眼检查监控录像,不仅产 ...

  6. Linux开发板连接WPA加密的AP路由器

    Linux目前有两种方法配置网络: wireless-tools wpa_supplicant iw支持的驱动较多,但只支持WEP加密:wpa_supplicant有部分驱动支持不完善,但支持WEP. ...

  7. linux基础第二部分

    一.Linux命令执行过程 先判断是否是别名,如果是直接执行,不是看是否是内部命令 如果是内部命令,直接执行,不是看hash表 hash表中有源文件直接执行,找不到报错 若hash表中不存在去外部规定 ...

  8. python 之 random.sample() 报ValueError: Sample larger than population or is negative

    def device_id(): device = ''.join(random.sample(string.digits, 19)) return device print(device_id()) ...

  9. Jmeter 之bzm- Concurrency Thread Group 压测

    bzm- Concurrency Thread Group  并发线程组代替 jp@gc - Stepping Thread Group线程组. 1.  下载jmeter-plugins-manage ...

  10. 网络编程 UDP套接字

    第十二章 UDP套接字 12.1 前言 上一章讲述了TCP通信方式,它是基于流的面向连接的网络通信.UDP是IP协议上的另一种传输协议. TCP和UDP都是端到端的通信协议,都处于TCP/IP网络模型 ...