查看:
20550
回复: 21 |
参赛作品《基于STM32和mpu6050的空中鼠标的设计与实现》
|
|
发表于2017-06-23 07:44:59
|
显示全部楼层
1#
电梯直达
1. 参赛者姓名(必填项):苏远柱 2. 单位或学校名称(必填项):五邑大学 3. 当前职务或职称(必填项):学生 4. 参赛作品的名字(必填项):基于STM32和mpu6050的空中鼠标的设计与实现 5. 简要陈述您的idea和作品(必填项): 随着电子技术的飞速发展,各类电子芯片在性能不断提高的同时价格却在不断降低,本文将采用STM32F103来制作一款空中鼠标,在方便实用的同时整体成本又比较低廉。目前市面广泛应用的光电鼠标是通过一个发光二极管发出光线经过桌面、鼠标垫等平面反射后传到光感应器件来分析运动轨迹并传输给电脑.它的原理决定它必须要一块相对平整的反射面才能正常工作,在一些特殊场合使用时将会受到限制。本文介绍的空中鼠标在空中即可实现普通光电鼠标的功能,如传统鼠标一样操作电脑,能够实现脱离平台、增大距离控制电脑,使用十分方便。 近年来,空中鼠标以其灵活控制以及不需要支撑物体的优点,被广泛的应用于智能家居控制领域。而现有的大部分应用于智能家居的空中鼠标的算法复杂度大、硬件配置要求高且不易于实现。因此,设计一款低复杂度、低硬件要求的空中鼠标对于智能家居的控制具有极大的价值。 为此,本设计基于MPU6050传感器,设计了一款低算法复杂度、低硬件要求的空中鼠标。文中针对空中鼠标设计过程中的关键问题即空中鼠标姿态的确定进行深入的研究,最终确定利用加速度计的静态特性补偿陀螺仪零点漂移来进行鼠标姿态解算的设计方案。该设计方案主要包含两个方面优化和改进:第一,在传感器数据预处理阶段,针对数值标定后,数值波动性较大的问题,增加了滑动窗口滤波环节,对数据进行平滑处理。第二,在姿态解算阶段,主要考虑俯仰角角和横滚角角度信息的准确性,因而只用加速度计补偿陀螺仪零点漂移,节约了成本。最后,配合空中鼠标的软硬件设计,实现鼠标指针指示、左键单双击、右键单双击、左键长按的功能。另外,在设计过程中,还兼顾到了鼠标低功耗以及传输距离的要求 6. 拟用到的立创商城在售物料(必填项): stm32f103c8t6芯片 MPU6050芯片 NRF2401模块 USB接口等等 7. 拟用到的非立创商城物料或其它补充(必填项): MPU6050模块 STM32f103c8t6最小系统板
一、作品简介 普通的光电鼠标通过底座的LED灯以一定角度照射在桌面上,在鼠标移动时反射光线通过一块透镜传入传感器来得到连续的图案,然后通过对比前后的图案变化来分析鼠标的位移来得到鼠标在二维坐标的具体移动数值,最终将数据传送给电脑。正是由于工作原理的限制,所以在实际使用中光电鼠标在一些特殊的场合使用将受到限制。不同于光电鼠标的位移检测原理,本设计的位移检测是通过MPU6050芯片来检测空间的对应坐标方向的角速度,由于MPU6050是六轴运动处理器件,而电脑鼠标指针的移动是二维平面,所以只用读取X轴和Z轴的角速度,进行姿态解算处理。然后STM32F103芯片读取对应值后通过NRF24L01无线传输模块将数据发送至数据接收端,接收端通过USB接口将数据发送至电脑从而实现鼠标的功能。
二、系统构架图 空中鼠标发射端包括传感器模块、按键模块、MCU及射频模块。传感器模块包括三轴加速度计以及三轴陀螺仪,该模块主要负责采集鼠标空中姿态数据,即鼠标运动的加速度及角速度运动信息。按键模块主要负责监测用户何时按下按键以及按下哪一个按键。MCU端主要对传感器采集的数据和按键信息进行处理,确定鼠标的姿态和按键信息,并将处理好的数据放入射频模块缓存区,由射频模块将数据发送到鼠标的接收端。在接收端,空中鼠标的技术核心在于鼠标姿态的确定,这需要用到惯性导航理论中的惯性导航定姿算法。
图2-1 空中鼠标发射端系统框图 空鼠接收端由射频模块、MCU、USB端口组成。接收端的射频模块主要负责接受发送端射频模块发送来的鼠标数据。MCU负责将这些数据组合成USB报文的格式放入USB的端点缓冲区,发送给上位机。
图2-2 空中鼠标接收端系统框 三、硬件部分的描述 本设计的位移检测是通过MPU6050芯片来检测空间的对应坐标方向的角速度,由于MPU6050是六轴运动处理器件,而电脑鼠标指针的移动是二维平面,所以只用读取X轴和Z轴的角速度,进行姿态解算处理。然后STM32F103芯片读取对应值后通过NRF24L01无线传输模块将数据发送至数据接收端,接收端通过USB接口将数据发送至电脑从而实现鼠标的功能。原理图和PCB如下图所示(使用软件为AD、自己学习不作商业用途):
图3-1 空中鼠标接收端原理图
图3-2 空中鼠标发射端原理图
图3-3 空中鼠标接收端PCB
图3-4 发射端PCB 图3-5 热转印的PCB 图3-6 热转印的实物图证面 实物图赶来啦,O(∩_∩)O哈哈~。丑了点的样子。 学生没去打工业板,只能自己动手用热转印做板子啦啦啦啦,而且为了方便制作,使用3.7V航模电池供电。接收板使用STM32F103C8T86最小系统板和底板USB电路配合形成了接收系统。发送板使用了NRF24L01和MPU6050模块,底板的STM32驱动部分也是自己画的,制作这个底板啊。那个线细的比头发还小,一不小心就完啦。好啦,空中鼠标目前实现了的功能有,鼠标移动、左键、右键、单击、双击、滚轮。 后期优化添加内容:接收端加入TF卡功能,开发类似于U盘的功能(毕竟钻用啦电脑端的一个USB接口,单单用于空中鼠标接收端就亏啦)。 发送端加上激光线、一键鼠标定位。 四、材料清单(BOM列表) STM32F103C8T6芯片 http://www.szlcsc.com/so/global.html MPU6050芯片 http://www.szlcsc.com/so/search/global.html&global_search_keyword=mpu6050&global_current_catalog=&search_type=drop_box NRF24L01无线通信模块 http://www.szlcsc.com/so/search/global.html&global_search_keyword=nrf24l01&global_current_catalog=&search_type=drop_box USB-A接头 http://www.szlcsc.com/so/search/global.html&global_search_keyword=usb-a&global_current_catalog=&search_type=drop_box
列出您这个作品所用到的主要器件(关键器件即可),比如单片机&ARM芯片、专用集成芯片(ASIC)、传感器、功能模块等。 如果所列出的芯片是来自我们立创商城上的,最好能写出该器件的商品编号或附上对应购买链接。 五、软件部分的描述 由于本设计分为发射端和接收端两个部分,所以编程也要分开进行。发射部分主要包括MPU6050数据读取,按键数据读取,数据发送。接收端编程主要为数据接收,与PC的USB通讯。因为STM32F103系列芯片都自带了USB,符合USB2.0规范,所以通讯十分方便。在调试时可以使用四轴飞行器上的上机位软件调试发射部分的程序,分模块进行调试。 (1)空中鼠标发送端程序设计 空中鼠标发送端固件程序框架本论文设计的鼠标具有指针指示、左键单、双击,左键长按,右键单、双击,右键长按以及鼠标滚轮等功能。其软件流程图如图2-7所示:
图5-1 空中鼠标发射端程序框图 系统在上电之后,首先进行时钟、I2C、SPI、以及姿态测量单元的初始化。接着进行按键检测,判断有无按键按下,如果有按键按下,接着判断是左键还是右键,如果是左右键按下,立刻发送左右键按下的报文。如果没有按键按下,就采集MPU6050中的加速度计和陀螺仪传感器数据,经过算法处理后得到鼠标Yaw、Pitch、Roll的信息,(Roll的相对位移作为鼠标x轴方向上的位移,将Picth的相对位移作为鼠标y轴方向上的位移),将数据打包发送出去。 (2)MPU6050驱动程序设计 主控制器STM32F103通过I2C接口与MPU6050相连接,数据在主机和从机(MPU6050)之间通过SCL时钟同步在SDA数据线上实现一字节一字节的同步传输,每个字节为8位长度,一个SCL时钟脉冲传输一个数据位,数据由最高位MSB开始传输。 驱动MPU6050的流程大概为: ①初始化IIC接口 ②复位MPU6050。由电源管理寄存器1(0X6B)控制。 ③设置角速度传感器和加速度传感器的满量程范围。由陀螺仪配置寄存器(0X1B)和加速度传感器配置寄存器(0X1C)设置 。 ④设置其他参数。配置中断,由中断使能寄存器(0X38)控制;设置AUX IIC接口,由户控制寄存器(0X6A)控制;设置FIFO,由FIFO使能寄存器(0X23)控制;陀螺仪采样率 ,由采样率分频寄存器(0X19)控制;设置数字低通滤波器,由配置寄存器(0X1A)控制。 ⑤设置系统时钟。由电源管理寄存器1(0X6B)控制。一般选择x轴陀螺PLL作为时钟源,以获得更高精度的时钟。 ⑥使能角速度传感器(陀螺仪)和加速度传感器。由电源管理寄存器2(0X6C)控制 初始化完成,即可读取陀螺仪、加速度传感器和温度传感器的数据了。 (3)姿态解算 MPU6050 DMP输出的是姿态解算后的四元数,采用q30格式,也就是放大了2的30次方,我们要得到欧拉角,就得做一个转换,代码如下:
q0=quat[0] / q30; //q30格式转换为浮点数 q1=quat[1] / q30; q2=quat[2] / q30; q3=quat[3] / q30; //计算得到俯仰角/横滚角/航向角 pitch=asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; //俯仰角 roll=atan2(2 * q2 *q3+2 * q0 * q1, -2 * q1 * q1- 2 *q2*q2 +1)* 57.3;//横滚角 yaw=atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //航向角
quat[0]~quat[3]:是MPU6050的DMP解算后的四元数,q30格式。 q30:是一个常量:1073741824,即2的30次方。 57.3:是弧度转换为角度,即180/π,这样结果就是以度(°)为单位的。 (4)STM32的USB虚拟串口程序设计 首先是枚举过程中的获取设备描述符部分,主机如果要识别成串口,就要将此USB设备的描述符写成虚拟串口的描述符,要根据CDC类通信协议进行编写。 此程序设备描述符是一个数组,数组的成员是描述符的内容。 下面定义的数组即是设备描述符。 const uint8_t Virtual_Com_Port_DeviceDescriptor[] = { 0x12, /* 描述符字节长度*/ USB_DEVICE_DESCRIPTOR_TYPE, /* 设备描述符类型*/ 0x00, 0x02, /* USB规范发布号,表示用哪种协议,0x20表示USB2.0*/ 0x02, /* 类型代码 即CDC */ 0x00, /* 子类型代码 */ 0x00, /* 协议代码*/ 0x40, /* 端点0最大分组大小,值为,8、16、32、64*/ 0x83, 0x04, /* 供应商ID*/ 0x40, 0x57, /* 产品ID。由产品ID和供应商ID,就可以让操作系统加载不同的驱动程序*/ 0x00, 0x02, /* 设备出产编码*/ 1, /* 制造商标示符*/ 2, /* 产品标示符*/ 3, /* 设备串口号描述符*/ 0x01 /* 可能配置数,指配置字符串的个数*/ }; 在枚举前期,USB主机发送SETUP包,然后获取设备描述符,然后会得知设备的类型,再加载相应的驱动,此时USB虚拟串口就成功了。完成枚举之后,就可以编写作为串口接收和发送数据的程序了。 在此设计中我们只需用到STM32的GPIOA,GPIOB和串口以及USB时钟。所以先要允许GPIOA,GPIOB和串口的时钟。USB时钟会在接下来使能。 下面看第一个Set_System()函数: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO_DISCONNECT, ENABLE); 这个函数叫允许USB断开线。通过查看RCC_APB2Periph_GPIO_DISCONNECT在程序中的定义为RCC_APB2Periph_GPIOA。 而USB_DISCONNECT_PIN在程序中定义的为GPIO_Pin_11。是程序定义的断开线引脚是PA11,查看STM32引脚图可以看出PA11是连接USB引脚的DM引脚。 此引脚连接到一个上拉电阻控制的三极管上面,接下来将USB的断开引脚即PA11配置成上拉的。这也就意味着在开始时这个上拉电阻使得三极管导通,从而使时DP脚被加上一个1.5K的电阻,这样就可以开始枚举了。 第二个函数Set_USBClock(),这个函数就是先将USB所在的总线AP1经过PLL分频,得到AP1时钟,然后再允许USB时钟使能。 第三个函数USB_Interrupts_Config(),由名字可以看出是配置USB中断的。在该函数中使能了两个中断,一个是USB,一个是串口。程序中没有设定它们的抢占优先级,故默认它们的优先级分组相同,USB的响应优先级为0,串口的响应优先级为1,由于抢占优先级相同,不存在嵌套关系,故这两个中断都不会被另一个中断打断。在它们中断函数里面是我要处理的各个事情, USB_Init()中,pInformation 指向Device_Info结构体,pProperty指向Device_Property结构体;将pUser_Standard_Requests指针指向User_Standard_Requests结构体。这三个结构体都是与具体设备枚举和功能实现相关的。 DEVICE_PROP中的Virtual_Com_Port_init()这个函数。这个函数通过查看可以看到几个函数: 1) Get_SerialNum(),此为获取设备序列号,转变为Unicode字符串。 2) Power On(),连接USB设备,实质是让主机检测到USB设备。 3) USART_Config_Default(),配置串口至缺省状态,在这里波特率被设置为9600, 并且允许了接收中断。发送中断没有允许。 4) bDeviceState = UNCONNECTED,将当前状态定义为未连接状态。 中断函数是串口的接受中断,程序中串口的发送中断是没有允许的。那么串口是如何发送数据呢?不用中断方式,那就是直接来用写寄存器方式来发送了。不过写寄存器方式,当有大量数据发送时就会出现问题,因为它没有判断是否发送缓冲区为空。 串口接收中断调用的函数为USART_To_USB_Send_Data()。函数功能是从串口向USB端发送数据。然后数据再从USB端向主机发送,这样就可以与主机相互通信了。 六、作品演示 请上传您的作品的功能演示到腾讯视频,并编辑到本楼(或附上视频链接)。按要求上传视频可获得5分,具体详见活动规则。 腾讯视频:https://v.qq.com/x/page/w05391dqizd.html
空中鼠标目前实现了的功能有,鼠标移动、左键、右键、单击、双击、滚轮。 后期优化添加内容:接收端加入TF卡功能,开发类似于U盘的功能(毕竟钻用啦电脑端的一个USB接口,单单用于空中鼠标接收端就亏啦)。 发送端加上激光线、一键鼠标定位。 七、总结
首先衷心感谢立创商城、ST公司的支持,为我们提供了一个制作的平台和机会,使我们受益匪浅。
本次基于STM32F103和MPU6050的空中鼠标设计硬件部分较为简单,体积较小,节能稳定,发射部分采用锂电池供电,可以反复充电,减少了不必要的开支,接收部分直接通过电脑的USB端口供电,数据传输和供电共用一个USB接口,减少了电脑端口的占用。整体来说,本设计可以方便地在空中实现鼠标指针的位移控制和左右键功能,实现了基本鼠标功能,满足普通使用,在一些特殊场合比如户外,工业前线等等,具有光电鼠标不具备的优势,对实际应用具有一定的意义。同时对MPU6050和STM32来说,本设计仅仅用到了部分功能,仍有很大的改进空间来升级功能和完善使用体验。
编辑原因:完善标题中的作品名 |
|
发表于2021-10-07 11:35:45
|
显示全部楼层
19#
标记
|
|