MPU6050的原始数据分析
个人经验来讲,如果对IIC总线协议很熟悉的情况下,获取6050的原始数据就不是什么太大的难题,毕竟再怎么复杂也只是一个传感器而已,就像你打电话给传感器,要它的数据,然后它返回给你,仅此而已。
首先,要了解6050是干什么的:
MPU-6000(6050)为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时间轴之差的问题,减少了大量的封装空间。(来自百度百科)
简单说,就是该传感器能获取XYZ三个轴方向的角速度和加速度,包含6个16位的ADC来表示这些值,关于传感器的测量原理,可以简单想象类似下图的模式,是不很直观。
当然,用过AD转换的童鞋都知道,这个是会有精度问题的,6050也一样,而且受到的噪声影响更大,但本次不讨论这个问题,仅讨论怎么获取原始数据
话不多说,上代码
初始化代码实现
/*--------MPU6050地址宏定义---------*/
#define MPU6050_SLAVEAddr 0xd0 //IIC写6050地址
#define MPU6050_ACCAddr 0x3B //MPU加速度读值地址
#define MPU6050_GYROAddr 0x43 //陀螺仪读值地址
#define MPU_Remove_Sleep 0x6B //解除休眠地址
#define MPU_GYRO_Smple_DIV 0x19 //陀螺仪采样率寄存器1Khz
#define MPU_LOW_Pass 0x1a //低通滤波器 带宽5K
#define MPU_ACC_Config 0x1c //加速度传感器工作在2g模式
#define MPU_GYRO_Config 0x1b //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define MPU_ACC_OUT_Addr 0x3b //读取加速度寄存器
#define MPU_GYRO_OUT_Addr 0x43 //读取陀螺仪寄存器
//MPU6050初始化
void mpu6050_Init(void)
{
//进行IIC初始化
IIC_Init();
//进行一小段的延时 防止断电再上电的时候数据出错
MPU_Dealy(1000);
//解除休眠状态
IIC_WriteData(MPU6050_SLAVEAddr,MPU_Remove_Sleep, 0x00);
//陀螺仪采样率
IIC_WriteData(MPU6050_SLAVEAddr,MPU_GYRO_Smple_DIV,0x07);
//低通滤波器设置
IIC_WriteData(MPU6050_SLAVEAddr,MPU_LOW_Pass,0x06);
//配置加速度传感器工作在2g模式下
IIC_WriteData(MPU6050_SLAVEAddr,MPU_ACC_Config,0x00);
//配置陀螺仪量程和自检范围
IIC_WriteData(MPU6050_SLAVEAddr,MPU_GYRO_Config, 0x18);
}
关于寄存器的配置其实没什么好说的,看数据手册一点点进行即可,值得注意的是2g模式,这个是指6050的量程容易查到的是,这样的加速度输出量程在-16384——>+16384之间,所以计算出的加速度为(读取值)/16384(g)自然的,加速度也一样,不过,这不属于当前讨论的范围。
读取加速度和角速度的代码如下,其实6050还可以获取很多参数,这里不予赘述,查询手册即可。
void mpu6050Read_Acc(short *accData) //MPU6050读加速度
{
u8 buf[6];
//因为我们一次读取一个字节,而6050的ADC是16位的,所以先读取,后取或运算,顺序依次是XYZ轴
IIC_ReadData(MPU6050_SLAVEAddr,MPU_ACC_OUT_Addr,buf,6);
accData[0] = (buf[0] << 8) | buf[1];
accData[1] = (buf[2] << 8) | buf[3];
accData[2] = (buf[4] << 8) | buf[5];
}
void mpu6050Read_Gyro(short *gyroData) //MPU6050读陀螺仪
{
u8 buf[6];
IIC_ReadData(MPU6050_SLAVEAddr,MPU_GYRO_OUT_Addr,buf,6);
gyroData[0] = (buf[0] << 8) | buf[1];
gyroData[1] = (buf[2] << 8) | buf[3];
gyroData[2] = (buf[4] << 8) | buf[5];
}
//注意,因为6050有噪声信号存在,所以当6050平放时 读取到的加速度值约为16384即可视为程序正确
int main()
{
short Accel[3];
short Gyro[3];
all_Init();
while(1)
{
mpu6050Read_Acc(Accel);
printf("\r\n加速度:%8d%8d%8d\t",Accel[0],Accel[1],Accel[2]);
mpu6050Read_Gyro(Gyro);
printf("陀螺仪:%8d%8d%8d",Gyro[0],Gyro[1],Gyro[2]);
delay_ms(1000);
}
}
(解决几个问题 以下属于转载内容,侵权请提示删除)
1.MPU6050是什么?
MPU6050是一个6轴运动处理组件,包含了3轴加速度 和3轴陀螺仪。
MPU-6000为全球首例整合性6轴运动处理组件,相较于多组件方案,免除了组合陀螺仪与加速器时之轴间差的问题,减少了大量的包装空间。MPU-6000整合了3轴陀螺仪、3轴加速器,并含可藉由第二个I2C端口连接其他厂牌之加速器、磁力传感器、或其他传感器的数位运动处理(DMP: Digital Motion Processor)硬件加速引擎,由主要I2C端口以单一数据流的形式,向应用端输出完整的9轴融合演算技术
InvenSense的运动处理资料库,可处理运动感测的复杂数据,降低了运动处理运算对操作系统的负荷,并为应用开发提供架构化的API。
MPU-6000的角速度全格感测范围为±250、±500、±1000与±2000°/sec (dps),可准确追緃快速与慢速动作,并且,用户可程式控制的加速器全格感测范围为±2g、±4g±8g与±16g。产品传输可透过最高至400kHz的I2C或最高达20MHz的SPI。
MPU-6000可在不同电压下工作,VDD供电电压介为2.5V±5%、3.0V±5%或3.3V±5%,逻辑接口VVDIO供电为1.8V± 5%。MPU-6000的包装尺寸4x4x0.9mm(QFN),在业界是革命性的尺寸。其他的特征包含内建的温度感测器、包含在运作环境中仅有±1%变动的振荡器。
2.加速度传感器是干嘛用的?
总而言这,加速度传感器,其实是力传感器。用来检查上下左右前后哪几个面都受了多少力(包括重力),然后计算角度。
3.陀螺仪是干嘛用的?
简而言之,陀螺仪就是角速度检测仪。比如,一块板,以X轴为轴心,在一秒钟的时间转到了90度,那么它在X轴上的角速度就是 90度/秒 (DPS, 角速度单位,Degree Per Second的缩写°/S ,体现了转动的快慢)
4.MPU6050分辨率是多少?
3轴加速度 和3轴陀螺仪分别用了3个16位的ADC, 也就是说,加速度有3个16位ADC,其中每个轴使用了一个。也是说,每个轴输出的数据,是2^16 也就是 -32768 —- +32768。陀螺仪也是一样。
- 单位换算
上面说的-32768 — +32768 ,那么这个数字到底代表了什么呢?比如陀螺仪 32768 到底是指角速度达到多少度/秒 ?
这个其实是根据MPU6050设置的量程来决定的,量程不一样,32768代表的值就不一样。
MPU6050的量程设置,在 MPU6050::initialize() (MPU6050.cpp库)初始化函数中进行了设置:
setFullScaleGyroRange(MPU6050_GYRO_FS_250);
setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
分别设置为,250度/秒 , 2g
按陀螺仪来说,MPU6050 有四个量程可选:
±250,±500,±1000,±2000 度/s
比方说,设置了是 ±250 , 那么-32768 —- +32768 就代表了 -250 —- +250 。此时它的LSB(拉傻B,最低有效位) 是 131 LSB/(度/s)
关于数据融合,最后得到欧拉角,是接下来的内容
简单说就是要,对原始数据先进行解算,滤波,基本就是这个过程。源码已经上传至CSDN资源(基于STM32的串口显示MPU6050原始数据)