OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 14518|回复: 23

MPU6050实验中 u8 mpu_dmp_get_data(float *pitch,float *roll,float *yaw)函数的一些问题

[复制链接]

12

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
123
金钱
123
注册时间
2014-9-25
在线时间
3 小时
发表于 2015-4-8 17:49:47 | 显示全部楼层 |阅读模式
5金钱
mpu_dmp_get_data的返回值一直是1,为什么主函数中还是能进入if语句。
造成返回值是1的原因我用J-Link调试的结果是下面这种情况。。请看代码中的红色部分
好像代码中加不了红色。。大家就看<span style="color:#E53333;">后面的话吧。
[mw_shl_code=c,true] if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)//返回值是1,但if语句还是能进去。这是问题一? { temp=MPU_Get_Temperature(); //得到温度值 MPU_Get_Accelerometer(&aacx,&aacy,&aacz); //得到加速度传感器数据 MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz); //得到陀螺仪数据 if(report)mpu6050_send_data(aacx,aacy,aacz,gyrox,gyroy,gyroz);//用自定义帧发送加速度和陀螺仪原始数据 if(report)usart1_report_imu(aacx,aacy,aacz,gyrox,gyroy,gyroz,(int)(roll*100),(int)(pitch*100),(int)(yaw*10)); if((t%10)==0) { if(temp<0) { LCD_ShowChar(30+48,200,'-',16,0); //显示负号 temp=-temp; //转为正数 }else LCD_ShowChar(30+48,200,' ',16,0); //去掉负号 LCD_ShowNum(30+48+8,200,temp/100,3,16,0); //显示整数部分 LCD_ShowNum(30+48+40,200,temp%10,1,16,0); //显示小数部分 [/mw_shl_code] [mw_shl_code=c,true][/mw_shl_code]
[mw_shl_code=c,true][/mw_shl_code] [mw_shl_code=c,true]u8 mpu_dmp_get_data(float *pitch,float *roll,float *yaw) { float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f; unsigned long sensor_timestamp; short gyro[3], accel[3], sensors; unsigned char more; long quat[4]; if(dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more))return 1;         //dmp_read_fifo的返回值为-1使得mpu_dmp_get_data的返回值为1。也就是说下面的计算根本就没执行。[/mw_shl_code] [mw_shl_code=c,true]        但在液晶屏上显示的结果像是对的。这是问题二? if(sensors&INV_WXYZ_QUAT) { q0 = quat[0] / q30; //q30格式转换为浮点数 q1 = quat[1] / q30; q2 = quat[2] / q30; q3 = quat[3] / q30; //计算得到俯仰角/横滚角/航向角 *pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch *roll = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll *yaw = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //yaw }else return 2; return 0; }[/mw_shl_code]

[mw_shl_code=c,true]int dmp_read_fifo(short *gyro, short *accel, long *quat, unsigned long *timestamp, short *sensors, unsigned char *more) { unsigned char fifo_data[MAX_PACKET_LENGTH]; unsigned char ii = 0; /* TODO: sensors[0] only changes when dmp_enable_feature is called. We can * cache this value and save some cycles. */ sensors[0] = 0; /* Get a packet. */ if (mpu_read_fifo_stream(dmp.packet_length, fifo_data, more)) return -1;    //程序执行到这退出,返回了-1。mpu_read_fifo_stream的返回值为-2。下面的语句也是没有执行的。 /* Parse DMP packet. */ if (dmp.feature_mask & (DMP_FEATURE_LP_QUAT | DMP_FEATURE_6X_LP_QUAT)) { #ifdef FIFO_CORRUPTION_CHECK long quat_q14[4], quat_mag_sq; #endif quat[0] = ((long)fifo_data[0] << 24) | ((long)fifo_data[1] << 16) | ((long)fifo_data[2] << 8) | fifo_data[3]; quat[1] = ((long)fifo_data[4] << 24) | ((long)fifo_data[5] << 16) | ((long)fifo_data[6] << 8) | fifo_data[7]; quat[2] = ((long)fifo_data[8] << 24) | ((long)fifo_data[9] << 16) | ((long)fifo_data[10] << 8) | fifo_data[11]; quat[3] = ((long)fifo_data[12] << 24) | ((long)fifo_data[13] << 16) | ((long)fifo_data[14] << 8) | fifo_data[15]; ii += 16;[/mw_shl_code]



[mw_shl_code=c,true]int mpu_read_fifo_stream(unsigned short length, unsigned char *data, unsigned char *more) { unsigned char tmp[2]; unsigned short fifo_count; if (!st.chip_cfg.dmp_on) return -1; if (!st.chip_cfg.sensors) return -1; if (i2c_read(st.hw->addr, st.reg->fifo_count_h, 2, tmp)) return -1; fifo_count = (tmp[0] << 8) | tmp[1]; if (fifo_count < length) { more[0] = 0; return -1; } if (fifo_count > (st.hw->max_fifo >> 1)) {//为什么要进行这一句的比较? /* FIFO is 50% full, better check overflow bit. */ if (i2c_read(st.hw->addr, st.reg->int_status, 1, tmp)) return -1; if (tmp[0] & BIT_FIFO_OVERFLOW) { mpu_reset_fifo(); return -2;    调试的结果是程序在这退出,返回了-2 。正确的不应该是执行到最下面返回0吗 } } if (i2c_read(st.hw->addr, st.reg->fifo_r_w, length, data)) return -1; more[0] = fifo_count / length - 1; return 0; }[/mw_shl_code]

我用的是原子哥的源程序,没做什么改动。是不是哪里的配置问题?
不知道有没有人遇到和我一样的困惑?
求大神解惑。。

最佳答案

查看完整内容[请看2#楼]

当初好像是解决了,但是忘记记录下来了,都忘记怎么搞了。当初好像是接错了电源了还是怎样,因为现在做的话也没出现过这种问题了。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

7

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2015-8-10
在线时间
39 小时
发表于 2015-4-8 17:49:48 | 显示全部楼层
生非死惧 发表于 2016-10-15 14:27
解决了吗?  求解

当初好像是解决了,但是忘记记录下来了,都忘记怎么搞了。当初好像是接错了电源了还是怎样,因为现在做的话也没出现过这种问题了。
回复

使用道具 举报

12

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
123
金钱
123
注册时间
2014-9-25
在线时间
3 小时
 楼主| 发表于 2015-4-8 17:57:56 | 显示全部楼层
好像有点乱。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2015-4-8 22:32:42 | 显示全部楼层
mpu6050初始化成了没有?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

12

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
123
金钱
123
注册时间
2014-9-25
在线时间
3 小时
 楼主| 发表于 2015-4-8 23:42:39 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
初始化了啊。。mpu6050换成了MPU9150。。在mini板上做的。
u8 mpu9150a_init(void)
{
u8 res;
IIC_Init();
Single_Write(MPU_9150A_ADDR,PWR_MGMT_1,0x80); //复位
Delay_ms(100);
Single_Write(MPU_9150A_ADDR,PWR_MGMT_1,0x00); //接触休眠模式
MPU_Set_Gyro_Fsr(3); //陀螺仪传感器,±2000dps
MPU_Set_Accel_Fsr(0); //加速度传感器,±2g
MPU_Set_Rate(50); //设置采样率50Hz

Single_Write(MPU_9150A_ADDR,INT_ENABLE,0X00); //关闭所有中断
Single_Write(MPU_9150A_ADDR,USER_CTRL,0X00); //I2C主模式关闭
Single_Write(MPU_9150A_ADDR,FIFO_EN,0X00); //关闭FIFO
Single_Write(MPU_9150A_ADDR,INT_PIN_CFG,0X82); //INT引脚低电平有效
res=Single_Read(MPU_9150A_ADDR,WHO_AM_I);
if(res==0x68)//器件ID正确
{
Single_Write(MPU_9150A_ADDR,PWR_MGMT_1,0X01); //设置CLKSEL,PLL X轴为参考
Single_Write(MPU_9150A_ADDR,PWR_MGMT_2,0X00); //加速度与陀螺仪都工作
MPU_Set_Rate(50); //设置采样率50Hz
  }else return 1;
return 0;
}
回复

使用道具 举报

12

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
123
金钱
123
注册时间
2014-9-25
在线时间
3 小时
 楼主| 发表于 2015-4-8 23:44:16 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
这里好像一直是溢出状态啊。
if里面为啥要那样写啊?

if (fifo_count > (st.hw->max_fifo >> 1)) {
        // FIFO is 50% full, better check overflow bit. //
        if (i2c_read(st.hw->addr, st.reg->int_status, 1, tmp))
            return -1;
        if (tmp[0] & BIT_FIFO_OVERFLOW) {
            mpu_reset_fifo();
            return -2;
        }
    }
回复

使用道具 举报

12

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
123
金钱
123
注册时间
2014-9-25
在线时间
3 小时
 楼主| 发表于 2015-4-8 23:47:05 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
这里为啥要乘57.3啊。
好多不懂得地方。。
*pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3; // pitch
*roll  = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll
*yaw   = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3; //yaw
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165516
金钱
165516
注册时间
2010-12-1
在线时间
2116 小时
发表于 2015-4-9 23:33:14 | 显示全部楼层
回复【6楼】小小驴:
---------------------------------
推导过程,我也不知道,我直接用的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

12

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
123
金钱
123
注册时间
2014-9-25
在线时间
3 小时
 楼主| 发表于 2015-4-9 23:36:44 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
还是不知道怎么错的。。
我把判断是否溢出的那一段注销了。。
回复

使用道具 举报

7

主题

25

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2015-8-10
在线时间
39 小时
发表于 2015-8-10 13:16:25 | 显示全部楼层
和楼主一样 if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)返回值是1,但是我的if语句进不去。调试也是追寻到mpu_read_fifo_stream的返回值为-2,st.chip_cfg.dmp_on=0,请问楼主怎么解决
回复

使用道具 举报

12

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
123
金钱
123
注册时间
2014-9-25
在线时间
3 小时
 楼主| 发表于 2015-8-20 13:40:54 | 显示全部楼层
回复【9楼】不会啊不会:
---------------------------------
把4楼的那一段给注销了。。现在也没找到更好的 解决方法。有更好的解决方法记得转告哦。
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2015-8-10
在线时间
0 小时
发表于 2015-8-24 09:00:22 | 显示全部楼层
回复【10楼】小小驴:
---------------------------------
mpu_read_fifo_stream的有时候返回值为-2有时候是-1,楼主解决没有啊?
回复

使用道具 举报

6

主题

279

帖子

0

精华

高级会员

Rank: 4

积分
750
金钱
750
注册时间
2015-3-27
在线时间
98 小时
发表于 2015-9-11 21:43:46 | 显示全部楼层
回复【5楼】小小驴:
---------------------------------
其他地方好像说是速度不够快,导致溢出,但是你单纯注释这一段...不会有很多错误么?
回复

使用道具 举报

2

主题

8

帖子

0

精华

新手上路

积分
44
金钱
44
注册时间
2015-7-28
在线时间
2 小时
发表于 2015-12-22 14:55:25 | 显示全部楼层
回复【9楼】不会啊不会:
---------------------------------
请问解决了吗,我也遇到这个问题了
回复

使用道具 举报

2

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
149
金钱
149
注册时间
2013-9-14
在线时间
36 小时
发表于 2016-3-15 21:29:49 | 显示全部楼层
小小驴 发表于 2015-8-20 13:40
回复【9楼】不会啊不会:
---------------------------------
把4楼的那一段给注销了。。现在也没找到更好的 ...

我也遇到一样的问题 请问你解决了吗
回复

使用道具 举报

2

主题

48

帖子

0

精华

初级会员

Rank: 2

积分
149
金钱
149
注册时间
2013-9-14
在线时间
36 小时
发表于 2016-3-15 21:30:50 | 显示全部楼层
我也遇到一样的问题 请问你解决了吗 可以加我QQ243591735 交流一下吗谢谢
回复

使用道具 举报

26

主题

201

帖子

0

精华

高级会员

Rank: 4

积分
606
金钱
606
注册时间
2013-12-14
在线时间
125 小时
发表于 2016-3-18 17:27:56 | 显示全部楼层
我也遇到了,楼主解决了没?
回复

使用道具 举报

15

主题

317

帖子

0

精华

高级会员

Rank: 4

积分
859
金钱
859
注册时间
2015-2-12
在线时间
353 小时
发表于 2016-3-19 09:18:36 | 显示全部楼层
小小驴 发表于 2015-4-8 23:47
回复【3楼】正点原子:
---------------------------------
这里为啥要乘57.3啊。
好多不懂得地方。。
*pitc ...

语法
编辑
ATAN2(Y坐标,X坐标)
X坐标 点的 X 坐标。
Y坐标 点的 Y 坐标。
说明
编辑
结果为正表示从 X 轴逆时针旋转的角度,结果为负表示从 X 轴顺时针旋转的角度。
ATAN2(a, b) 与 ATAN(a/b)稍有不同,ATAN2(a,b)的取值范围介于 -pi 到 pi 之间(不包括 -pi),
而ATAN(a/b)的取值范围介于-pi/2到pi/2之间(不包括±pi/2)。
若要用度表示反正切值,请将结果再乘以 180/3.14159。
另外要注意的是,函数atan2(y,x)中参数的顺序是倒置的,atan2(y,x)计算的值相当于点(x,y)的角度值。


你说的57.3 = 180/3.14159。
回复

使用道具 举报

6

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
172
金钱
172
注册时间
2014-4-25
在线时间
17 小时
发表于 2016-6-2 10:43:16 | 显示全部楼层
小小驴 发表于 2015-4-8 23:44
回复【3楼】正点原子:
---------------------------------
这里好像一直是溢出状态啊。
if里面为啥要那样写 ...

溢出是因为读取的速度慢了,读取快点,最好是在中断中读取
学习会使你永远立于不败之地。
回复

使用道具 举报

0

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2016-1-21
在线时间
15 小时
发表于 2016-6-12 11:50:53 | 显示全部楼层
小小驴 发表于 2015-4-8 23:42
回复【3楼】正点原子:
---------------------------------
初始化了啊。。mpu6050换成了MPU9150。。在mini ...

看一下MPU9150的数据手册,那个器件ID是否为0X68?
回复

使用道具 举报

2

主题

5

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2015-3-18
在线时间
8 小时
发表于 2016-6-23 17:37:01 | 显示全部楼层
如果是杜邦线,试试把电源或者地线跟SCL和SDA放在一起;今天测试到一个现象:只要把地线和电源线都和SCL、SDA分开,通信就异常了,只需要其中一根和SCL、SDA放一起就正常。
回复

使用道具 举报

2

主题

18

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2016-5-13
在线时间
45 小时
发表于 2016-7-18 19:31:54 | 显示全部楼层
请问楼主解决了吗,我也遇到了同样的问题。在使用调试器调试时一直在这里出问题,但是全速执行的时候却可以出现 if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0) 成功进入if语句的情况。(好像并不是每次到这一句时都能进入if语句,只是会出现进入if语句的情况,所以if语句内的代码还是有一定的执行频率的,这句话为猜测)。虽然全速运行时,还是可以读取到三个姿态角度并上传到匿名四轴上位机上,但是在上位机上显示时有很明显的卡顿现象。
回复

使用道具 举报

4

主题

24

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
219
金钱
219
注册时间
2015-8-5
在线时间
43 小时
发表于 2016-10-15 14:27:38 | 显示全部楼层
不会啊不会 发表于 2015-8-10 13:16
和楼主一样&nbsp;if(mpu_dmp_get_data(&pitch,&roll,&yaw)==0)返回值是1,但是我的if语句进不去。调试也是 ...

解决了吗?  求解
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2021-4-16
在线时间
3 小时
发表于 2021-7-6 08:45:21 | 显示全部楼层
解决了吗,太难了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-23 10:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表