搜索
bottom↓
回复: 16

请教--MPU6050输出信号出现截止失真,什么原因,有图有真相

[复制链接]

出0入0汤圆

发表于 2013-2-7 06:35:57 | 显示全部楼层 |阅读模式
本帖最后由 f43 于 2013-2-7 06:39 编辑

模块在做沿X轴摆动实验时,出现只有1个轴向上有数据,反方向数值不变如下图

输出负数是可以的,如果是将采集的信号改变符号,则出现饱和失真,感觉还是模块有问题,但是买了新的还是一样
这个测试的模块,陀螺和加速度都是一个情况
请大家给个建议啊

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2013-2-7 11:55:37 | 显示全部楼层
这是陀螺还是加计的数据?
MPU6050有量程设置,超出量程就会截止,好好看手册。
之所以你正负的截止值不对称是因为你传感器没校准,有偏移。

出0入0汤圆

 楼主| 发表于 2013-2-7 19:28:38 | 显示全部楼层
zywei_09 发表于 2013-2-7 11:55
这是陀螺还是加计的数据?
MPU6050有量程设置,超出量程就会截止,好好看手册。
之所以你正负的截止值不对 ...

首先感谢你的回答,针对你的建议,我要做如下说明:
1图是加速度输出数据
2我的量程是正负4g(设置中设置01,8192LSB/g)故输出数据除以8。192
3零偏的问题我是考虑测量陀螺输出数据范围,最终确定零偏的数量大小,虽然我没有修正零偏的数值,但是零偏应该不会偏移到将负半轴的输出都偏移掉吧

出0入0汤圆

 楼主| 发表于 2013-2-7 19:39:58 | 显示全部楼层
zywei_09 发表于 2013-2-7 11:55
这是陀螺还是加计的数据?
MPU6050有量程设置,超出量程就会截止,好好看手册。
之所以你正负的截止值不对 ...


首先还是要感谢,我仔细研究了手册
如果加速度配置成正负4g的话,我在手里缓慢晃动,1秒钟1次(频率1hz)应该不会有4G的加速度,对吧
下面的2张图,分别是没有加零偏的(上图)加零偏修正的(+100)下图
这两图图在数值上相差100左右外,我觉得没有什么其他的区别了
烦请大侠指点
小弟初来乍到,诚信学习


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-2-8 12:27:46 | 显示全部楼层
f43 发表于 2013-2-7 19:39
首先还是要感谢,我仔细研究了手册
如果加速度配置成正负4g的话,我在手里缓慢晃动,1秒钟1次(频率1hz) ...

怎么感觉你没读出负的数据,你看看变量定义,以及传递过程中的强制转换。我读取传感器用的是short变量。

出0入0汤圆

 楼主| 发表于 2013-2-8 18:06:11 | 显示全部楼层
zywei_09 发表于 2013-2-8 12:27
怎么感觉你没读出负的数据,你看看变量定义,以及传递过程中的强制转换。我读取传感器用的是short变量。 ...

数据类型方面我开始有所注意
首先在读取方面都是有符号的,
其次在显示方面,我也测试过负数显示(正常的)
最后在图像上也是,能够显示负数(请看我最开始的图,黄线是在0下面的)
所以我觉得应该不是负数显示的问题

出0入0汤圆

发表于 2013-2-8 18:46:16 | 显示全部楼层
就图和描述来说就不太清楚了,我遇到过是量程导致的,你调成8g或者16g试试。

出0入0汤圆

 楼主| 发表于 2013-2-8 19:00:30 | 显示全部楼层
zywei_09 发表于 2013-2-8 18:46
就图和描述来说就不太清楚了,我遇到过是量程导致的,你调成8g或者16g试试。 ...

你好,修改量程,好像是没有改变,下面的由于量程不合适,倒是失真的图像

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-2-8 20:14:03 | 显示全部楼层
f43 发表于 2013-2-8 19:00
你好,修改量程,好像是没有改变,下面的由于量程不合适,倒是失真的图像
...

好奇怪,你看我的数据,量程是8g,在桌子上使劲乱磕得到的。

不会出现你说的现象啊。在自己好好检查一下吧,我是看不出来了。总之调bug这种事有时就得靠顿悟。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-2-8 22:47:12 | 显示全部楼层
能贴出处理数据的代码吗?

出0入0汤圆

发表于 2013-2-12 15:57:35 来自手机 | 显示全部楼层
直接贴代码吧,看流程对不对

出0入0汤圆

 楼主| 发表于 2013-2-13 11:32:27 | 显示全部楼层
js200300953 发表于 2013-2-8 22:47
能贴出处理数据的代码吗?

//********************************************************
//I2C定义延时
//********************************************************
void IIC_Del()
{
  int a;
  for(a=0;a<50;a++)  //7 IS 347kHz  29 IS 99.7KHz
  _asm(NOP);
}
//***********************************************************************
//I2C起始信号
//***********************************************************************
void I2C_Start()
{
    SDA = 1;
     IIC_Del();
    SCL = 1;
     IIC_Del();
    SDA = 0;
     IIC_Del();
    SCL = 0;
     IIC_Del();
}
//***********************************************************************
//I2C停止信号
//***********************************************************************
void I2C_Stop()
{
    SCL = 0;
     IIC_Del();
    SDA = 0;
     IIC_Del();
    SCL = 1;
     IIC_Del();
    SDA = 1;
     IIC_Del();
}
//***********************************************************************
//向I2C总线发送一个字节数据
//***********************************************************************
uchar I2C_WriteByte(uchar dat)
{
    uchar i;
    for (i=0; i<8; i++)         //8位计数器
    {
        //if(dat & 0x01<<i)
      
        if(dat & 0x80)     //应该是先发送高位,但是不行
        SDA=1;
        else
        SDA=0;
        IIC_Del();
        
        SCL = 1;                //拉高时钟线
        IIC_Del();             //延时
        //IIC_Del();             //延时
        SCL = 0;                //拉低时钟线
        IIC_Del();             //延时
        //IIC_Del();             //延时
        dat<<=1;        
    }
   
    DDRA=0XFD;
    i=50;
    SCL=1;
    while((i>2)&&(SDA==1))
    i--;
    //i=SDA;
    DDRA=0XFF;
    SCL=0;
    IIC_Del();             //延时
    if(i>2) return 0; //  ok
    else    return 1; //  exist = 0 so break
}

//********************************************************
//向I2C总线写地址信息
//********************************************************
void single_byte_write(uchar REG_Address,uchar REG_data)
{
  uchar i;
  i=0;
    I2C_Start();                  //起始信号
    if(I2C_WriteByte(SlaveAddress)==1)i=1;  //发送设备地址+写信号
    if(I2C_WriteByte(REG_Address)==1) i=2;   //内部寄存器地址,
    if(I2C_WriteByte(REG_data)==1)    i=3; //内部寄存器数据,
    I2C_Stop();                   //发送停止信号
    IIC_Del();
    //if(i>0)
    //sci_send_uint(i,0x09,'i');    //_FEED_COP();// feeds the dog /
}

//********************************************************
//向I2C总线写地址信息
//********************************************************
void InitMPU6050()
{
        single_byte_write(PWR_MGMT_1, 0x01);        //解除休眠状态
        single_byte_write(SMPLRT_DIV, 0x07);                                
        single_byte_write(CONFIG, 0x06);
        single_byte_write(GYRO_CONFIG, 0x18);
        single_byte_write(ACCEL_CONFIG, 0x18);  //bit = 000 A1A0 000
  //         single_byte_write(0x1c, 0xf0);
  //        single_byte_write(0x0d, 0x00);
  //        single_byte_write(0x10, 0x10);
}

//***********************************************************************
//向I2C总线发送一个字节数据
//***********************************************************************
char I2C_ReadByte(void)
{
    char i,dat;
    dat=0;
    DDRA=0XFD;
    for (i=0; i<8; i++)         //8位计数器
    {
        SCL = 1;                //拉高时钟线
        IIC_Del();             //延时

        if(SDA)
        dat |= 0x01;
        else
        dat |= 0;
        //IIC_Del();             //延时
        SCL = 0;                //拉低时钟线
        IIC_Del();             //延时
        //IIC_Del();             //延时
        dat>>=1;   
    }
    DDRA=0XFF;
    SDA=1;
    IIC_Del();             //延时
    SCL=1;
    IIC_Del();             //延时
    SCL=0;
    IIC_Del();             //延时
    return dat; //  exist = 0 so break
}

int Single_ReadI2C(uchar REG_Address)
{
  int data;
  char data_l,data_h;
  uchar error;                                 
  data=0;     // h is 0  l is +1
  data_l=0;
  data_h=0;
  error=0;
               
  I2C_Start();                  //起始信号
  error=I2C_WriteByte(SlaveAddress);
  error=I2C_WriteByte(REG_Address);
  I2C_Start();                  //起始信号
  error=I2C_WriteByte(SlaveAddress+1);
  data_h = I2C_ReadByte();
  I2C_Stop();   
  I2C_Start();                  //起始信号
  error=I2C_WriteByte(SlaveAddress);
  error=I2C_WriteByte(REG_Address+1);
  I2C_Start();                  //起始信号
  error=I2C_WriteByte(SlaveAddress+1);
  data_l = I2C_ReadByte();
  I2C_Stop();                          
  //data = data_h<<8+data_l;
  data = data_h<<8;
  data +=data_l;
  return data;  
}
   

出0入0汤圆

 楼主| 发表于 2013-2-13 11:33:20 | 显示全部楼层
bygreencn 发表于 2013-2-12 15:57
直接贴代码吧,看流程对不对

请看楼上的代码,IIC的读取

出0入0汤圆

发表于 2013-2-13 11:59:14 | 显示全部楼层
f43 发表于 2013-2-13 11:32
//********************************************************
//I2C定义延时
//*********************** ...
int Single_ReadI2C(uchar REG_Address)
这个函数,其实data_l和data_h是可以连续一次性读出的。
补码处理也可能有问题,试试这个:
  1. int16_t value = 0;
  2. ((uint8_t *)&value)[0] = data_l;
  3. ((uint8_t *)&value)[1] = data_h;
  4. return value;
复制代码

出0入0汤圆

 楼主| 发表于 2013-2-14 07:52:28 | 显示全部楼层
js200300953 发表于 2013-2-13 11:59
这个函数,其实data_l和data_h是可以连续一次性读出的。
补码处理也可能有问题,试试这个: ...

大哥,好像 是不行啊,使用你的程序出现下面错误
..\SRC\USER\main.c(451): error:  #142: expression must have pointer-to-object type
什么指针错误,我没有指针啊??
另外这个传感器虽然手册上说能burst read但是如果我连续读取的话,都是0,如果分开读取,则能有数据(虽然这个数据出现了截止失真)
最后感谢你的回答,谢谢

出0入0汤圆

发表于 2013-4-22 22:30:46 | 显示全部楼层
帮顶!!!!!!!!!!!!!!

出0入0汤圆

发表于 2013-5-28 15:39:13 | 显示全部楼层
最近也早搞这个,头痛中……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 20:45

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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