这一模块实际上就是一个集成了加速度+重力+温度传感器,并且提供一系列寄存器来供给用户读取,使用I2c最大可以获得400khz的传输速率,这里使用arduino来作为开发环境。
线路连接:在这里板载的A4为328P的I2C的SDA 数据接口,接6050上面的SDA,SCL为A5
(部分案例中要连接INT端到digitalPin上面,待研究)
基本测试步骤为以下:
1.在文件头包括ArduinoIDE自带的Wire.h头文件来提供底层透明化的操作
2.在程序中初始化6050,提供6050的地址,并通过写寄存器将其从睡眠中唤醒
3.结束传输初始化的数据后,后面可以直接循环读取数据并转化为整数型
4.数据读取:先选择寄存器地址,然后按位读取并存储,并最终转化为十进制整数
实现例1:
读取MPU6050自带的温度传感器数据
#include
void MPU6050_Init()
{
Wire.beginTransmission(0x68);//6050的地址
Wire.write(0x6B);//设置休眠寄存器
Wire.write(0);//设置为0,不休眠
Wire.endTransmission(true);//结束向6050通讯
}
void MPU6050_ReadData()
{
Wire.beginTransmission(0x68);//开启传输
Wire.write(0x41);//指定X轴的数据寄存器
Wire.requestFrom(0x68,2,true);//从0x68设备输出数据2个字节也就是十六位
Wire.endTransmission(true);//关闭本次传输
int val = Wire.read()<<8 | Wire.read();//设置val为数据的存储变量
Serial.print("Temp:");
double temp =(double) val /340 +34.53;//官方文档提供的转化为摄氏温度的公式
Serial.println(temp);
}
void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(9600);
MPU6050_Init();
}
void loop() {
// put your main code here, to run repeatedly:
MPU6050_ReadData();
delay(500);
}
//--------------这里的温度实际上并不准确,在运行时间持续一段后,受到芯片发热的影响产生偏差
//PS:在一定时间内会比ds18B20误差更小
========
========
========
========
========
========
========
========
========
========
========
===========
第二部分:对加速度的读取
加速度数值保存在0x3B到0x40这一段寄存器中,我们通过选择寄存器与请求传输数据,保存数据并处理的方式来输出6050所感测到的三轴原始数据
void MPU6050_ReadAccelData()
{
int Accel[3];
Wire.beginTransmission(0x68);//开启传输
Wire.write(0x3B);
Wire.requestFrom(0x68,3 * 2,true);//从0x68设备输出3个轴数据每个2个字节
Wire.endTransmission(true);//关闭本次传输
for (long i = 0; i < 3; i++) {
Accel[i]= Wire.read()<<8 | Wire.read();//将数据存入数组,分别为XYZ轴的数据
}
Serial.print("X:");
Serial.print(Accel[0]);
Serial.print("
Y:");
Serial.print(Accel[1]);
Serial.print("
Z:");
Serial.println(Accel[2]);
}
===================================================================================================
第三部分:同时读取与输出,基本归零处理
即使我们不做任何动作,也会有远远大于或者小于0的数据输出,影响我们的观察,这个就是自带的误差
校准这一问题:
我们可以在初始化后记录一部分数值,作为误差参考,对这些误差进行平均,得出误差偏移值后使得后面读取的数据误差得到减少
#include
long Xac = 0,Yac = 0,Zac = 0;//初始化误差偏移值
void MPU6050_Init()
{
Wire.beginTransmission(0x68);//6050的地址
Wire.write(0x6B);//设置休眠寄存器
Wire.write(0);//设置为0,不休眠
Wire.endTransmission(true);//结束向6050通讯
}
void MPU6050_ReadData()
{
Wire.beginTransmission(0x68);//开启传输
Wire.write(0x41);//指定X轴的数据寄存器
Wire.requestFrom(0x68,2,true);//从0x68设备输出数据2个字节也就是十六位
Wire.endTransmission(true);//关闭本次传输
int val = Wire.read()<<8 | Wire.read();//设置val为数据的存储变量
Serial.print("Temp:");
double temp =(double) val /340 +34.53;
Serial.println(temp);
}
void MPU6050_ReadAccelData()
{
int Accel[3];
long Xa = 0,Ya = 0,Za = 0;
Wire.beginTransmission(0x68);//开启传输
Wire.write(0x3B);
Wire.requestFrom(0x68,3 * 2,true);//从0x68设备输出3个轴数据每个2个字节
Wire.endTransmission(true);//关闭本次传输
for (long i = 0; i < 3; i++) {
Accel[i]= Wire.read()<<8 | Wire.read();//将数据存入数组,分别为XYZ轴的数据
}
Xa = Accel[0] - Xac;//误差值的校准
Ya = Accel[1] - Yac;
Za = Accel[2] - Zac;
Serial.print("X:");
Serial.print(Xa);
Serial.print("
Y:");
Serial.print(Ya);
Serial.print("
Z:");
Serial.println(Za);
}
void MPU6050_AccelDataCalibration(int t)
{
//t参数为采集多少个数据后进行平均
int Accel[3];
for(int i=0;i < t;i++)//循环方式存储读取的数据
{
Wire.beginTransmission(0x68);//开启传输
Wire.write(0x3B);
Wire.requestFrom(0x68,3 * 2,true);//从0x68设备输出3个轴数据每个2个字节
Wire.endTransmission(true);//关闭本次传输
//将数据在这一循环中相加
Xac += Wire.read()<<8 | Wire.read();
Yac += Wire.read()<<8 | Wire.read();
Zac += Wire.read()<<8 | Wire.read();
delay(10);
}
平均后得到偏移值
Xac = Xac /t;
Yac = Yac /t;
Zac = Zac /t;
Serial.print("X:");
Serial.print(Xac);
Serial.print("
Y:");
Serial.print(Yac);
Serial.print("
Z:");
Serial.println(Zac);
}
void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(9600);
MPU6050_Init();
delay(100);
MPU6050_AccelDataCalibration(200);//平均二百次
}
void loop() {
MPU6050_ReadAccelData();
}
试验中发现MPU6050这个模块的误差非常大,静态中都有很大的误差,原因可能还是来自芯片质量问题。
测量加速,加速方向等可以通过该模块实现并能进行一些初步判断,但是无法利用这些数据进行更准确的PID处理,建议使用更高价格的芯片,以保证数据质量。
转载请注明原文地址: https://ju.6miu.com/read-703.html