f43 发表于 2013-2-7 06:35:57

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

本帖最后由 f43 于 2013-2-7 06:39 编辑

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

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

zywei_09 发表于 2013-2-7 11:55:37

这是陀螺还是加计的数据?
MPU6050有量程设置,超出量程就会截止,好好看手册。
之所以你正负的截止值不对称是因为你传感器没校准,有偏移。

f43 发表于 2013-2-7 19:28:38

zywei_09 发表于 2013-2-7 11:55 static/image/common/back.gif
这是陀螺还是加计的数据?
MPU6050有量程设置,超出量程就会截止,好好看手册。
之所以你正负的截止值不对 ...

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

f43 发表于 2013-2-7 19:39:58

zywei_09 发表于 2013-2-7 11:55 static/image/common/back.gif
这是陀螺还是加计的数据?
MPU6050有量程设置,超出量程就会截止,好好看手册。
之所以你正负的截止值不对 ...

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


zywei_09 发表于 2013-2-8 12:27:46

f43 发表于 2013-2-7 19:39 static/image/common/back.gif
首先还是要感谢,我仔细研究了手册
如果加速度配置成正负4g的话,我在手里缓慢晃动,1秒钟1次(频率1hz) ...

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

f43 发表于 2013-2-8 18:06:11

zywei_09 发表于 2013-2-8 12:27 static/image/common/back.gif
怎么感觉你没读出负的数据,你看看变量定义,以及传递过程中的强制转换。我读取传感器用的是short变量。 ...

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

zywei_09 发表于 2013-2-8 18:46:16

就图和描述来说就不太清楚了,我遇到过是量程导致的,你调成8g或者16g试试。

f43 发表于 2013-2-8 19:00:30

zywei_09 发表于 2013-2-8 18:46 static/image/common/back.gif
就图和描述来说就不太清楚了,我遇到过是量程导致的,你调成8g或者16g试试。 ...

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

zywei_09 发表于 2013-2-8 20:14:03

f43 发表于 2013-2-8 19:00 static/image/common/back.gif
你好,修改量程,好像是没有改变,下面的由于量程不合适,倒是失真的图像
...

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

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

js200300953 发表于 2013-2-8 22:47:12

能贴出处理数据的代码吗?

bygreencn 发表于 2013-2-12 15:57:35

直接贴代码吧,看流程对不对

f43 发表于 2013-2-13 11:32:27

js200300953 发表于 2013-2-8 22:47 static/image/common/back.gif
能贴出处理数据的代码吗?

//********************************************************
//I2C定义延时
//********************************************************
void IIC_Del()
{
int a;
for(a=0;a<50;a++)//7 IS 347kHz29 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 0l 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;
}
   

f43 发表于 2013-2-13 11:33:20

bygreencn 发表于 2013-2-12 15:57 static/image/common/back.gif
直接贴代码吧,看流程对不对

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

js200300953 发表于 2013-2-13 11:59:14

f43 发表于 2013-2-13 11:32 static/image/common/back.gif
//********************************************************
//I2C定义延时
//*********************** ...

int Single_ReadI2C(uchar REG_Address) 这个函数,其实data_l和data_h是可以连续一次性读出的。
补码处理也可能有问题,试试这个:int16_t value = 0;
((uint8_t *)&value) = data_l;
((uint8_t *)&value) = data_h;
return value;

f43 发表于 2013-2-14 07:52:28

js200300953 发表于 2013-2-13 11:59 static/image/common/back.gif
这个函数,其实data_l和data_h是可以连续一次性读出的。
补码处理也可能有问题,试试这个: ...

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

yue621 发表于 2013-4-22 22:30:46

帮顶!!!!!!!!!!!!!!

也无风雨赵 发表于 2013-5-28 15:39:13

最近也早搞这个,头痛中……
页: [1]
查看完整版本: 请教--MPU6050输出信号出现截止失真,什么原因,有图有真相