c++通过serial库进行上下位机通信
编辑
风紊
现役大学牲,半退休robomaster视觉队员
写在前面
本文章主要介绍的是如何通过开源的serial
库和虚拟串口实现上位机和下位机通信。
需求
假设下位机有这样一个数据报发送给上位机
struct DataRecv {char start = 's';TeamColor color = TeamColor::Blue;Mode mode = Mode::Armor;float speed = 20;float euler[3] = {}; //(0,1,2) = (yaw,roll,pitch)char shoot_bool = 0;char RuneFlag = 0; char unused[10] = {};char end = 'e';
}//TeamColor是一个char类型的迭代类,Mode也是一个char类型的迭代类
其他数据我都不需要,只需要欧拉角,也就是一个浮点数数组,euler[3]
解决方法
serial库的github仓库
先clone下来,安装,得到头文件和动态库。
我们来看看serial库的构造函数:
class Serial {
public:/*!* Creates a Serial object and opens the port if a port is specified,* otherwise it remains closed until serial::Serial::open is called.** \param port A std::string containing the address of the serial port,* which would be something like 'COM1' on Windows and '/dev/ttyS0'* on Linux.** \param baudrate An unsigned 32-bit integer that represents the baudrate** \param timeout A serial::Timeout struct that defines the timeout* conditions for the serial port. \see serial::Timeout** \param bytesize Size of each byte in the serial transmission of data,* default is eightbits, possible values are: fivebits, sixbits, sevenbits,* eightbits** \param parity Method of parity, default is parity_none, possible values* are: parity_none, parity_odd, parity_even** \param stopbits Number of stop bits used, default is stopbits_one,* possible values are: stopbits_one, stopbits_one_point_five, stopbits_two** \param flowcontrol Type of flowcontrol used, default is* flowcontrol_none, possible values are: flowcontrol_none,* flowcontrol_software, flowcontrol_hardware** \throw serial::PortNotOpenedException* \throw serial::IOException* \throw std::invalid_argument*/Serial (const std::string &port = "" //需要打开的端口uint32_t baudrate = 9600, //设置波特率,缺省值位9600Timeout timeout = Timeout(), //打开超时的时间,缺省值时间为0bytesize_t bytesize = eightbits, //字节大小,缺省值位8位parity_t parity = parity_none, //奇偶校验位,默认无奇偶校验stopbits_t stopbits = stopbits_one, //停止位,缺省值为1位flowcontrol_t flowcontrol = flowcontrol_none);//流控制,默认五流控制,可选择软件流控制和硬件流控制
选项都设置好后,直接调用对象的open()方法就能打开串口通信。
读数据的方法:
size_t
Serial::read (uint8_t *buffer, size_t size)
{ScopedReadLock lock(this->pimpl_);return this->pimpl_->read (buffer, size);
}
所以我们只需要将数据包转为uint8_t的类型的存储格式指针,传给函数,并指定字节数size就能读取数据了。
通信实现文件test.cpp
的代码
#include <serial/serial.h>
#include <iostream>struct data_package
{char start = 's';char unused1[2];float speed = 20;float euler[3] = {}; //(0,1,2) = (yaw,roll,pitch)char shoot_bool = 0;char RuneFlag = 0; //char unused2[10] = {};char end = 'e';
} __attribute__((packed));
static_assert(sizeof(data_package) == 32);data_package data;
int main()
{std::cout << "helloworld" << std::endl;serial::Serial ser; // 实例化一个串口的对象ser.setPort("/dev/serial_sdk"); // 设置串口设备ser.setBaudrate(115200); // 设置波特率try{ser.open(); // 打开串口while (true){std::cout << "number" << ser.available() << std::endl; // 读取到缓存区数据的字节数ser.read(reinterpret_cast<uint8_t *>(&data), 32);//将data_package类型结构体强制转换位uint8_t类型的指针,来接收32字节的数据std::cout << data.start << data.unused1[0] << data.unused1[1] << std::endl;std::cout << "(yaw,pitch,roll)" << data.euler[0] << " " << data.euler[1] << " " << data.euler[2] << std::endl;}}catch (std::exception &e){std::cerr << e.what() << std::endl;}
}
使用g++编译代码失败的话,可以参考关于库不在默认搜索路径时,g++链接库时找不到函数实现的问题。
如果要给设备起别名,可以参考Linux下给外部挂载的设备起别名,而不使用内核名称
Notice
如果结构体最后不接 attribute((packed)),经笔者测试,数据包大小变为36位。
相关文章:
c++通过serial库进行上下位机通信
编辑 风紊 现役大学牲,半退休robomaster视觉队员 写在前面 本文章主要介绍的是如何通过开源的serial库和虚拟串口实现上位机和下位机通信。 需求 假设下位机有这样一个数据报发送给上位机 struct DataRecv {char start s;TeamColor color TeamColor::Blu…...

【傻瓜级JS-DLL-WINCC-PLC交互】7.C#直连PLC并读取PLC数据
思路 JS-DLL-WINCC-PLC之间进行交互,思路,先用Visual Studio创建一个C#的DLL控件,然后这个控件里面嵌入浏览器组件,实现JS与DLL通信,然后DLL放入到WINCC里面的图形编辑器中,实现DLL与WINCC的通信。然后PLC与…...

指针常量和常量指针的区别
文章目录 指针常量常量指针即是指针常量又是常量指针 指针常量 指针常量的本质是常量,表示的是 这个指针所指向的地址不能发生改变。即指针变量的值(即地址值)不能发生修改。但是指针所指向的那块内存里的值是可以修改的。 注意:…...
离散化算法总结
离散化是将大范围的数字映射到小范围的区间内,适用于稀疏的区间。 两个问题需要考虑: 1. 原数组中可能有重复元素,需要去重。 2. 如何算出离散化后的值(离散化后保序,使用二分)。 题目链接: …...

【海思SS528 | VO】MPP媒体处理软件V5.0 | VO模块编程总结
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...

逻辑卷管理器lvm
啥意思,个人理解就是可以将物理分区合并一起组成大的磁盘,也可以移除其中的某个分区。 有四个概念需要了解下 PV,物理卷,VG 卷用户组,PE物理扩展块,LV逻辑卷 p物理,v卷,g用户组&a…...
函数声明后的“ - >”是什么?
这种语法的优势之一是可以在函数的返回类型中使用函数参数,使得返回类型更灵活。 先来看一个使用尾返回类型的例子: #include <iostream> auto add(int a, int b) -> int {return a b; }int main() {std::cout << add(3, 4) <<…...

51爱心流水灯32灯炫酷代码
源代码摘自远眺883的文章,大佬是30个灯的,感兴趣的铁汁们可以去看看哦~(已取得原作者的许可):基于STC89C51单片机设计的心形流水灯软件代码部分_单片机流水灯代码_远眺883的博客-CSDN博客 由于博主是个小菜鸡ÿ…...

将不同时间点的登录状态记录转化为不同时间段的相同登录状态SQL求解
题目 有不同时间点的登录状态记录表state_log如下 请使用sql将其转化为如下表的不同时间段的相同登录状态记录 思路分析: 此类问题需要用到lag或lead函数取上下行对应的数据,然后对前后结果做比较打标签(0或1),再…...
正则表达式与SQL数据库教程
使用正则表达式通过用例查询 Postgres 数据库: 正则表达式(又名 Regex) 正则表达式是一个强大的工具,广泛用于模式匹配和文本操作。 几乎所有编程语言都支持它们,并且经常用于文本提取、搜索和匹配文本等用例。 正则…...

HTML_web扩展标签
1.表格标签 2.增强表头表现 4.表格属性(实际不常用) 结构标签: 合并单元格: 更多请查看主页...

论文阅读:Distributed Initialization for VVIRO with Position-Unknown UWB Network
前言 Distributed Initialization for Visual-Inertial-Ranging Odometry with Position-Unknown UWB Network这篇论文是发表在ICRA 2023上的一篇文章,本文提出了一种基于位置未知UWB网络的一致性视觉惯性紧耦合优化测距算法( DC-VIRO )的分布式初始化方法。 对于…...

scrapy爬虫中间件和下载中间件的使用
一、关于中间件 之前文章说过,scrapy有两种中间件:爬虫中间件和下载中间件,他们的作用时间和位置都不一样,具体区别如下: 爬虫中间件(Spider Middleware) 作用: 爬虫中间件主要负…...

手敲单链表,简单了解其运行逻辑
1. 链表 1.1 结构组成 链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。 链表的结构如下图所示,是由很多个节点相互通过引用来连接而成的;每一个节点由两部分组成,分别数据域&…...

Redis RDB
基于内存的 Redis, 数据都是存储在内存中的。 那么如果重启的话, 数据就会丢失。 为了解决这个问题, Redis 提供了 2 种数据持久化的方案: RDB 和 AOF。 RDB 是 Redis 默认的持久化方案。当满足一定条件的时候, 会把当前内存中的数据写入磁盘, 生成一个快照文件 dump.rdb。Redi…...
Elasticsearch一些函数查询
1. 根据价格分组统计数量,每组区间为2000, filter_pathaggregations 设置查询结果只展示函数结果 也有date_histogram函数根据日期分组等等 GET order/_search?filter_pathaggregations {"aggs": {"hist_price": {"histogr…...

竞赛选题 : 题目:基于深度学习的水果识别 设计 开题 技术
1 前言 Hi,大家好,这里是丹成学长,今天做一个 基于深度学习的水果识别demo 这是一个较为新颖的竞赛课题方向,学长非常推荐! 🧿 更多资料, 项目分享: https://gitee.com/dancheng-senior/pos…...

Linux expect命令详解
在Linux系统中,expect 是一款非常有用的工具,它允许用户自动化与需要用户输入进行交互的程序。本文将深入探讨expect命令的基本语法、使用方法以及一些最佳实践。 什么是Expect命令? expect 是一个用于自动化交互式进程的工具。它的主要功能…...
ubuntu18编译Android8的Failed to contact Jack server问题
环境 ubuntu18.04 Android8.1.0 步骤 安装环境 apt install git-core apt install gnupg apt install flex apt install bison apt install gperf apt install build-essential apt install curl apt install libc6-dev apt install libssl-dev apt install libncurses5-dev:…...
FindSecBugs支持的检测规则
很多SAST集成了FindSecBugs这个开源工具,其好处是直接对Class文件进行检测,也就是直接检测二进制问题,可以直接检测war、jar,还是非常方便的。虽然误报率较高,但是这些检测出来的安全漏洞很多是安全从业人员耳熟能详的…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...

mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...
CppCon 2015 学习:Time Programming Fundamentals
Civil Time 公历时间 特点: 共 6 个字段: Year(年)Month(月)Day(日)Hour(小时)Minute(分钟)Second(秒) 表示…...

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...