目的:
通过调用树莓派的IIC接口,编写常用元器件陀螺仪的数据采集
目录
1、基础知识
1.1、陀螺仪传感器介绍
陀螺仪传感器是一个简单易用的基于自由空间移动和手势的定位和控制系统。在假想的平面上挥动鼠标,屏幕上的光标就会跟着移动,并可以绕着链接画圈和点击按键。当你正在演讲或离开桌子时,这些操作都能够很方便地实现。 陀螺仪传感器原本是运用到直升机模型上的,已经被广泛运用于手机这类移动便携设备上。
运动感测人机界面(MotionInterfac)正在成为智能手机和平板电脑制造商采用的“必备”功能,由于它增加了最终用户体验的巨大价值。 在智能手机中,它发现应用程序和电话控制等手势命令,增强游戏,增强现实,全景照片捕获和观看以及行人和车辆导航等应用程序中使用。凭借其精确准确地跟踪用户动作的能力,MotionTrack技术可以将手机和平板电脑转换为强大的3D智能设备,这些设备可用于从健康和健身监测到基于位置的服务的应用。运动感测人机界面支持的设备的关键要求是小型封装尺寸,低功耗,高精度和可重复性,高抗冲视和应用特定性能可编程性,所有这些都处于低消费者的价格点。
MPU-60X0是世界上第一款集成的6轴MoteletTracking装置,将3轴陀螺仪,3轴加速度计和数字运动处理器™(DMP)组合在一个小型4x4x0.9mm封装中。 利用其专用I2C传感器总线,它直接接受外部3轴罗盘的输入,以提供完整的9轴MotionFusion™输出。 MPU-60X0 MotionTracking设备,其6轴集成,车载MotionFusion™和运行时校准固件,使制造商能够消除离散设备的昂贵和复杂的选择,验证和系统级集成,保证最佳运动 消费者的表现。 MPU-60X0还设计用于在其辅助I 2C端口上与多个非惯性数字传感器(例如压力传感器)接口。 MPU-60X0是与MPU-30x0系列兼容的占用空间。
MPU-60X0具有三个16位模数转换器(ADC),用于数字化陀螺仪输出和三个16位ADC,用于数字化加速度计输出。 为了精确跟踪快速和慢速运动,该部件具有±250,±500,±1000和±2000°/ sec(DPS)的用户可编程陀螺全尺寸范围,以及用户可编程加速度计的用户可编程加速度计 ±2g,±4g,±8g和±16g的范围。
片上1024字节FIFO缓冲器通过允许系统处理器在突发中读取传感器数据然后输入低功率模式,有助于降低系统功耗,然后当MPU收集更多数据时,输入低功率模式。 通过所有必要的片上处理和传感器组件,需要支持许多基于运动的用例,MPU-60X0唯一可以在便携式应用中实现低功耗MotionInterface应用,并降低系统处理器的处理要求。 通过提供集成的MotionFuction输出,MPU-60X0中的DMP从系统处理器卸下强化MotionProcessing计算要求,最大限度地减少了对运动传感器输出的频繁轮询的需求。
图1-1-1 MPU-6050框架图
本次案例采用IIC接口,通过查看数据手册,知道MPU6050的地址是0x68。
2、功能实现
2.1、原理图
图2-1-1 MPU6050
通过线接在树莓派的IIC0引脚上,编写代码实现数据的读取。
2.2、打开树莓派的IIC0功能
如果没有开启树莓派I2C-0总线,需要按照如下步骤开启:
- a、树莓派连接互联网;
- b、打开一个终端,输入命令【sudo apt update & sudo apt install vim】,安装命令行下的文本文件编辑器;
- c、输入命令【sudo vim /boot/config.txt】,打开配置文件,输入【/i2c】回车,查找关键词i2c并定位到如下行:
图2-2-1 打开配置文件
- d、按下【a】进入插入编辑模式,方向键将光标移动到该行末尾,按下回车添加新的一行,输入【dtparam=i2c_vc=on】,如图所示:
图2-2-2 打开IIC-0
- e、确认内容和上图一样后,按下键盘【ESC】键退出编辑模式,然后输入【:wq】回车,保存退出。
- f、如果要使用i2c0,需要在设置中把camera功能关闭,即disable。方法是输入【sudo raspi-config】,把树莓派配置界面的interface页面找到canmera接口,选择disable关闭,这里不再赘述过程。
- g、最后,输入【sudo reboot】回车,等待树莓派重启完成后,重新连接到终端。
2.3、查看I2C-0上的设备
VSCode新建一个树莓派终端,输入命令【i2cdetect -y 0】并回车确定,检测挂载在i2c总线上的所有设备,如图所示。
图2-3-1 树莓派i2c-0检测设备
其中,此处的0x68为MPU6050传感器的设备地址,后续将会通过这个地址进行通信。
2.4、代码实现
2.4.1、头文件
#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <wiringPiI2C.h>
2.4.2、宏定义
//****************************************
// 定义MPU6050内部地址
//****************************************
#define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz)
#define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz)
#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)
#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)
#define ACCEL_XOUT_H 0x3B
#define ACCEL_XOUT_L 0x3C
#define ACCEL_YOUT_H 0x3D
#define ACCEL_YOUT_L 0x3E
#define ACCEL_ZOUT_H 0x3F
#define ACCEL_ZOUT_L 0x40
#define TEMP_OUT_H 0x41
#define TEMP_OUT_L 0x42
#define GYRO_XOUT_H 0x43
#define GYRO_XOUT_L 0x44
#define GYRO_YOUT_H 0x45
#define GYRO_YOUT_L 0x46
#define GYRO_ZOUT_H 0x47
#define GYRO_ZOUT_L 0x48
#define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)
#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读)
#define SlaveAddress 0x68 //MPU6050器件地址
2.4.3、MPU6050初始化
// 初始化 mpu6050
void initMPU6050()
{
wiringPiSetup () ;
fd = wiringPiI2CSetupInterface ("/dev/i2c-0",SlaveAddress);
if (fd >= 0) { // fd 为负数,说明IIC连接失败
printf("fd = %d\n",fd);
wiringPiI2CWriteReg8(fd,PWR_MGMT_1,0x00); // 开启温度检测 关闭休眠
wiringPiI2CWriteReg8(fd,SMPLRT_DIV, 0x07);
wiringPiI2CWriteReg8(fd,CONFIG, 0x06);
wiringPiI2CWriteReg8(fd,GYRO_CONFIG, 0x18);
wiringPiI2CWriteReg8(fd,ACCEL_CONFIG, 0x01);
}
else {
printf("IIC初始化失败");
}
}
2.4.4、读取指定寄存器的数据的函数接口
// 读取指定寄存器中的数据
int getData(int reg_address)
{
int value = 0;
value = wiringPiI2CReadReg16(fd,reg_address);
if(value > 32768)
value = value - 65536;
return value;
}
2.4.5、主函数
int main (void)
{
int acc_x,acc_y,acc_z,gyro_x,gyro_y,gyro_z;
float Ax,Ay,Az,Gx,Gy,Gz;
initMPU6050();
for(;;)
{
printf("WHO_AM_I = %x\n",wiringPiI2CReadReg8(fd,WHO_AM_I));
//#Read Accelerometer raw value
acc_x = getData(ACCEL_XOUT_H);
acc_y = getData(ACCEL_YOUT_H);
acc_z = getData(ACCEL_ZOUT_H);
//#Read Gyroscope raw value
gyro_x = getData(GYRO_XOUT_H);
gyro_y = getData(GYRO_YOUT_H);
gyro_z = getData(GYRO_ZOUT_H);
//#Full scale range +/- 250 degree/C as per sensitivity scale factor
Ax = acc_x/16384.0;
Ay = acc_y/16384.0;
Az = acc_z/16384.0;
Gx = gyro_x/131.0;
Gy = gyro_y/131.0;
Gz = gyro_z/131.0;
printf("Ax: %.2f, Gx: %.2f\n",Ax,Gx);
printf("Ay: %.2f, Gy: %.2f\n",Ay,Gy);
printf("Az: %.2f, Gz: %.2f\n",Az,Gz);
delay(5000); // 间隔5秒 打印一次数据
}
return 0 ;
}
2.5、生成执行程序
编译的时候需要添加wiringPi库,编译步骤如下所示:
gcc -Wall -o mp6050 mp6050.c -lwiringPi
图2-5-1 编译过程
2.6、现象
运行执行程序,终端上打印出陀螺仪的数据。
./mp6050
图2-6-1 陀螺仪数据