RM遥控键鼠控制总结

2024-08-25 23:44
文章标签 总结 控制 rm 遥控 键鼠

本文主要是介绍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之内都不对这个按键进行解码,从而实现可靠模式切换。

这篇关于RM遥控键鼠控制总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1106959

相关文章

浅析如何使用Swagger生成带权限控制的API文档

《浅析如何使用Swagger生成带权限控制的API文档》当涉及到权限控制时,如何生成既安全又详细的API文档就成了一个关键问题,所以这篇文章小编就来和大家好好聊聊如何用Swagger来生成带有... 目录准备工作配置 Swagger权限控制给 API 加上权限注解查看文档注意事项在咱们的开发工作里,API

Python中连接不同数据库的方法总结

《Python中连接不同数据库的方法总结》在数据驱动的现代应用开发中,Python凭借其丰富的库和强大的生态系统,成为连接各种数据库的理想编程语言,下面我们就来看看如何使用Python实现连接常用的几... 目录一、连接mysql数据库二、连接PostgreSQL数据库三、连接SQLite数据库四、连接Mo

Git提交代码详细流程及问题总结

《Git提交代码详细流程及问题总结》:本文主要介绍Git的三大分区,分别是工作区、暂存区和版本库,并详细描述了提交、推送、拉取代码和合并分支的流程,文中通过代码介绍的非常详解,需要的朋友可以参考下... 目录1.git 三大分区2.Git提交、推送、拉取代码、合并分支详细流程3.问题总结4.git push

Spring IOC控制反转的实现解析

《SpringIOC控制反转的实现解析》:本文主要介绍SpringIOC控制反转的实现,IOC是Spring的核心思想之一,它通过将对象的创建、依赖注入和生命周期管理交给容器来实现解耦,使开发者... 目录1. IOC的基本概念1.1 什么是IOC1.2 IOC与DI的关系2. IOC的设计目标3. IOC

Kubernetes常用命令大全近期总结

《Kubernetes常用命令大全近期总结》Kubernetes是用于大规模部署和管理这些容器的开源软件-在希腊语中,这个词还有“舵手”或“飞行员”的意思,使用Kubernetes(有时被称为“... 目录前言Kubernetes 的工作原理为什么要使用 Kubernetes?Kubernetes常用命令总

Python中实现进度条的多种方法总结

《Python中实现进度条的多种方法总结》在Python编程中,进度条是一个非常有用的功能,它能让用户直观地了解任务的进度,提升用户体验,本文将介绍几种在Python中实现进度条的常用方法,并通过代码... 目录一、简单的打印方式二、使用tqdm库三、使用alive-progress库四、使用progres

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Java向kettle8.0传递参数的方式总结

《Java向kettle8.0传递参数的方式总结》介绍了如何在Kettle中传递参数到转换和作业中,包括设置全局properties、使用TransMeta和JobMeta的parameterValu... 目录1.传递参数到转换中2.传递参数到作业中总结1.传递参数到转换中1.1. 通过设置Trans的

C# Task Cancellation使用总结

《C#TaskCancellation使用总结》本文主要介绍了在使用CancellationTokenSource取消任务时的行为,以及如何使用Task的ContinueWith方法来处理任务的延... 目录C# Task Cancellation总结1、调用cancellationTokenSource.

Python实现局域网远程控制电脑

《Python实现局域网远程控制电脑》这篇文章主要为大家详细介绍了如何利用Python编写一个工具,可以实现远程控制局域网电脑关机,重启,注销等功能,感兴趣的小伙伴可以参考一下... 目录1.简介2. 运行效果3. 1.0版本相关源码服务端server.py客户端client.py4. 2.0版本相关源码1