Arduino下基于MPU6050的姿态数据读…

    xiaoxiao2021-03-25  212

    这一模块实际上就是一个集成了加速度+重力+温度传感器,并且提供一系列寄存器来供给用户读取,使用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

    最新回复(0)