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. kubernetes笔记-1-基础环境部署

    一.环境信息: 操作系统:ubuntu 18.04 server amd64 docker:docker 19.03.ce kubernetes:v1.19 IP地址 主机名   角色 172.29. ...

  2. 如何在kali Linux上安装VMware Tools

    作用: 1.让虚拟机和本地上的文件可以互传,直接拖动就可以实现转接 2.可在虚拟机上执行本地脚本 3.本地时钟与虚拟机同步 4........... 方法: 1.运行虚拟机 2.在上方菜单栏中点击安装 ...

  3. easyui combobox的级联设置

    <body> <input id="title" class="easyUI-combobox" //onSelect:在该combobox被 ...

  4. 零基础入门数据挖掘——二手车交易价格预测:baseline

    零基础入门数据挖掘 - 二手车交易价格预测 赛题理解 比赛要求参赛选手根据给定的数据集,建立模型,二手汽车的交易价格. 赛题以预测二手车的交易价格为任务,数据集报名后可见并可下载,该数据来自某交易平台 ...

  5. 【vue3】element-plus,Checkbox-Group多选框之绑定选中数据不选中问题

    今天记录一下在新项目vue3中,使用的element-plus组价库遇到的一个问题!场景如下:有一个表格的column绑定的数组对象,我需要对表格的头部实现动态可配置显示表格列,由于绑定的column ...

  6. MySQL事务(四大特性)-存储过程

    目录 一:事务 1.四大特性(ACID) 2.事物存在的必要性(真实比喻) 3.如何使用事务 4.开启事务-回滚-确认 二:事务案例实战 1.模拟消费 2.创建 3.插入数据 4.开启事务 5.修改操 ...

  7. 电脑无法自动获取ip地址

    1.按下win+r,输入cmd,打开命令提示符;2.执行ipconfig命令看下能否获取到ip地址:3.若不能,执行ipconfig /renew命令重新获取ip:4.执行ipconfig命令看下能否 ...

  8. 体验一个前端视图层的mvvm的框架Knockoutjs(双向绑定,模板..)..解放您的双手,不再处理那么多的dom操作..快速实现视图层数据与UI的交互处理

    笔者之前对于类似前端展示的,可能都是自己开发js对象,集合外加dom事件进行处理..  近期看到相关资料,了解了Knockoutjs这个框架,下面来段代码: <script type=" ...

  9. Java8时间日期处理新特性

    Java8时间日期处理新特性 简介 伴随lambda表达式.streams以及一系列小优化,Java 8 推出了全新的日期时间API.Java处理日期.日历和时间的不足之处:将 java.util.D ...

  10. 那些年我们用过的组件-结构化日志组件 Serilog

    什么是结构化日志 我们记录日志惯常使用 log4j2.NLog 等日志组件,这些组件提供了输出到多种终端的能力,但是大部分时候我们选择将日志输出到操作系统的文件系统中,为什么呢?至少有一部分原因是记录 ...