MPU6050

例程资料链接如下(群文件也可下载):

BD网盘链接:

https://pan.baidu.com/s/1lM3s3uZu4iEsKWiVAFFxbg 

提取码:oqe6

一、简介

1. MPU6050是一种常用的六轴姿态传感器模块,结合了三轴陀螺仪和三轴加速度计,以及一个可扩展的数字运动处理器DMP(Digital Motion Processor),可用I2C接口连接一个第三方的数字传感器,比如磁力计。MPU6050 对陀螺仪和加速度计分别用了三个16 位的ADC(0~65535),将其测量的模拟量转化为可输出的数字量。为了精确跟踪快速和慢速的运动,传感器的测量范围都是用户可控的,陀螺仪可测范围为±250,±500,±1000,±2000°/秒(dps),加速度计可测范围为±2,±4,±8,±16g。并有可编程的低通滤波器。MPU6050模块的应用场景非常广泛,包括但不限于以下几个领域:

(1)姿态感知与控制:通过读取陀螺仪和加速度计的数据,可以实时获取物体的姿态信息,如倾斜角度、旋转角度等。这在飞行器、机器人、无人车等项目中非常常见,用于实现姿态感知和控制。

(2)运动跟踪与手势识别:MPU6050可以用于捕捉人体运动轨迹,如手部的姿态和手势,从而实现运动跟踪、手势识别、虚拟现实交互等应用。

(3)震动检测与防抖:结合加速度计,MPU6050可以检测到物体的震动和冲击,用于防抖技术、硬盘保护、运动检测等。

(4)步态分析与健康监测:MPU6050可以用于分析人体的步态特征和动作,用于健康监测、运动分析、姿势校正等。

二、所需物料+寄存器说明

.本实验使用到了CW32F030C8小蓝板、GY-521模块、0.96寸OLED显示屏Keil5开发环境

1.png

CW32F030C8小蓝板

2.png   

GY-521模块

   3.png

实物展示

【GY-521模块与单片机连线】:VCC<-->+3.3V

GND<-->GND

SCL<-->PB5

SDA<-->PB4

【OLED显示屏与单片机连线】:VCC<-->+3.3V

GND<-->GND

SCL<-->PA1

SDA<-->PA2

注:SCL和 SDA是连接MCU的 IIC接口,MCU通过这个IIC 接口来控制MPU6050,另外还有一个 IIC 接口: XCL和XDA ,这个接口可用来连外部从设备比如磁力计,这样就可以组成一个九轴传感器。AD0是MPU6050的地址控制引脚,该引脚控制的是IIC 地址的最低位。MPU6050的默认IIC地址是:0X68,如果AD0接VDD,则是0X69。需要注意的是:这里的地址0x68(110 1000)和0x69(110 1001)是不包含最低位的7位数据,通常最低位用于表示IIC主机的读取数据/写数据模式。如默认情况下对MPU6050进行写操作,则发送地址0xD0(1101 0000),读操作则发送地址0xD1(1101 0001)。

寄存器说明:

 4.png

该寄存器是配置陀螺仪输出速率的分频器,用于为MPU-6050生成采样速率。这里有个公式:采样频率=陀螺仪输出频率/(1+采样分频数)。当 DLPF(数字低通滤波器,见寄存器Configuration)禁用时,陀螺仪输出频率为8kHz;当 DLPF 使能,陀螺仪输出频率=1KHz。 5.png

该寄存器为陀螺仪和加速度计配置外部帧同步(FSYNC) 管脚的采样和数字低通滤波(DLPF)设置。其中,数字低通滤波器DLPF由DLPF_CFG配置。根据下表所示的DLPF_CFG值对加速度计和陀螺仪进行滤波。

 6.png

FS为陀螺仪输出频率。SMPLRT_DIV由预设定的采样频率根据上述的公式计算得出。一般情况下,DPLF滤波频率为采样频率的一半,如设定采样频率为50Hz,由表可知当FS为1kHz,SMPLRT_DIV的值为1000/50-1=19。

6.png 

该寄存器是用来触发陀螺仪自检和配置陀螺仪的满量程范围。其中,XG_ST、YG_ST、ZG_ST分别用来设置陀螺仪X轴、Y轴、Z轴自检,置0则不触发自检。FS_SEL[1:0]用于设置陀螺仪的满量程,如下表:

 7.png

我们一般设置为3,即满量程为±2000°/s

8.png

该寄存器是用来触发加速度计自检和配置加速度计的满量程范围。同时这个寄存器也可以用于配置数字高通滤波器(DHPF)。其中,XA_ST、YA_ST、ZA_ST分别用来设置加速度计X轴、Y轴、Z轴自检,置0则不触发自检。AFS_SEL[1:0]用于选择加速度计的满量程范围,如下表:

 9.png

我们一般设置为0,即满量程为±2g

 10.png

ACCEL_XOUT :由 2部分组成的 16位数值存储最近X 轴加速度计的测量值。ACCEL_YOUT :由 2部分组成的 16位数值存储最近Y 轴加速度计的测量值。ACCEL_ZOUT :由 2部分组成的 16位数值存储最近Z 轴加速度计的测量值。

以ACCEL_XOUT为例,若倍率设定为2g,则意味着ACC_X取最小值-32768时,当前加速度为沿X轴正方向2倍的重力加速度;若设定为4g,取-32768时表示沿X轴正方向4倍的重力加速度,以此类推。显然,倍率越低精度越好,倍率越高表示的范围越大,这要根据具体的应用来设定。以ACC_X为例,若当前设定的加速度倍率为4g,那么将ACC_X读数换算为加速度的公式为:

11.png

g可取当地重力加速度。

12.png

该寄存器存储最近加陀螺仪的测量值,构成与加速度计测量值寄存器相同,不做赘述。

以GYR_X为例,若倍率设定为250度/秒,则意味着GYR取正最大值32768时,当前角速度为顺时针250度/秒;若设定为500度/秒,取32768时表示当前角速度为顺时针500度/秒。显然,倍率越低精度越好,倍率越高表示的范围越大。以GYR_X为例,若当前设定的角速度倍率为1000度/秒,那么将GRY_X读数换算为角速度(顺时针)的公式为:

 13.png

14.png

该寄存器允许用户配置电源模式和时钟源,还提供了复位整个设备和禁用温度传感器的位。当置SLEEP位为1时,MPU-60X0 可以进入低功耗睡眠模式。该寄存器的最低三位用于设置系统的时钟源选择,默认值是0(内部8M RC振荡),不过一般设置为1,即选择x轴陀螺仪PLL作为时钟源,以获得更高精度的时钟。DEVICE_RESET该位置 1,重启内部寄存器到默认值。复位完成后该位自动清0。TEMP_DIS该位置 1,禁用温度传感器。

三、核心代码

main.c:
#include "main.h"
#include "OLED.h"
#include "GY_521.h"
#include "MYI2C.h"
#include "Delay.h"    
typedef struct
{  
    int16_t AX;  
    int16_t AY;  
    int16_t AZ;  
}MPU6050_Adata;  //MPU6050加速度计三轴数据

typedef struct
{  
    int16_t GX;  
    int16_t GY;  
    int16_t GZ;  
}MPU6050_Gdata;  //MPU6050陀螺仪三轴数据

MPU6050_Adata Adata;  //结构体变量
MPU6050_Gdata Gdata;

void GY_521_Init(void)  //GY-521初始化
{  
    GY521_GPIO_Init();  //GPIO初始化  
    //解除睡眠,失能温度传感器,选择X轴的陀螺仪时钟  
    WriteData(GY521_ADDR, MPU6050_PWR_MGMT_1, 0x09);   
    WriteData(GY521_ADDR, MPU6050_CONFIG, 0x06); //低通滤波  
    WriteData(GY521_ADDR, MPU6050_SMPRT_DIV, 0x09); //1KHz十分频为100Hz  
    WriteData(GY521_ADDR, MPU6050_GYRO_CONFIG, 0x18);//陀螺仪最大量程  
    WriteData(GY521_ADDR, MPU6050_ACCEL_CONFIG, 0x18);//加速度计最大量程
}

void MPU6050_GetData()  //获取MPU6050六轴数据
{  
    uint8_t MPU6050_Raw_Data[14]={0};  
    //以MPU6050_ACCEL_XOUT_H为起始地址,连续读取14字节的数据  
    ReadData(GY521_ADDR,MPU6050_ACCEL_XOUT_H,MPU6050_Raw_Data,14);  
    //数据处理      
    Adata.AX=(MPU6050_Raw_Data[0]<<8)|MPU6050_Raw_Data[1];  
    Adata.AY=(MPU6050_Raw_Data[2]<<8)|MPU6050_Raw_Data[3];  
    Adata.AZ=(MPU6050_Raw_Data[4]<<8)|MPU6050_Raw_Data[5];  
    Gdata.GX=(MPU6050_Raw_Data[8]<<8)|MPU6050_Raw_Data[9];  
    Gdata.GY=(MPU6050_Raw_Data[10]<<8)|MPU6050_Raw_Data[11];  
    Gdata.GZ=(MPU6050_Raw_Data[12]<<8)|MPU6050_Raw_Data[13];
}

int main()
{  
    OLED_Init();   //OLED初始化  
    GY_521_Init(); //GY-521初始化  
    OLED_ShowString(1,1,"A:      G:");//提示:左列显示加速度计数据;右列显示陀螺仪数据  
    while(1)  
    {    
        MPU6050_GetData(); //获取六轴数据    
        OLED_ShowSignedNum(2,1,Adata.AX,5);    
        OLED_ShowSignedNum(3,1,Adata.AY,5);    
        OLED_ShowSignedNum(4,1,Adata.AZ,5);     
        
        OLED_ShowSignedNum(2,9,Gdata.GX,5);    
        OLED_ShowSignedNum(3,9,Gdata.GY,5);    
        OLED_ShowSignedNum(4,9,Gdata.GZ,5);    
        Delay_ms(100); //延时刷新  
    }
}

四、效果演示

15.png

平放

 16.png

向下倾斜

 17.png 

左倾斜向

18.png 

直立

读到的原始数据还不能直接使用,要转化成四元数,欧拉角后,获得器件的姿态角才有用,而 MPU6050 自带了数字运动处理器,即 DMP,并且,InvenSense 提供了一个 MPU6050 的嵌入式运动驱动库,结合 MPU6050 的 DMP,可以将我们的原始数据,直接转换成四元数输出,而得到四元数之后,就可以很方便的计算出欧拉角,从而得到yaw、roll和pitch。

来源:CW32生态社区

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 76

摘要: 多旋翼飞行器具有较好的发展前景,也是近年来的热门研究方向。本文讨论的四轴飞行器是一种四旋翼飞行器。首先介绍四轴飞行器的飞行控制原理;其次逐个阐述了基于CC3200单片机和MPU6050加速度计/陀螺仪的迷你四轴飞行器的各个关键模块,从软件和硬件的角度分别描述了各模块的实现和整合;最后,分析了该四轴飞行器的试飞结果以及该飞行器的一些不足。

引言

本文主要介绍了一种迷你四轴飞行器的控制原理,不同于市面上的大多数四轴飞行器,本文所讨论的四轴飞行器以WiFi网络作为控制器与飞行器的通信媒介,这将使四轴飞行器的易用性得到提高。

四轴飞行器原理简介

四轴飞行器,又称四旋翼飞行器、四旋翼直升机,是一种多旋翼飞行器。四轴飞行器的4个螺旋桨都是电机直连的简单机构,十字形的布局允许飞行器通过改变电机转速获得旋转机身的力,从而调整自身姿态。四轴飞行器可以完成垂直运动、俯仰运动、滚转运动、平移运动、偏航运动等动作。

1.1垂直运动

图1 平衡姿态
图1 平衡姿态

四轴飞行器的每个电机驱动一只旋翼,如图1所示,4只电机用圆形表示,机身框架由图中的十字结构表示。图1中,因有两对电机转向相反,可以平衡其对机身的反扭矩,当同时增加4个电机的输出功率,旋翼转速增加使得总的拉力增大,当总拉力足以克服整机的重量时,四轴飞行器便离地垂直上升;反之,同时减小4个电机的输出功率,四轴飞行器则垂直下降,直至平衡落地,实现了沿z轴的垂直运动。当外界扰动量为零时,旋翼产生的升力等于飞行器的自重时,飞行器便保持悬停状态。保证4个旋翼转速同步增加或减小是保持垂直运动的关键。

1.2俯仰运动、滚转运动

图2 倾斜姿态
图2 倾斜姿态

倾斜姿态如图2所示,电机1、电机2的转速上升,电机3、电机4的转速下降。为了不因为旋翼转速的改变引起四轴飞行器整体扭矩及总拉力改变,旋翼1与旋翼3转速改变量的大小应相等,旋翼2与旋翼4转速改变量的大小应相等。由于旋翼1、旋翼2的升力上升,旋翼3、旋翼4的升力下降,产生的不平衡力矩使机身绕y轴旋转,发生俯仰运动。同理,当电机1、电机4的转速下降,电机2、电机3的转速上升时,机身便绕x轴向旋转,实现飞行器的滚转运动。

1.3平移运动

四轴飞行器在作出俯仰、滚转运动时,由于机体倾斜,旋翼提供的升力将产生水平分量,使得机体可以作出前、后、左、右平移运动。

1.4偏航运动

偏航运动如图3所示。四轴飞行器偏航运动可以借助旋翼产生的反扭矩来实现。旋翼转动过程中由于空气阻力作用会形成与转动方向相反的反扭矩,为了克服反扭矩影响,可使4个旋翼中的2个正转、2个反转,且对角线上的各个旋翼转动方向相同。

图3 偏航运动
图3 偏航运动

反扭矩的大小与旋翼转速有关,当4个电机转速相同时,4个旋翼产生的反扭矩则相互平衡,则四轴飞行器不发生转动;当4个电机转速不完全相同时,不平衡的反扭矩会引起四轴飞行器转动。在图3中,当电机1和电机3的转速上升、电机2和电机4的转速下降时,旋翼1和旋翼3对机身的反扭矩大于旋翼2和旋翼4对机身的反扭矩,机身便在富余反扭矩的作用下绕z轴转动,实现飞行器的偏航运动,转向与电机1、电机3的转向相反。因为电机的总升力不变,飞机不会发生垂直运动。

能够作出以上几种动作,使得四轴飞行器具备了较高的灵活性和较好的操控性。

四轴飞行器硬件设计与实现

本文所讨论的迷你四轴飞行器以自身的PCB板为机架,由CC3200无线微控制器负责飞控算法、电机控制和无线通信,由MPU6050加速度计/陀螺仪负责获取姿态数据,由4只720空心杯电机和螺旋桨提供升力,由MOS管驱动电机,由锂电池和LDO稳压器提供电源。

2.1迷你四轴飞行器总体设计

图4 迷你四轴飞行器外观
图4 迷你四轴飞行器外观

该飞行器PCB尺寸为10 cm×10 cm,层数为两层。整体外观如图4所示。

为降低硬件开发复杂度,CC3200和MPU6050均使用成品模块。为节约空间、降低负重,PCB上的阻容器件均采用0603封装,其他器件采用小型贴片封装。

2.2CC3200模块

CC3200是TI公司推出的一款单芯片无线微控制器,为SimpleLink、WiFi和物联网提供解决方案。CC3200由应用微控制器、WiFi网络处理器和电源管理子系统组成。

应用微控制器采用ARM CortexM4内核,运行频率为80 MHz,具有256 KB RAM,浮点运算能力较强,满足飞控算法性能要求;有2个UART接口、1个I2C接口、4个通用定时器,通道支持16位脉宽调制 (PWM) 模式,4通道12位模/数转换器 (ADC),多达27个独立可编程、复用通用输入/输出(GPIO)引脚,硬件接口完全满足四轴飞行器的功能需求。

WiFi网络处理器子系统特有WiFi InternetOnaChip专用ARM MCU,完全解除应用微控制器的WiFi和互联网协议处理负担。ROM中固化有WiFi以及互联网协议、802.11 b/g/n射频、基带、媒介访问控制(MAC)、WiFi驱动器和请求方TCP/IP堆栈。

电源管理子系统集成DCDC转换器,支持2.1~3.6V宽范围的电源电压,并具备高级低功耗模式。

本文所使用的CC3200模块已集成必要的外围电路和时钟,扩展出GPIO和外设接口,仅需提供电源即可运行。PCB中引出CC3200模块的2路UART和1路JTAG进行调试,1路I2C总线与MPU6050传感器通信,4路PWM用于控制电机,2路GPIO控制指示灯。

2.3MPU6050模块

MPU6050为整合性6轴运动处理组件,相较于多组件方案,避免了组合陀螺仪与加速器时之轴间差的问题,减少了大量的封装空间。MPU6050的角速度全格感测范围为±250°/sec、±500°/sec、±1 000°/sec与±2000°/sec (dps),可准确追踪快速与慢速动作,并且,用户可程式控制的加速器全格感测范围为±2g、±4g、±8g与±16g,产品传输可通过最高至400 kHz的I2C总线接口实现。MPU6050可在不同电压下工作,VDD供电电压为2.5 V±5%、3.0 V±5%或3.3V±5%。MPU6050的封装尺寸为4×4×0.9 mm3(QFN)。MPU6050还包含内建的温度感测器、在运作环境中仅有±1%变动的振荡器。

MPU6050模块已集成必要的外围电路,扩展出I2C接口,仅需提供电源并进行配置即可使用。

2.4电机及其驱动电路

四轴飞行器采用转速高达45 000 r/min的720空心杯电机提供动力。电机由SI2302场效应管驱动,场效应管由CC3200 PWM控制。

2.5电源设计

四轴飞行器的电源由锂电池提供。锂电池容量为500 mAh、放电系数为20C,最大放电电流为10 A,可支持飞行器飞行5 min。电池输出分两路,一路直接通过MOS管加在电机上为电机供电,另一路通过XC6206 LDO稳压到3.3 V,为CC3200和MPU6050供电。

2.6遥控器设计

四轴飞行器使用Android手机通过WiFi与CC3200建立连接并通信。手机端遥控APP将在3.2节介绍。

四轴飞行器软件设计与实现

3.1四轴飞行器端固件

四轴飞行器端固件主要实现如下功能:

① 初始化CC3200应用控制器。
② 初始化并配置MPU6050传感器。
③ 初始化网络处理器并建立WLAN AP和TCP Server Socket,等待遥控连接。
④ 进入主循环,处理传感器数据,生成姿态数据并根据姿态和遥控指令计算出每个电机的PWM输出值。

main()函数框架如下(略去部分代码):

void main(){
BoardInit();//初始化CC3200
PinMuxConfig();//配置引脚
InitPWMModules();//初始化PWM
I2C_IF_Open(I2C_MASTER_MODE_FST);//初始化I2C
mpu_setup();//初始化和配置MPU6050
……
//初始化网络子系统,建立WLAN AP和TCP Server Socket
osi_TaskCreate( WlanAPMode, \\
(const signed char*)"wireless LAN in AP mode", \\
OSI_STACK_SIZE, NULL, 1, NULL );
//主循环,处理传感器数据,生成姿态数据并实现飞控算法
osi_TaskCreate( GestureCtrl, \\
(const signed char*)"gesture ctrl", \\
OSI_STACK_SIZE, NULL, 1, NULL );
……
}

主要飞控算法函数Gesture_ctrl()框架如下(略去部分代码):

void Gesture_ctrl(int accelerato, float offsetX, float offsetY){
MakeOut_xyz();//根据传感器返回的数据计算x、y、z三个轴向的倾角
UpdatePID(offsetX, offsetY);//计算调节量
//把几个轴向的调节量加在相应的电机上
moto1 = accelerato + pid_rol.out - pid_pit.out - pid_yaw.out;
moto2 = accelerato - pid_rol.out - pid_pit.out + pid_yaw.out;
moto3 = accelerato - pid_rol.out + pid_pit.out - pid_yaw.out;
moto4 = accelerato + pid_rol.out + pid_pit.out + pid_yaw.out;
//将运算结果输出给PWM控制器
UpdateDutyCycleMoto1(moto1);
UpdateDutyCycleMoto2(moto2);
UpdateDutyCycleMoto3(moto3);
UpdateDutyCycleMoto4(moto4);
}

其中,UpdatePID(offsetX, offsetY)根据倾角、遥控指令(offsetX, offsetY)和PID算法,求出x、y、z三个轴向上的调节量pid_rol.out、pid_pit.out和pid_yaw.out。offsetX、offsetY 为遥控器命令指定的目标姿态,PID算法将改变电机输出,使机体姿态调整到目标姿态。PID算法公式为:uk=Kp×ek+Ki∑kj=0ej+Kd(ek-ek-1)

其中,u为调节量;e为当前姿态的姿态角较目标姿态的偏差,即offsetX + x或offsetY + y(x、y为当前姿态倾角);Kp为比例相系数;Ki为积分项系数,积分项为e的累加和;Kd为微分项系数,角度的微分即角速度,所以微分项可由MPU6050的陀螺仪输出直接得到。

网络通信的简要代码如下(略去部分代码):

int BsdTcpServer(unsigned shortusPort){
……
//填充TCP Server Socket地址
sLocalAddr.sin_family = SL_AF_INET;
sLocalAddr.sin_port = sl_Htons((unsigned short)usPort);
sLocalAddr.sin_addr.s_addr = 0;
//创建TCP Server Socket
iSockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
//绑定TCP socket
sl_Bind(iSockID, (SlSockAddr_t *)&sLocalAddr, iAddrSize);
//监听TCP连接
sl_Listen(iSockID, 0);
//设置Socket操作为非阻塞模式
sl_SetSockOpt(iSockID, SL_SOL_SOCKET, SL_SO_NONBLOCKING,&lNonBlocking, sizeof(lNonBlocking));
iNewSockID = SL_EAGAIN;
while( iNewSockID < 0){
//接受TCP连接请求
iNewSockID = sl_Accept(iSockID, ( struct SlSockAddr_t *)&sAddr,(SlSocklen_t*)&iAddrSize);
}
return iNewSockID;
}
void TcpLoopRecive(void *pvParameters){
……
while(1){
//接收TCP包
sl_Recv(iNewSockID, g_cBsdBuf, 16, 0);
//解析遥控指令
if(g_cBsdBuf[0] == 0xAA){
accelerato = g_cBsdBuf[1] + ((int)g_cBsdBuf[2] << 8);
memcpy(&offsetX, g_cBsdBuf + 3, 4);
memcpy(&offsetY, g_cBsdBuf + 7, 4);
}
}
}

3.2遥控器端APP设计

遥控器APP运行在Android手机系统中,主要功能是建立与CC3200的TCP连接,为用户提供操作界面,获取用户输入,并通过TCP Seruer Socket将输入传给CC3200。用户界面如图5所示,该界面能够获取用户的“方向”和“油门”输入。

图5 遥控APP界面
图5 遥控APP界面

结语

按照本文的方案设计出的四轴飞行器,在试飞中可以根据遥控器指令,作出悬停、垂直运动、水平运动等动作,验证了本方案的可行性。同时,四轴飞行器方案在飞行稳定性、遥控距离、电源稳定性方面,还有很大的提升空间。

文章来源:单片机与嵌入式系统应用

围观 621
订阅 RSS - MPU6050