MPU6050+HMC5883驱动程序
- 格式:docx
- 大小:30.41 KB
- 文档页数:17
2020.9一款心率戒指的设计Design of a heart rate ring杨风健1,孙艳红2,赵宏杰2(1.吉林医药学院 生物医学工程学院,吉林 吉林 132013;2.吉林市中医院,吉林 吉林 132011)摘 要:本文介绍了一款心率戒指的设计,利用光电传感器检测食指指间动脉的PPG信号,并对该信号进行放大、滤波处理,再利用STM32F103C8T6单片机内置A/D转换模块进行模拟/数字信号的转换和采样,最后编写单片机程序,通过FFT算法提取心率信息,另具有心率显示、蓝牙通信、运动检测功能。
本文详细论述了电路的设计思路、原理以及元器件参数,经测试,在运动幅度较小时,该电路可以实现对心率信号的稳定检测,在进行周期性幅度较大的运动时,尚需研究合适的算法消除运动伪差。
关键词:心率;戒指;PPG;FFT0 引言随着人们生活水平的提高,健康、便携、智能的生活理念已深入人心,对于可穿戴、人性化的健康产品,受到了人们广泛的关注[1]。
生活中,戒指是一种穿戴饰品,因其美观、小巧、不影响生活受到人们的广泛喜爱,传统戒指功能相对单一,仅具有装饰作用,已无法满足人们对于穿戴类产品的智能化需求。
目前,国内外检测心率的主要方法为:动脉血压法,光电测量法,动脉血压法,而比较适合在穿戴式设备上使用的方法为光电测量法[2],因此,本文基于光电测量法设计了一种具有心率检测、运动计步、蓝牙通信、锂电池供电、可充电功能的心率戒指。
1 设计思路1.1 手指PPG信号检测食指指间动脉循行如图1所示,根据人体动脉网络在手上的分布,可发现在每根手指两侧均有动脉血管走行,而食指指间动脉血流量相比其他手指更强一些,同一根手指的指根部位搏动最强,因此,本文选择的食指的手指根部内侧作为PPG 信号的采样点。
尽管如此,手指的PPG 信号依然相对较弱,而且受限于电路体积。
因此,PPG 信号的采集与处理仍然是本设计的一大难点。
作者简介:杨风健(1987—),男,硕士,吉林医药学院教师。
本章旨在讲解以下内容1.加速度2.陀螺仪3.磁力计MiniIMU AHRS姿态板销售网址:/作者:lisn31880序言一直想写篇文章关于姿态解算原理的,使用尽量通俗的语句说明如何从加速度计和陀螺仪的数据,融合得到载体的姿态角。
无奈自己的水平有限,一直搁置。
淡泊以明志,宁静以致远.人总是要逼自己做些事,才过得心安理得。
那就拿点时间把这方面的资料整合一下吧。
这篇文章的大部分内容都不是本人原创的,感谢网络上无私奉献的人.在此介绍一下实验的姿态板 ,新一代的mini AHRS ,采用STM32F103单片机进行姿态解算,板子上集成有1.MPU6050,三轴的加速度和陀螺仪2.HMC5883 三轴的磁力计3.BMP180 高精度气压高度计这些传感器都通过I2C 接口连接到主控制器STM32.不需要额外的ADC 电路,直接通过数字接口就可以读取传感器的当前输出.SDA BMP180气压高度计Mini AHRS 硬件框图Mini AHRS 是一个九轴的姿态仪模块,使用的都是数字器件,每一个传感器内部都集成有ADC ,只需要通过I2C 总线,就可以读取传感器当前输出。
现在我们不着急了解如何读出这些数据,先来认识一下这些传感器都是做什么,它们主要是测量哪些物理量,从加速度计开始。
1加速度计加速度计顾名思义,就是测量加速度的.那么,我们如何认识这个加速度呢?在此用一个盒子形状的立方体来做模型,认识加速度,如下,盒子内的图像。
如果我们把盒子形状的立方体 放在一个没引力场的地方,球会保持在盒子的中间.你可以想象,这个盒子是在外太空,远离任何天体,很难找到这样的地方,就想象飞船轨道围绕地球飞,一切都是在失重状态下。
那么六个壁面感受到的压力都是0.如果我们突然将立方体向左侧移动(我们加快加速,1G =9.8米/ S ^ 2),皮球打在了墙上X-。
然后,我们测量球适用于在X轴上的壁和输出-1g 值的压力。
如下图失重状态请注意,加速度计反应的加速向量与当前的受力方向是相反的.如上图所示,受力方向向左,但是加速度的向量方向为右.如果我们把这个小盒子拿来放在地球上,那么小球会落在Z-壁面上,并会为1G的底壁施加一个力,在下面的图片所示:在这种情况下,框不动,但我们仍然可以得到Z轴的读数-1G。
基于Arduino的四旋翼飞行器设计与实现作者:董瑞智李泽文徐振平来源:《电脑知识与技术》2017年第28期摘要:针对四旋翼飞行器姿态数据测量存在误差、控制算法选择较难的问题,该文选用Arduino开发板作为系统控制板,构建基于Arduino的四旋翼飞行器。
选择惯性测量单元六轴组件MPU6050、电子罗盘HMC5883L及气压计BMP085等多个MEMS传感器实时采集飞行器姿态数据,并由双闭环PID控制器实现对两组四路电机的转速控制。
为降低传感器数据的测量误差,该文采用卡尔曼滤波算法对飞行器姿态数据进行滤波与融合,为飞行器的姿态控制提供有利条件。
经飞行实验显示,该文设计的飞行器实现了悬停、升降和转弯等功能,并验证了该文使用卡尔曼滤波算法降低姿态数据测量误差和双闭环PID控制器控制飞行器状态的有效性。
关键词:四旋翼飞行器;MEMS传感器;卡尔曼滤波;姿态解算;PID控制中图分类号:TP391 文献标识码:A 文章编号:1009-3044(2017)28-0263-03Abstract: In order to solve the problem of the measurement error of the attitude data of the four rotor aircraft and the difficulty of the selection of the control algorithm. This paper uses Arduino development board as the system control board to build a Arduino based four rotor aircraft, and select some MEMS sensors, such as the inertial measurement unit six axis components MPU6050,HMC5883L electronic compass and barometer BMP085, to collect aircraft attitude data. Then, use double closed-loop PID controllers to control the speed of two groups of four motors. In order to reduce the measurement error of sensor data, the Calman filtering algorithm is used to filter and fuse the attitude data of aircraft, which provides favorable conditions for attitude control of spacecraft. The flight experiment shows that the design of the aircraft can hovering, lifting and turning function, and verified effectiveness of using the Calman filter algorithm to reduce the measurement error of attitude data and using double closed-loop PID controllers to control the state of the aircraft.Key words: quad-rotor helicopter; MEMS sensor; kalman filtering; attitude calculation;PID controller1 概述四旋翼飞行器,一种由4个转子推动飞行[1],六自由度垂直起降飞行器[2],能够完成悬停、飞行、垂直起降等功能。
Mpu9150STM32F103C8SCLSDA MPU6050 HMC5883LMpu6050传感器读取数据(ax,ay,az)(gx,gy,gz)HMC5883L传感器读取数据(mx,my,mz)数据结构使用I2C进行数据传输/*************************************************名称:iic_init(void)功能:iic外设1初始化(管脚配置总线速度数据位宽)输入参数:无输出参数:无返回值:无**************************************************/void iic_init(void){I2C_InitTypeDef I2C_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);/* PA6,7 SCL and SDA */GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_Init(GPIOA, &GPIO_InitStructure);I2C_DeInit(I2C2);I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_OwnAddress1 = 0x30;I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;I2C_InitStructure.I2C_ClockSpeed = 300000; //200KI2C_Cmd(I2C2, ENABLE);I2C_Init(I2C2, &I2C_InitStructure);/*允许1字节1应答模式*/I2C_AcknowledgeConfig(I2C2, ENABLE);}/*************************************************名称:iic_rw(u8 *data_buff, u8 byte_quantity, u8 reg_address, u8 slave_address, u8 control_byte) 功能:iic数据的读写输入参数:u8 *data_buff 数据输入输出指针u8 byte_quantity 数据个数u8 reg_address iic寄存器地址u8 slave_address iic器件地址u8 control_byte 读写控制字read=1 write=0输出参数:u8 *data_buff iic读取的数据内容返回值:无**************************************************/void iic_rw(u8 *DataBuff, u8 ByteQuantity, u8 RegAddress, u8 SlaveAddress, u8 ControlByte) {u8 errorflag = 1, j, i = 1;while(i--){/* 起始位*/I2C_GenerateSTART(I2C2, ENABLE);while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));/* 发送器件地址(写)*/I2C_Send7bitAddress(I2C2, SlaveAddress, I2C_Direction_Transmitter);while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));/*发送地址*/I2C_SendData(I2C2, RegAddress);while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));if(ControlByte == 0){j=ByteQuantity;errorflag = 0;while(j--){I2C_SendData(I2C2, *DataBuff++);while(!(I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_BYTE_TRANSMITTED)||I2C_SR1_AF));}I2C_GenerateSTOP(I2C2, ENABLE);}else{I2C_GenerateSTART(I2C2, ENABLE);while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT));/* 发送器件地址(写)*/I2C_Send7bitAddress(I2C2, SlaveAddress, I2C_Direction_Receiver);while(!I2C_CheckEvent(I2C2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); /* EV7 */while (ByteQuantity){if(ByteQuantity == 1){I2C_AcknowledgeConfig(I2C2, DISABLE); //最后一位后要关闭应答的I2C_GenerateSTOP(I2C2, ENABLE); //发送停止位}while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */*DataBuff = I2C_ReceiveData(I2C2);DataBuff++;/* Decrement the read bytes counter */ByteQuantity--;}I2C_AcknowledgeConfig(I2C2, ENABLE); //再次允许应答模式}}}数据中断处理/*************************************************名称:timer_init(void)功能:timer3外设初始化(中断定时时间)输入参数:无输出参数:无返回值:无**************************************************/void timer_init(void){TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;NVIC_InitTypeDef NVIC_InitStructure;/* Enable the TIM3 gloabal Interrupt */NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);/* Time base configuration */TIM_TimeBaseStructure.TIM_Period = 7200 - 1; // 0.1msTIM_TimeBaseStructure.TIM_Prescaler = 25 - 1; // (Period + 1) * (Prescaler + 1) / 72M = 2.5msTIM_TimeBaseStructure.TIM_ClockDivision = 0;TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);/* TIM3 enable counter */TIM_Cmd(TIM3, ENABLE);/* TIM IT enable */TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);}。
基于ARM11的海洋浮标云台稳定控制系统周金金;林志;王小英【摘要】由于载体姿态的变化和海浪等因素的影响,海洋浮标成像系统所获得的图像不稳定或者模糊,如何改变现状是人们不断探讨和研究的课题.结合陀螺传感器MPU6050和磁力计HMC5883L设计一套基于ARM11的云台稳定控制系统,通过S3C6410的I2C接口读取MPU6050和HMC5883L的数据,采用卡尔曼滤波算法对其进行处理,然后解算出载体的航向角和俯仰角,实现云台摄像机姿态的反向调整.当云台摄像机与PC相连时,对UleadVideoStudio软件进行简单的配置,便可看到云台摄像机所拍摄的视频信息.实验结果表明:云台将以水平速度280°/s、垂直速度100°/s完成反向偏转,最长反馈调整时间为0.38s,满足工程上的应用需求;该系统电路结构简单、成本低、可视化且稳定,可以移植到无人机及船舶监控等场合,具有一定的实用性.【期刊名称】《中国测试》【年(卷),期】2016(042)001【总页数】5页(P74-78)【关键词】MPU6050;HMC5883L;卡尔曼滤波;四元数;云台【作者】周金金;林志;王小英【作者单位】中国矿业大学信息与电气工程学院,江苏徐州221000;常熟理工学院电气与自动化工程学院,江苏常熟215500;常熟理工学院电气与自动化工程学院,江苏常熟215500;常熟理工学院电气与自动化工程学院,江苏常熟215500【正文语种】中文海洋资料浮标能够全天候、稳定不间断地对海洋中海水的温度、压力及气象等诸多数据进行采集,对海洋气候灾害的预测、海洋科学的研究以及资源的开发和利用等具有重要的现实意义[1-3]。
随着采集数据分析准确度要求的提高,可视化实时图像数据的作用越发显著。
而在现实监测环境中,由于成像系统工作时受其载体的姿态变化和海浪等因素的影响,将导致获得的图像信息不稳定或模糊,极大地限制了图像信息的有效利用。
MPU6050使⽤⼀阶互补和卡尔曼滤波算法平滑⾓度数据最近项⽬上想⽤MPU6050来⾃动探测物体的转向⾓度,花了2天时间学习如何拿陀螺仪的姿态⾓度,发现蛮难的,写点笔记。
下⾯是哔哩哔哩的⼀堆废话讲解,只想看代码本体的可以直接跳到最后。
应⽤场景是51单⽚机环境,有⼀块MPU6060,需要知道硬件板⼦⽔平摆放时,板⼦摆放的姿态和旋转的⾓度。
编译环境只能⽤C语⾔。
⾸先单⽚机通过TTL串⼝接到MPU6050上拿到通信数据,⽔平旋转⾓度需要另外加地磁仪通过南北极磁性拿到。
很遗憾设计硬件时没注意这茬,只⽤了⼀块MPU6050。
不过呢可以⽤旋转时的⾓速度求出旋转幅度(这个下篇说)。
但是拿到原始数据后,发现原始数据的跳动⾮常厉害,需要⽤带滤波的积分算法平滑过滤。
代码演⽰了计算Roll,Pitch⾓和Yaw⾓并⽤卡尔曼过滤算法。
样例⾥⾯有四种芯⽚的演⽰,我⽤的是MPU6050,就直接看这个⽬录了,⾥⾯还有MPU6050+HMC5883L磁⼒计的样式,可惜⼿头板⼦当初没有想过算Yaw⾓旋转要磁⼒计,也就莫法实现读取Yaw⾓。
加HMC5883L磁⼒计的那个样例,是读的磁⼒计的数据来算Yaw轴⾓度。
MPU6050的重⼒加速度出来的z轴数据基本不咋变化,仅依靠x和y轴数据肯定不准的,所以这⾥通过重⼒加速度算出来Yaw轴的⾓度⽆意义。
继续回来说代码。
下载回来的样例代码扩展名是.ino,搞不懂啥,改成.c,⼀样看,c语⾔万岁!⾸先要先拿到陀螺仪的数据,⾓速度和重⼒加速度。
如何读取MPU6050的数据我略过。
⽹上有很多现成的样例,直接拿来⽤。
/* IMU Data */float accX, accY, accZ;float gyroX, gyroY, gyroZ;accX = ((i2cData[0] << 8) | i2cData[1]);accY = ((i2cData[2] << 8) | i2cData[3]);accZ = ((i2cData[4] << 8) | i2cData[5]);//tempRaw = (i2cData[6] << 8) | i2cData[7];gyroX = (i2cData[8] << 8) | i2cData[9];gyroY = (i2cData[10] << 8) | i2cData[11];gyroZ = (i2cData[12] << 8) | i2cData[13];i2cData是MPU6050读到的14个字节的数据。
Multi-Rotor开源飞控用户手册V1.7修订日期2015.12.26恒拓科技版权本产品及手册为河北恒拓电子科技有限公司版权所有,未经书面许可,任何组织和个人不得以任何形式复制,翻版和发行。
如需引用需表明出处,并且不得对本手册进行有悖于原意的修改,删减和引用。
免责声明请用户在使用本产品前,务必仔细阅读本用户手册。
一旦使用本产品,即视为对本声明的所有内容表示认可和接受。
本产品适合18周岁以上人士使用。
在使用本飞控系统调试参数和进行固件升级时,为安全起见,我们强烈建议您卸下螺旋桨,进行无桨调试。
试飞时请务必远离人群,危险物品和易碎物品。
使用本产品时,发生以下原因直接或间接造成人身伤害和财产损失,恒拓科技将不承担赔偿责任:1.用户没有按照本手册的要求组装和使用;2.用户主动或故意操控飞行器制造伤害;3.用户操作失误或主观判断失误造成的伤害;4.飞行器自然磨损,电路老化等飞行器不正常工作造成的伤害;5.用户在明知飞行器处于非正常工作状态下任然操控飞行器飞行;6.用户在台风,冰雹,大雾等恶劣气象条件下仍然操控飞行器飞行;7.用户在磁场干扰区域,无线电干扰区域,正负禁飞区飞行;8.用户在能见度不良,视线受到遮挡的情况驾驶飞行器;9.用户使用本产品操控飞行器取得任何数据,影像资料等造成的侵权;10.其他不属于恒拓科技责任范围内的损失。
产品简介HT-Hawk是一款适用于多旋翼飞行器的开源飞行控制系统,支持四、六、八旋翼飞行器,是为多旋翼飞行器爱好者们开发的一种开源自动驾驶系统,可以实现姿态稳定功能,给用户提供卓越的飞行体验。
盒内物品清单●主控器X1●主控器外壳X1●Micro USB线X1 ●3M胶X3●三针伺服对接线X8 ●资料光盘X1●保修卡X1飞控硬件介绍● STM32F103VCT6:32Bit ARM Cortex-M3处理器,72MHZ 主频; ● MPU6050:三轴陀螺仪+三轴加速度计;● HMC5883L :三轴地磁传感器,检测地球磁场;● MS5611:气压高度计,检测飞行器高度;● AT24C256:Flash 芯片,用于存放数据;● OLED12864:显示屏接口,显示实时数据,方便用户开发;● LED 三色指示灯:状态指示灯,反应飞控当前状态;● Micro USB 接口:USB 虚拟串口,可以当做串口使用。
四轴飞行器报告(中级篇)姓名: 阿力木江艾合买提江高瞻完成日期: 2014年11月10日星期一报告内容1.软件架构及其思想2.模块选用及配型软件架构及其思想定时器4里面的任务,是整个飞机的核心,定时器3主要是配合上位机,用于调试测量任何一个处理器要正常运行后面的代码,首先必须得有一大段设备初始化的代码先运行,这些代码用于初始化处理器的内部时钟、中断优先级、I/O 口的输入输出方向等等,也就是为后续代码正常运行,做了一个环境配置准备。
飞行器的主控是Crotex-M3内核(STM32),其实就是ARM架构发展到一定阶段的产物。
Crotex-M3还是ARM架构。
于是,对ARM的初始化,首先必须要做的就是系统时钟初始化,中断向量表初始化,中断优先级初始化,I/O方向初始化,如下:STM32内部模拟E E P ROM初始化→LE D初始化→延时函数初始化→蓝牙电源使能初始化→电机P WM输出初始化→电池电压AD初始化→IIC总线初始化→传感器初始化→P ID参数初始化→无线收发模块初始化为接受模式→开蓝牙→开定时器3→开定时器4。
.接下来,程序运行到while(1),程序会一直停在这里,等待数据中断的到来。
在初始化代码段,我们说到初始化了两个定时器,一个定时器3,一个定时器4,这两个定时器都可以打断死循环w hile(1)。
定时器3用于广播机身姿态信息,定时器4用于更新遥控数据+机身姿态融合+P ID计算输出+P WM输出。
可以看到,定时器4里面任务的优先级明显要比定时器3实时性要求更高,所以。
中断优先级的顺序是:定时器4 > 串口中断 > 定时器3。
姿态更新频率为1000Hz,广播信息更新频率为1Hz。
可以看到定时器4的中断服务函数TIM4_IRQHandler()中,有个一Controler()。
而Controler()内部,DMP姿态输出→接收遥控器数据→接收串口数据→P ID计算+P WM输出,这些任务构成了Controler()函数。
姿态角解算(MPU6050 加速度计加陀螺仪)本文持续更新…I2C通信AHRS是自动航向基准系统(Automatic Heading Reference System)的简称。
目前,使用四元数来进行AHRS姿态解算的算法被广泛采用于四轴飞行器上。
IMU部分:IMU是惯性测量装置(Inertial Measurement Unit)的简称,通常包含陀螺仪和加速度计。
1.陀螺仪:测量的是角速度,即物体转动的速度,把速度和时间相乘,即可以得到某一时间段内物体转过的角度。
(但是积分运算得来的角度本身就存在误差,随着时间的累加,误差会加剧,此时就需要加速度计辅助计算出姿态角度)2.加速度计:测量的是物体的加速度,我们知道,重力加速度是一个物体受重力作用的情况下所具有的加速度。
当物体处于静止状态时,加速度计测量出来的值就等于重力加速度1g, 约等于9.8米每平方秒。
重力加速度g的方向总是竖直向下的,通过获得重力加速度在其X轴,Y轴上的分量,我们可以计算出物体相对于水平面的倾斜角度。
典型的IMU惯性测量芯片为MPU6050,它被广泛采用在四轴飞行器上。
mpu6050便是这两种传感器结合测出姿态角,通常运用卡尔曼滤波得出最终角度根据加速度计和地磁计的数据,转换到地理坐标系后,与对应参考的重力向量和地磁向量进行求误差,这个误差用来校正陀螺仪的输出,然后用陀螺仪数据进行四元数更新,再转换到欧拉角陀螺仪的角速度测量:如果他的速度是1度不加秒,我们用速度乘以时间就可以知道他从起点走了多少度。
加速度计来测量倾角:一个简单的例子如下: 一个单轴的加速计位于重力水平面上的时候,它在垂直方向上受到的加速度为1g,在水平方向上受到的加速度为0。
当我们把它旋转一个角度的时候,就会在水平轴上产生一个加速度分量。
通过它们的关系,就可以计算出该单轴加速计的倾角。
1.通过陀螺仪的积分来获得四轴的旋转角度2.然后通过加速度计的比例和积分运算来修正陀螺仪的积分结果。
基于虚拟现实的下肢主动康复训练系统LI Wenxiao;GUO Bingjing;HAN Jianhan;LI Xiangpan;MAO Yongfei【摘要】针对传统下肢康复训练中病人参与度低、主动运动意图逐渐丧失的问题,设计一种基于虚拟现实的下肢主动康复训练系统.该系统采用惯性检测单元(IMU)获取并解算下肢关节活动度,作为虚拟场景中的运动控制信号,并建立无线蓝牙通信机制,把患者下肢运动与运动功能康复训练游戏结合在一起.基于鞋内置多点足底力传感器(FSR)获取患肢足底力参数,识别步态相周期,作为康复评估的数据基础.实验验证了康复数据获取的准确性、交互通信的实时性与康复场景运行的流畅性.【期刊名称】《现代电子技术》【年(卷),期】2019(042)004【总页数】5页(P61-64,70)【关键词】虚拟现实;主动康复;下肢康复训练;传感系统;活动度;足底力【作者】LI Wenxiao;GUO Bingjing;HAN Jianhan;LI Xiangpan;MAO Yongfei 【作者单位】;;;;【正文语种】中文【中图分类】TN915.5-34;TP274随着社会老龄化的加剧,由脑卒中等导致的神经损伤引起的下肢功能障碍者逐年增加[1],严重影响患者的生活质量,给社会和家庭带来了沉重的负担。
传统的康复治疗多采用医师手工辅助完成,效率低、康复过程枯燥,已不能满足患者的需求[2]。
根据大脑神经可塑性理论、镜像神经元理论和运动康复理论,丰富的训练环境可以促进康复的进程[3],也可以有效地提高患者的训练兴趣和积极性,从而提高康复效率。
如德国柏林弗朗霍费尔研究所研制Haptic Walker机器人系统和加拿大蒙特利尔McGill大学研究的多自由度反馈的下肢训练器;当前的下肢康复训练设备多为在医疗机构中使用,价格昂贵[4],同时也需要医护人员的协助,缺乏可供患者使用的家庭便携式智能康复训练设备,不利于患者的自主训练。
#include "MPU6050.h"#include "includes.h"#include "math.h"u8 mpu6050_buffer[14];u8 hmc5883_buffer[6];float HMC5883_Angle_F;u16 HMC5883_Angle_D;int16_t ax,ay,az;S_INT16_XYZ GYRO_OFFSET,ACC_OFFSET;uint8_t GYRO_OFFSET_OK = 1;uint8_t ACC_OFFSET_OK = 1;S_INT16_XYZ MPU6050_ACC_LAST,MPU6050_GYRO_LAST;/**************************实现函数******************************************** //将iic读取到得数据分拆,放入相应寄存器******************************************************************************* /void MPU6050_Dataanl(void){MPU6050_ACC_LAST.X=((((int16_t)mpu6050_buffer[0]) << 8) | mpu6050_buffer[1])- 510; //ACC_OFFSET.X;MPU6050_ACC_LAST.Y=((((int16_t)mpu6050_buffer[2]) << 8) | mpu6050_buffer[3])- 42;//ACC_OFFSET.Y;MPU6050_ACC_LAST.Z=((((int16_t)mpu6050_buffer[4]) << 8) | mpu6050_buffer[5]);//- 16950;//ACC_OFFSET.Z;//跳过温度ADCMPU6050_GYRO_LAST.X=((((int16_t)mpu6050_buffer[8]) << 8) | mpu6050_buffer[9])-227;// - GYRO_OFFSET.X;MPU6050_GYRO_LAST.Y=((((int16_t)mpu6050_buffer[10]) << 8) | mpu6050_buffer[11])-18;// - GYRO_OFFSET.Y;MPU6050_GYRO_LAST.Z=((((int16_t)mpu6050_buffer[12]) << 8) | mpu6050_buffer[13])+110;//+26; //- GYRO_OFFSET.Z;VIEW_16_1=(int16_t)MPU6050_ACC_LAST.X;VIEW_16_2=(int16_t)MPU6050_ACC_LAST.Y;VIEW_16_3=(int16_t)MPU6050_ACC_LAST.Z;VIEW_16_4=(int16_t)MPU6050_GYRO_LAST.X;VIEW_16_5=(int16_t)MPU6050_GYRO_LAST.Y;VIEW_16_6=(int16_t)MPU6050_GYRO_LAST.Z;///////////////////////////////////////////////////////////////////////////////////////////////// ///if(!GYRO_OFFSET_OK)//开机时候得到陀螺仪的偏移值{static int32_t tempgx=0,tempgy=0,tempgz=0;static uint8_t cnt_g=0;//LED1_ON;if(cnt_g==0){GYRO_OFFSET.X=0;GYRO_OFFSET.Y=0;GYRO_OFFSET.Z=0;tempgx = 0;tempgy = 0;tempgz = 0;cnt_g = 1;return;}tempgx+= MPU6050_GYRO_LAST.X;tempgy+= MPU6050_GYRO_LAST.Y;tempgz+= MPU6050_GYRO_LAST.Z;if(cnt_g==200){GYRO_OFFSET.X=tempgx/cnt_g;GYRO_OFFSET.Y=tempgy/cnt_g;GYRO_OFFSET.Z=tempgz/cnt_g;cnt_g = 0;GYRO_OFFSET_OK = 1;return;}cnt_g++;}if(!ACC_OFFSET_OK)//开机时候得到加速度计的偏移值{static int32_t tempax=0,tempay=0,tempaz=0;static uint8_t cnt_a=0;//LED1_ON;if(cnt_a==0){ACC_OFFSET.X = 0;ACC_OFFSET.Y = 0;ACC_OFFSET.Z = 0;tempax = 0;tempay = 0;tempaz = 0;cnt_a = 1;return;}tempax+= MPU6050_ACC_LAST.X;tempay+= MPU6050_ACC_LAST.Y;tempaz+= MPU6050_ACC_LAST.Z;if(cnt_a==200){ACC_OFFSET.X=tempax/cnt_a;ACC_OFFSET.Y=tempay/cnt_a;ACC_OFFSET.Z=tempaz/cnt_a;cnt_a = 0;ACC_OFFSET_OK = 1;return;}cnt_a++;}}/**************************实现函数******************************************** //将iic读取到得数据分拆,放入相应寄存器,更新MPU6050_Last******************************************************************************* /void MPU6050_READ(void){i2cRead(MPU6050_Addr,MPU6050_RA_ACCEL_XOUT_H,14,mpu6050_buffer);}/**************************实现函数******************************************** *函数原型: u8 IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data)*功能: 读修改写指定设备指定寄存器一个字节中的1个位输入dev 目标设备地址reg 寄存器地址bitNum 要修改目标字节的bitNum位data 为0 时,目标位将被清0 否则将被置位返回成功为1失败为0******************************************************************************* /void IICwriteBit(u8 dev, u8 reg, u8 bitNum, u8 data){u8 b;i2cRead(dev, reg, 1, &b);b = (data != 0) ? (b | (1 << bitNum)) : (b & ~(1 << bitNum));i2cWrite(dev, reg, b);}/**************************实现函数******************************************** *函数原型: u8 IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data)*功能: 读修改写指定设备指定寄存器一个字节中的多个位输入dev 目标设备地址reg 寄存器地址bitStart 目标字节的起始位length 位长度data 存放改变目标字节位的值返回成功为1失败为0******************************************************************************* /void IICwriteBits(u8 dev,u8 reg,u8 bitStart,u8 length,u8 data){u8 b,mask;i2cRead(dev, reg, 1, &b);mask = (0xFF << (bitStart + 1)) | 0xFF >> ((8 - bitStart) + length - 1);data <<= (8 - length);data >>= (7 - bitStart);b &= mask;b |= data;i2cWrite(dev, reg, b);}/**************************实现函数******************************************** *函数原型: void MPU6050_setClockSource(uint8_t source)*功能: 设置MPU6050 的时钟源* CLK_SEL | Clock Source* --------+--------------------------------------* 0 | Internal oscillator* 1 | PLL with X Gyro reference* 2 | PLL with Y Gyro reference* 3 | PLL with Z Gyro reference* 4 | PLL with external 32.768kHz reference* 5 | PLL with external 19.2MHz reference* 6 | Reserved* 7 | Stops the clock and keeps the timing generator in reset******************************************************************************* /void MPU6050_setClockSource(uint8_t source){IICwriteBits(MPU6050_Addr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, source);}/** Set full-scale gyroscope range.* @param range New full-scale gyroscope range value* @see getFullScaleRange()* @see MPU6050_GYRO_FS_250* @see MPU6050_RA_GYRO_CONFIG* @see MPU6050_GCONFIG_FS_SEL_BIT* @see MPU6050_GCONFIG_FS_SEL_LENGTH*/void MPU6050_setFullScaleGyroRange(uint8_t range) {IICwriteBits(MPU6050_Addr, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, range);}/**************************实现函数******************************************** *函数原型: void MPU6050_setFullScaleAccelRange(uint8_t range)*功能: 设置MPU6050 加速度计的最大量程******************************************************************************* /void MPU6050_setFullScaleAccelRange(uint8_t range) {IICwriteBits(MPU6050_Addr, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, range);}/**************************实现函数******************************************** *函数原型: void MPU6050_setSleepEnabled(uint8_t enabled)*功能: 设置MPU6050 是否进入睡眠模式enabled =1 睡觉enabled =0 工作******************************************************************************* /void MPU6050_setSleepEnabled(uint8_t enabled) {IICwriteBit(MPU6050_Addr, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, enabled);}/**************************实现函数******************************************** *函数原型: void MPU6050_setI2CMasterModeEnabled(uint8_t enabled)*功能: 设置MPU6050 是否为AUX I2C线的主机******************************************************************************* /void MPU6050_setI2CMasterModeEnabled(uint8_t enabled) {IICwriteBit(MPU6050_Addr, MPU6050_RA_USER_CTRL, MPU6050_USERCTRL_I2C_MST_EN_BIT, enabled);}/**************************实现函数******************************************** *函数原型: void MPU6050_setI2CBypassEnabled(uint8_t enabled)*功能: 设置MPU6050 是否为AUX I2C线的主机******************************************************************************* /void MPU6050_setI2CBypassEnabled(uint8_t enabled) {IICwriteBit(MPU6050_Addr, MPU6050_RA_INT_PIN_CFG, MPU6050_INTCFG_I2C_BYPASS_EN_BIT, enabled);}void MPU6050_setDLPF(uint8_t mode){IICwriteBits(MPU6050_Addr, MPU6050_RA_CONFIG, MPU6050_CFG_DLPF_CFG_BIT, MPU6050_CFG_DLPF_CFG_LENGTH, mode);}/**************************实现函数******************************************** *函数原型: void MPU6050_initialize(void)*功能: 初始化MPU6050 以进入可用状态。