RM遥控键鼠控制总结

硬件&通信介绍

RM比赛中各个参赛队伍使用的都是大疆官方提供的遥控器套装,包括遥控器和接收机,接收机上共三个引脚:VCC,GND,DBUS(数据通道),首次使用需要进行遥控器和接收机配对,在两者都上电的情况下短按接收机上的对频按键即可(位于指示灯旁边)。在官方更新了遥控器的固件版本之后,遥控器上手轮也已经开放。

遥控器通讯采用的是2.4GHz频段的DBUS通讯协议,接收机工作电压为4-8.4V,输出信号满足TTL电平,但是为负逻辑,因此接收机和单片机之间需要加反相器来获得正确的数据(官方开发板的USART1接口已经集成)。

接收机的数据发送周期为14ms,每次发送18字节数据,和单片机通过串口通信,通信参数如下:

1.jpg

2.jpg

什么是DBUS?

DBUS是一个轻量级的IPC,用于进程间或进程与内核间的通信,DBUS通信结构下图:

Bus daemon(总线守护进程):DBUS是点对点进行通信,所以基本上DBUS进程连接的都是Bus daemon,Bus daemon负责将受到的DBUS信息进行路由、转发。DBUS进程将信息发送给Bus daemon,Bus daemon会结合消息的目标地址、对象路径、消息的类型、以及DBUS进程希望受到的信息进行综合,然后转发。

解码

遥控器的数据每一帧为18个字节,采用串口接收,每个字节都用CPU处理效率较低,因此考虑使用DMA,串口中断使能IDLE(线路空闲),当一帧数据接收完毕之后触发串口中断,调用DMA进行接收。官方手册提供了基于标准库的串口&DMA配置以及解码函数,在这里只贴出中断服务函数(HAL库)以及解码函数,串口和DMA略去。

代码实现(如果要使用请提前定义相关变量):

void RemotreCtl_Data_Receive(void)
{
uint32_t rx_data_len = 0;
if((__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)!=RESET)) //判断一帧数据是否接收完成
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1); //清空IDLE标志位
(void)USART1->SR; //清空SR寄存器
(void)USART1->DR; //清空DR寄存器
__HAL_DMA_CLEAR_FLAG(&hdma_usart1_rx,DMA_FLAG_TCIF2_6); //清除DMA传输完成标注
HAL_UART_DMAStop(&huart1); //停止DMA接收
rx_data_len=BSP_USART1_DMA_RX_BUF_LEN-__HAL_DMA_GET_COUNTER(&hdma_usart1_rx);//数据量
HAL_UART_Receive_DMA(&huart1,USART1_DMA_RX_BUF, BSP_USART1_DMA_RX_BUF_LEN); //读数据
if(rx_data_len== 18) //如果数据量正确,则进行解码
{
RC_DataHandle(USART1_DMA_RX_BUF);
}
}
}
2.解码函数
voidRC_DataHandle(uint8_t *pData)
{
if(pData == NULL)
{
return;
}
/*pData[0]为ch0的低8位,Data[1]的第三位为ch0的高三位*/
RemoteCtrlData.remote.ch0 =((uint16_t)pData[0] | (uint16_t)pData[1] << 8) & 0x07FF;
/*pData[1]的高5位为ch1的低五位,pData[2]的低6位为ch1的高6位*/
RemoteCtrlData.remote.ch1 = ((uint16_t)pData[1] >> 3 |(uint16_t)pData[2] << 5) & 0x07FF;
/*pData[2]的高2位为ch3的低二位,pData[3]为ch3的3~10位,pData[4]的最低位为ch3的最高位*/
RemoteCtrlData.remote.ch2 = ((uint16_t)pData[2] >> 6 |(uint16_t)pData[3] << 2 | (uint16_t)pData[4] << 10) & 0x07FF;
/*pData[4]的高7位为ch4的低7位,pData[5]的低4位为ch4的高4位*/
RemoteCtrlData.remote.ch3 = ((uint16_t)pData[4] >> 1 |(uint16_t)pData[5] << 7) & 0x07FF
/*pData[5]的高8位为S1*/
RemoteCtrlData.remote.s1 = ((pData[5] >> 6) &0x03);
/*pData[5]的6、7位为s2*/
RemoteCtrlData.remote.s2 = ((pData[5] >> 4) &0x03);
/*pData[6]和pData[7]鼠标x方向*/
RemoteCtrlData.mouse.x = ((int16_t)pData[6] |(int16_t)pData[7] << 8);
/*pData[8]和pData[9]为鼠标Y方向*/
RemoteCtrlData.mouse.y = ((int16_t)pData[8] | (int16_t)pData[9] << 8);
/*pData[10]和pData[11]为鼠标Z方向*/
RemoteCtrlData.mouse.z = ((int16_t)pData[10] | (int16_t)pData[11] << 8);
/*pData[12]为鼠标左键*/
RemoteCtrlData.mouse.press_l = pData[12];
/*pData[13] 为鼠标右键*/
RemoteCtrlData.mouse.press_r = pData[13];
/*pData[14]和pData[15]为键盘*/
RemoteCtrlData.key.v = ((int16_t)pData[14]) |((int16_t)pData[15] << 8);
}

在上面的代码里,DMA被用于UART通信,以实现高效的数据接收。

键鼠控制的小tips

键鼠控制和遥控器有所不同,按键存在延时,按下一个键该键值会被置高一段时间,并且在中断中不能通过延时来解决该问题。

按下按键之前:

3.jpg

短暂按下按键之后:

4.jpg

基本上短按都会持续 7~14次接收周期, 所以如果想要用按键做模式切换的话,至少需要延时20个接收周期,也就是在第一次接收到这个键之后20次接收中断中不再对这个键进行解码,因为模式切换通常来说不会在短时间内进行,所以我建议1S之内都不对这个按键进行解码,从而实现可靠模式切换。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/408966.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++类和对象(下):初始化列表、explicit关键字、友元函数、友元类

文章目录 C类和对象9、初始化列表9.1构造函数体赋值9.2初始化列表9.3 explicit&#xff08;显示&#xff09;关键字 10、友元10.1友元函数10.2友元类 C类和对象 9、初始化列表 一个类的构造函数要初始化成员变量有两种方式&#xff0c;一种是构造函数体赋值&#xff0c;另一种…

8.23-docker基础命令学习

docker 1.docker容器 [rootdocker ~]# systemctl start docker[rootdocker ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEcentos latest 5d0da3dc9764 2 years ago 231MB​# 容器执行完就退出了​[rootdocker ~]# docker run -it …

spring框架简介

文章目录 1.Spring的简介2.Spring的起源与发展3.Spring的核心体系介绍4.Spring框架的特点总结5.xml定义bean的相关属性1、class属性、id属性、name属性2、作用域属性3、初始化方法和销毁方法 1.Spring的简介 Spring的英文翻译为春天&#xff0c;可以说是给Java程序员带来了春天…

python爬虫——入门

一、概念 万维网之所以叫做网&#xff0c;是因为通过点击超链接或者进入URL&#xff0c;我们可以访问任何网络资源&#xff0c;从一个网页跳转到另一个网页&#xff0c;所有的相关资源连接在一起&#xff0c;就形成了一个网。 而爬虫呢&#xff0c;听名字就让人想起来一个黏糊…

设计模式篇(DesignPattern - 创建型模式)

目录 模式一&#xff1a;单例模式 一、简介 二、种类 1. 饿汉式(静态常量&#xff09; 1.1. 代码 1.2. 优缺点 2. 饿汉式&#xff08;静态代码块&#xff09; 2.1. 代码 2.2. 优缺点 3. 懒汉式(线程不安全) 3.1. 代码 3.2. 优缺点 4. 懒汉式(线程安全&#xff0c;…

Vulkan入门系列16 - 生成多级纹理贴图( Mipmaps)

一:概述 我们的程序现在可以加载和渲染 3D 模型了。在本章中,我们将再添加一项功能-- Mipmaps 生成。Mipmaps 广泛应用于游戏和渲染软件中,Vulkan 让我们可以完全控制 Mpmaps 的生成方式。 Mipmaps 是预先计算的、缩放的图像。每个新图像的宽度和高度都是前一个图像的一半。…

ssrf漏洞之——漏洞复现

漏洞介绍 SSRF漏洞&#xff1a;SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由恶意访问者构造url&#xff0c;由服务端对此url发起请求的一个安全漏洞。 漏洞原理 SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能&#xff0c;并且没有对目…

(QT-UI)十四、在时间轴上绘制一段段时间片

本系列预计实现 ①刻度上方文字显示&#xff0c; ②时间轴拖动效果&#xff0c; ③时间轴刻度缩放&#xff0c; ④时间轴和其他控件联动显示&#xff0c; ⑤鼠标放置到时间轴&#xff0c;显示具体时间。 ⑥通过定时器&#xff0c;实时更新时间轴 ⑦时间轴上绘制时间片 完…

用excel内容批量建立文件夹

建文件夹是电脑操作过程中比较常见的&#xff0c;但是用EXCEL内容批量建文件夹&#xff0c;这似乎不相关的两个操作&#xff0c;那么怎么实现这样的一个功能&#xff0c;我们需要用到专门的软件进行关联&#xff0c;推荐&#xff1a;可易文件夹批量生成器&#xff0c;这个软件有…

数据结构基础详解(C语言): 栈与队列的详解附完整代码

数据结构 栈 栈的核心重点&#xff1a; 栈是只能从表尾插入和删除的数据结构。 栈的顺序存储结构由两部分组成&#xff0c;top指针和数组。 链栈其实本质就是单链表头插法 文章目录 数据结构 栈1.栈的基本概念1.1 栈的常用操作 2.栈的存储结构2.1 栈的顺序存储结构2.1.1 栈的定…

AVL树的旋转

目录 一、AVL树的概念 二、AVL树节点的定义 三、AVL树的插入 四、AVL树的旋转 4.1右单旋 4.2左单旋 4.3左右双旋 4.4右左双旋 五、AVL树的验证 六、AVL树的性能 一、AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化…

【AI绘画】Midjourney提示词详解:精细化技巧与高效实践指南

文章目录 &#x1f4af;Midjourney提示词基础结构1 图片链接1.1 上传流程 2 文字描述3 后置参数 &#x1f4af;Midjourney提示词的文字描述结构全面剖析1 主体主体细节描述2 环境背景2.1 环境2.2 光线2.3 色彩2.4 氛围 3 视角4 景别构图5 艺术风格6 图片制作方法7 作品质量万能…

鸿蒙(API 12 Beta3版)【使用Image完成图片接收器】图片开发指导依赖JS对象

图像接收类&#xff0c;用于获取组件surface id&#xff0c;接收最新的图片和读取下一张图片&#xff0c;以及释放ImageReceiver实例。 开发步骤 添加依赖 在进行应用开发之前&#xff0c;开发者需要打开native工程的src/main/cpp/CMakeLists.txt&#xff0c;在target_link_…

文章中的错字一并替换成正确的字

with open("文件路径"&#xff0c;"模式"&#xff0c;"编码") as file ("r" 是读&#xff0c;"w"是写) with open(r"D:\python-installer\python-code\pythonProject\src\关于文件操作练习/人物介绍.txt",&quo…

PHP酒店宾馆民宿预订系统小程序源码

酒店宾馆民宿预订系统&#xff1a;一键解锁完美旅行住宿新体验 &#x1f31f; 开篇&#xff1a;告别繁琐&#xff0c;拥抱便捷预订新时代 在这个快节奏的时代&#xff0c;每一次旅行的规划都希望能尽可能高效与省心。想象一下&#xff0c;在规划一场说走就走的旅行时&#xf…

docker基本环境搭建

前面在虚拟机centos中搭建的fastdfs和minio分布式文件存储服务都是手动编译安装的&#xff0c;为了方便后续学习&#xff0c;本地开发环境的中间件服务部署&#xff0c;我们将交给docker来部署。下面先进行docker环境搭建。 后续相关教程&#xff08;待更新&#xff09;&#…

iOS RunLoop

一:什么是Runloop Runloop&#xff0c;正如其名&#xff0c;loop表示某种循环&#xff0c;和run放在一起就表示一直在运行着的循环 二:Runloop的创建? iOS并没有提供Runloop的创建方法,因为创建了现场自然会有一个Runloop. 所以只有获取Runloop的方法: NSRunLoop * runloo…

selenium学习记录

1、初识selenium 概述&#xff1a; Selenium是一个Web的自动化测试工具&#xff0c;最初是为网站自动化测试而开发的&#xff0c;类型像我们玩游戏用的按键精灵&#xff0c;可以按指定的命令自动操作&#xff0c;不同是Selenium 可以直接运行在浏览器上&#xff0c;它支持所有…

TXT文件转换pdf格式的java方法

<dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13.2</version> </dependency>接下来&#xff0c;编写一个方法来执行文件转换&#xff1a; import com.itextpdf.text.Document…

计算机网络-物理层

物理层 基本概念 物理层考虑怎样才能在连接各种计算机的传输媒体上传输数据比特流 物理层为数据链路层屏蔽了各种传输媒体的差异&#xff0c;使数据链路层只需要考虑如何完成本层的协议和服务&#xff0c;而不必考虑网络具体的传输媒体是什么 物理层协议主要任务 机械特性&am…