极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 22471|回复: 12

做10轴传感器时遇到了莫名问题

[复制链接]
发表于 2012-9-12 18:39:35 | 显示全部楼层 |阅读模式
我的四翼飞行器开始了,论坛上东平西凑的找到了许多代码研究,有些在单一模块上可以正常运行,但是到了10轴中就出问题了,好不容易才找到一个,一开始没问题,完全是平铺直叙的写可以运行,但是编译后居然17K之多,加上滤波等等空间不够了,改称函数调用出了问题。
代码如下
int ADXAddress = 0x53;        // ADXL345的I2C地址

int L3GAddress = 0x69;        // L3G4200D的I2C地址

int HMCAddress = 0x1E;         // HMC5883L的I2C地址

int BMPAddress = 0x77;         // BMP085的I2C地址

long p0=101325;         // 海平面大气压

const unsigned char OSS = 0;        // Oversampling 设置

int  acce[3],magn[3],gyro[3];        //存储传感器xyz三轴结果

long atmo[3];                        //BMP085结果存储,温度,气压,高度

int  temp[6];                        //临时变量,用于存取寄存器值



#include "Wire.h"       // IIC运行库

void setup()

{

  deviceInti();

 

}



void loop()

{

 

    acceRead();

    Serial.print("xAcc=");

    Serial.print(acce[0]);

    Serial.print("  yAcc=");

    Serial.print(acce[1]);

    Serial.print("  zAcc=");

    Serial.println(acce[2]);

    delay(100);



    gyroRead();

    Serial.print("xGyro=");

    Serial.print(gyro[0]);

    Serial.print("  yGyro=");

    Serial.print(gyro[1]);

    Serial.print("  zGyro=");

    Serial.println(gyro[2]);

    delay(100);



    magnRead();

   Serial.print("xMag=");

    Serial.print(magn[0]);

    Serial.print("  yMag=");

    Serial.print(magn[1]);

    Serial.print("  zMag=");

    Serial.println(magn[2]);

    Serial.println();

       

    atmoRead();



    Serial.print("Temperature: ");

    Serial.print(atmo[0], DEC);

    Serial.print(" *0.1 deg C");

    Serial.print("        Pressure: ");

    Serial.print(atmo[1], DEC);

    Serial.print(" Pa");

    Serial.print("        altitude: ");

    Serial.println(atmo[2], DEC);



    delay(1000);

       

}







void deviceInti()                                //初始化

{

        Wire.begin();

        Serial.begin(9600);

        acceInti();

        magnInti();

        gyroInti();

        atmoInti();

       

}



void registerSet(int deviceAddress, int registerAddress, int registerValue)  // 写寄存器

{

           

    Wire.beginTransmission(deviceAddress);

    Wire.write(registerAddress);

    Wire.write(registerValue);

    Wire.endTransmission();

}



void registerRead(int deviceAddress, int registerAddress) // 读寄存器

{ 



        int i;

       

    Wire.beginTransmission(deviceAddress);

    Wire.write(registerAddress);

    Wire.endTransmission();

    Wire.requestFrom(deviceAddress,6);

        if(Wire.available()<=6);;

                {

                &#160;&#160;&#160;&#160;for(i=0;i<6;i++)       

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;temp&#160;=&#160;Wire.read();

                       

                }



        Wire.endTransmission();

       

}



void acceInti()                                                                // 加速度传感器初始化

{

        &#160;registerSet(ADXAddress,0x2D,0x08);                // 测量模式

}



void acceRead()                                                                //加速度读取

{

        registerRead(ADXAddress,0x32);

       

        acce[0]&#160;=&#160;temp[1]<<8&#160;|&#160;temp[0];

        acce[1]&#160;=&#160;temp[3]<<8&#160;|&#160;temp[2];

        acce[2]&#160;=&#160;temp[5]<<8&#160;|&#160;temp[4];

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;

}



void magnInti()                                                                        // 磁场传感器初始化

{

        registerSet(HMCAddress,&#160;0x02,&#160;0x00);&#160;                // 连续测量





}



void magnRead()                                                                        //磁场传感器读取

{

        registerRead(HMCAddress,0x03);

       

        magn[0]&#160;=&#160;temp[0]<<8&#160;|&#160;temp[1];

        magn[1]&#160;=&#160;temp[2]<<8&#160;|&#160;temp[3];

        magn[2]&#160;=&#160;temp[4]<<8&#160;|&#160;temp[5];



}



void gyroInti()                                                        //陀螺仪初始化

{

&#160;&#160;registerSet(L3GAddress,&#160;0x20,&#160;0x0F);&#160;&#160;&#160;// 设置睡眠模式、x, y, z轴使能

&#160;&#160;registerSet(L3GAddress,&#160;0x21,&#160;0x00);&#160;&#160;&#160;// 选择高通滤波模式和高通截止频率

&#160;&#160;registerSet(L3GAddress,&#160;0x22,&#160;0x00);&#160;&#160;&#160;// 设置中断模式

&#160;&#160;registerSet(L3GAddress,&#160;0x23,&#160;0x30);&#160;&#160;&#160;// 设置量程(2000dps)、自检状态、SPI模式

&#160;&#160;registerSet(L3GAddress,&#160;0x24,&#160;0x00);&#160;&#160;&#160;// FIFO & 高通滤波





}



void gyroRead()                                                        // 陀螺仪读取

{

        registerRead(L3GAddress,0x28);



        gyro[0]&#160;=&#160;temp[1]<<8&#160;|&#160;temp[0];

        gyro[1]&#160;=&#160;temp[3]<<8&#160;|&#160;temp[2];

        gyro[2]&#160;=&#160;temp[5]<<8&#160;|&#160;temp[4];



}



void atmoInti()                                                        //气压传感器初始化

{







}



void atmoRead()                                                        //气压传感器读取

{

        int ac1,ac2,ac3;

        unsigned int ac4,ac5,ac6,ut;

        int b1,b2,mb,mc,md;

        long b5,x1, x2, x3, b3, b6, p,pressure,altitude;

        short temperature;

        unsigned long up,b4, b7;

        //////////////////////////////////////内部寄存器读取

        registerRead(BMPAddress,0xAA);

       

        ac1&#160;=&#160;temp[0]<<8&#160;|&#160;temp[1];

        ac2&#160;=&#160;temp[2]<<8&#160;|&#160;temp[3];

        ac3&#160;=&#160;temp[4]<<8&#160;|&#160;temp[5];

       

        registerRead(BMPAddress,0xB0);

       

        ac4&#160;=&#160;temp[0]<<8&#160;|&#160;temp[1];

        ac5&#160;=&#160;temp[2]<<8&#160;|&#160;temp[3];

        ac6&#160;=&#160;temp[4]<<8&#160;|&#160;temp[5];

       

        registerRead(BMPAddress,0xB6);

       

        b1&#160;=&#160;temp[0]<<8&#160;|&#160;temp[1];

        b2&#160;=&#160;temp[2]<<8&#160;|&#160;temp[3];

        ;

        registerRead(BMPAddress,0xBA);

       

        mb&#160;=&#160;temp[0]<<8&#160;|&#160;temp[1];

        mc&#160;=&#160;temp[2]<<8&#160;|&#160;temp[3];

        md&#160;=&#160;temp[4]<<8&#160;|&#160;temp[5];

       

        /////////////////////////////////////////////////计算UP值

        registerSet(BMPAddress,0xF4,0x34&#160;+&#160;(OSS<<6));



        delay(2 + (3<<OSS));

&#160;

        registerRead(BMPAddress,0xF6);

&#160;&#160;&#160;&#160;

        up&#160;=&#160;(((unsigned long) temp[0] << 16) | ((unsigned long) temp[1] << 8) | (unsigned long) temp[2]) >> (8-OSS);

       

        /////////////////////////////////////////////////计算UT值

        registerSet(BMPAddress,0xF4,0x2E);

       

        delay(5);

       

        registerRead(BMPAddress,0xF6);

       

        ut&#160;=&#160;temp[0]&#160;<<&#160;8&#160;|&#160;temp[1];

        /////////////////////////////////////////////////计算温度



        x1&#160;=&#160;(((long)ut - (long)ac6)*(long)ac5) >> 15;

        x2&#160;=&#160;((long)mc << 11)/(x1 + md);

        b5&#160;=&#160;x1&#160;+&#160;x2;

&#160;

        temperature&#160;=&#160;((b5&#160;+&#160;8)>>4);&#160;

       

        //////////////////////////////////////////////////计算气压



        b6&#160;=&#160;b5&#160;-&#160;4000;

        x1&#160;=&#160;(b2&#160;*&#160;(b6&#160;*&#160;b6)>>12)>>11;

        x2&#160;=&#160;(ac2&#160;*&#160;b6)>>11;

        x3&#160;=&#160;x1&#160;+&#160;x2;

        b3&#160;=&#160;(((((long)ac1)*4 + x3)<<OSS) + 2)>>2;

&#160;

        x1&#160;=&#160;(ac3&#160;*&#160;b6)>>13;

        x2&#160;=&#160;(b1&#160;*&#160;((b6&#160;*&#160;b6)>>12))>>16;

        x3&#160;=&#160;((x1&#160;+&#160;x2)&#160;+&#160;2)>>2;

        b4&#160;=&#160;(ac4&#160;*&#160;(unsigned long)(x3 + 32768))>>15;

&#160;

        b7&#160;=&#160;((unsigned long)(up - b3) * (50000>>OSS));

        if (b7 < 0x80000000)

                p&#160;=&#160;(b7<<1)/b4;

        else

                p&#160;=&#160;(b7/b4)<<1;

&#160;&#160;&#160;

        x1&#160;=&#160;(p>>8)&#160;*&#160;(p>>8);

        x1&#160;=&#160;(x1&#160;*&#160;3038)>>16;

        x2&#160;=&#160;(-7357&#160;*&#160;p)>>16;

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;p&#160;+=&#160;(x1&#160;+&#160;x2&#160;+&#160;3791)>>4;

        pressure&#160;=&#160;p;

        //////////////////////////////////////////////////计算海拔

        altitude&#160;=&#160;44330*(1-pow((double)p/p0,1/5.255))*100;

       

        ////////////////////////

        atmo[0]&#160;=&#160;temperature;

        atmo[1]&#160;=&#160;pressure;

        atmo[2]&#160;=&#160;altitude;

       

}


运行结果

陀螺仪出现了问题,经过检查发现6个寄存器得到的结果是同一个数值,而其他的都正确。

为了验证是否是器件问题,用了另一个代码

#include&#160;<Wire.h>           // IIC运行库





const unsigned char OSS = 0;  // Oversampling Setting

float  p0=1013.25;

int BMPAddress = 0x77;

int ADXAddress = 0x53;             // ADXL345的I2C地址

int L3GAddress = 0x69;      // L3G4200D的I2C地址

int HMCAddress = 0x1E;      // HMC5883L的I2C地址



byte vL, vH,vOF;            // 存放低位、高位值

int xAcc,  yAcc,  zAcc;     // 存放加速度值(整型)

int xGyro, yGyro, zGyro;    // 存放角速度值(整型)

int xMag,  yMag,  zMag;     // 存放地磁场值(整型)



int xOfst,yOfst,zOfst;     // 存放加速度偏移值(整型)



float  xAf,  yAf,  zAf;     // 存放加速度值(浮点)

float  xGf, yGf, zGf;      // 存放角速度值(浮点)

float  xMf,  yMf,  zMf;     // 存放地磁场值(浮点)



                                                        // 存放压力寄存器值

int ac1;

int ac2;

int ac3;

unsigned int ac4;

unsigned int ac5;

unsigned int ac6;

int b1;

int b2;

int mb;

int mc;

int md;

long b5;

                                                       

short temperature;                        //存放温度变量值

long pressure;                                //存放压力变量值





void setup()

{

&#160;&#160;&#160;&#160;Serial.begin(9600);         // 定义串口

&#160;&#160;&#160;&#160;Wire.begin();

&#160;&#160;&#160;&#160;delay(100);

&#160;&#160;&#160;&#160;Serial.println(" Device Initializating......");

&#160;&#160;&#160;&#160;void deviceInt();                        //设备初始化

&#160;&#160;&#160;&#160;delay(2000);

}



void loop()

{

&#160;&#160;&#160;&#160;getAccValues();                                //输出加速度

&#160;&#160;&#160;&#160;Serial.print("xAcc=");

&#160;&#160;&#160;&#160;Serial.print(xAcc);

&#160;&#160;&#160;&#160;Serial.print("  yAcc=");

&#160;&#160;&#160;&#160;Serial.print(yAcc);

&#160;&#160;&#160;&#160;Serial.print("  zAcc=");

&#160;&#160;&#160;&#160;Serial.println(zAcc);

&#160;&#160;&#160;&#160;delay(100);



&#160;&#160;&#160;&#160;getGyroValues();                        //输出角加速度

&#160;&#160;&#160;&#160;Serial.print("xGyro=");

&#160;&#160;&#160;&#160;Serial.print(xGyro);

&#160;&#160;&#160;&#160;Serial.print("  yGyro=");

&#160;&#160;&#160;&#160;Serial.print(yGyro);

&#160;&#160;&#160;&#160;Serial.print("  zGyro=");

&#160;&#160;&#160;&#160;Serial.println(zGyro);

&#160;&#160;&#160;&#160;delay(100);



&#160;&#160;&#160;&#160;getMagValues();                                //输出磁罗盘

&#160;&#160;&#160;&#160;Serial.print("xMag=");

&#160;&#160;&#160;&#160;Serial.print(xMag);

&#160;&#160;&#160;&#160;Serial.print("  yMag=");

&#160;&#160;&#160;&#160;Serial.print(yMag);

&#160;&#160;&#160;&#160;Serial.print("  zMag=");

&#160;&#160;&#160;&#160;Serial.println(zMag);

&#160;&#160;&#160;&#160;Serial.println();

       

        temperature&#160;=&#160;getTemperature(readUT());                //输出温度

        pressure&#160;=&#160;getPressure(readUP());                //输出压力

        Serial.print("Temperature: ");

        Serial.print(temperature, DEC);

        Serial.println(" *0.1 deg C");

        Serial.print("Pressure: ");

        Serial.print(pressure, DEC);

        Serial.println(" Pa");

        Serial.println();

       

       

&#160;&#160;&#160;&#160;delay(1000);

}



void deviceInt()

{

&#160;&#160;&#160;&#160;writeRegister(ADXAddress,&#160;0x2D,&#160;0b00001000);&#160;&#160;&#160;// 测量模式

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 配置ADXL345

&#160;&#160;&#160;&#160;writeRegister(L3GAddress,&#160;0x20,&#160;0b00001111);&#160;&#160;&#160;// 设置睡眠模式、x, y, z轴使能

&#160;&#160;&#160;&#160;writeRegister(L3GAddress,&#160;0x21,&#160;0b00000000);&#160;&#160;&#160;// 选择高通滤波模式和高通截止频率

&#160;&#160;&#160;&#160;writeRegister(L3GAddress,&#160;0x22,&#160;0b00000000);&#160;&#160;&#160;// 设置中断模式

&#160;&#160;&#160;&#160;writeRegister(L3GAddress,&#160;0x23,&#160;0b00110000);&#160;&#160;&#160;// 设置量程(2000dps)、自检状态、SPI模式

&#160;&#160;&#160;&#160;writeRegister(L3GAddress,&#160;0x24,&#160;0b00000000);&#160;&#160;&#160;// FIFO & 高通滤波

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 配置L3G4200D(2000 deg/sec)

&#160;&#160;&#160;&#160;writeRegister(HMCAddress,&#160;0x02,&#160;0x00);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 连续测量

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;// 配置HMC5883L



        bmpCalibration();

}



void setAccOffset()                                                                        //加速度偏移设置

{

        writeRegister(ADXAddress,&#160;0x1E,&#160;0x00);

        writeRegister(ADXAddress,&#160;0x1F,&#160;0x00);

        writeRegister(ADXAddress,&#160;0x20,&#160;0x00);



}



void getAccValues()                                                                // 加速度值读取

{

&#160;&#160;&#160;&#160;vL&#160;=&#160;readRegister(ADXAddress,&#160;0x32);

&#160;&#160;&#160;&#160;vH&#160;=&#160;readRegister(ADXAddress,&#160;0x33);

        vOF&#160;=&#160;readRegister(ADXAddress,&#160;0x1E);

&#160;&#160;&#160;&#160;xAcc&#160;=&#160;(vH&#160;<<&#160;8)&#160;|&#160;vL;

        xAcc&#160;=&#160;xAcc&#160;+vOF;

        xAf&#160;=&#160;xAcc/2560.0000;

       

&#160;&#160;&#160;&#160;vL&#160;=&#160;readRegister(ADXAddress,&#160;0x34);

&#160;&#160;&#160;&#160;vH&#160;=&#160;readRegister(ADXAddress,&#160;0x35);

        vOF&#160;=&#160;readRegister(ADXAddress,&#160;0x1F);

&#160;&#160;&#160;&#160;yAcc&#160;=&#160;(vH&#160;<<&#160;8)&#160;|&#160;vL;

        yAcc&#160;=&#160;yAcc&#160;+&#160;vOF;

        yAf&#160;=&#160;yAcc/2560.0000;

       

&#160;&#160;&#160;&#160;vL&#160;=&#160;readRegister(ADXAddress,&#160;0x36);

&#160;&#160;&#160;&#160;vH&#160;=&#160;readRegister(ADXAddress,&#160;0x37);

        vOF&#160;=&#160;readRegister(ADXAddress,&#160;0x20);

&#160;&#160;&#160;&#160;zAcc&#160;=&#160;(vH&#160;<<&#160;8)&#160;|&#160;vL;

        zAcc&#160;=&#160;zAcc&#160;+&#160;vOF;

        zAf&#160;=&#160;zAcc/2560.0000;

}



void getGyroValues()                                                        // 角速度值读取

{

&#160;&#160;&#160;&#160;vL&#160;=&#160;readRegister(L3GAddress,&#160;0x28);

&#160;&#160;&#160;&#160;vH&#160;=&#160;readRegister(L3GAddress,&#160;0x29);

&#160;&#160;&#160;&#160;xGyro&#160;=&#160;(vH&#160;<<&#160;8)&#160;|&#160;vL;



&#160;&#160;&#160;&#160;vL&#160;=&#160;readRegister(L3GAddress,&#160;0x2A);

&#160;&#160;&#160;&#160;vH&#160;=&#160;readRegister(L3GAddress,&#160;0x2B);

&#160;&#160;&#160;&#160;yGyro&#160;=&#160;(vH&#160;<<&#160;8)&#160;|&#160;vL;



&#160;&#160;&#160;&#160;vL&#160;=&#160;readRegister(L3GAddress,&#160;0x2C);

&#160;&#160;&#160;&#160;vH&#160;=&#160;readRegister(L3GAddress,&#160;0x2D);

&#160;&#160;&#160;&#160;zGyro&#160;=&#160;(vH&#160;<<&#160;8)&#160;|&#160;vL;

       

}



void getMagValues()                                                                // 磁场值读取

{

&#160;&#160;&#160;&#160;vH&#160;=&#160;readRegister(HMCAddress,&#160;0x03);

&#160;&#160;&#160;&#160;vL&#160;=&#160;readRegister(HMCAddress,&#160;0x04);

&#160;&#160;&#160;&#160;xMag&#160;=&#160;(vH&#160;<<&#160;8)&#160;|&#160;vL;

       

&#160;&#160;&#160;&#160;vH&#160;=&#160;readRegister(HMCAddress,&#160;0x05);

&#160;&#160;&#160;&#160;vL&#160;=&#160;readRegister(HMCAddress,&#160;0x06);

&#160;&#160;&#160;&#160;yMag&#160;=&#160;(vH&#160;<<&#160;8)&#160;|&#160;vL;



&#160;&#160;&#160;&#160;vH&#160;=&#160;readRegister(HMCAddress,&#160;0x07);

&#160;&#160;&#160;&#160;vL&#160;=&#160;readRegister(HMCAddress,&#160;0x08);

&#160;&#160;&#160;&#160;zMag&#160;=&#160;(vH&#160;<<&#160;8)&#160;|&#160;vL;

       

       

       

}

       

void bmpCalibration()                                                                //气压传感器值读取

{

&#160;&#160;ac1&#160;=&#160;readInt(0xAA);

&#160;&#160;ac2&#160;=&#160;readInt(0xAC);

&#160;&#160;ac3&#160;=&#160;readInt(0xAE);

&#160;&#160;ac4&#160;=&#160;readInt(0xB0);

&#160;&#160;ac5&#160;=&#160;readInt(0xB2);

&#160;&#160;ac6&#160;=&#160;readInt(0xB4);

&#160;&#160;b1&#160;=&#160;readInt(0xB6);

&#160;&#160;b2&#160;=&#160;readInt(0xB8);

&#160;&#160;mb&#160;=&#160;readInt(0xBA);

&#160;&#160;mc&#160;=&#160;readInt(0xBC);

&#160;&#160;md&#160;=&#160;readInt(0xBE);

}





short getTemperature(unsigned int ut)                                //温度计算

{

&#160;&#160;long x1, x2;

&#160;

&#160;&#160;x1&#160;=&#160;(((long)ut - (long)ac6)*(long)ac5) >> 15;

&#160;&#160;x2&#160;=&#160;((long)mc << 11)/(x1 + md);

&#160;&#160;b5&#160;=&#160;x1&#160;+&#160;x2;

&#160;

&#160;&#160;return ((b5 + 8)>>4);

}







long getPressure(unsigned long up)                                        //气压计算

{

&#160;&#160;long x1, x2, x3, b3, b6, p;

&#160;&#160;unsigned long b4, b7,ut;

&#160;&#160;ut=readUT();

&#160;&#160;

&#160;&#160;x1&#160;=&#160;(((long)ut - (long)ac6)*(long)ac5) >> 15;

&#160;&#160;x2&#160;=&#160;((long)mc << 11)/(x1 + md);

&#160;&#160;b5&#160;=&#160;x1&#160;+&#160;x2;

&#160;

&#160;&#160;b6&#160;=&#160;b5&#160;-&#160;4000;

&#160;&#160;// 计算 B3

&#160;&#160;x1&#160;=&#160;(b2&#160;*&#160;(b6&#160;*&#160;b6)>>12)>>11;

&#160;&#160;x2&#160;=&#160;(ac2&#160;*&#160;b6)>>11;

&#160;&#160;x3&#160;=&#160;x1&#160;+&#160;x2;

&#160;&#160;b3&#160;=&#160;(((((long)ac1)*4 + x3)<<OSS) + 2)>>2;

&#160;

&#160;&#160;// 计算 B4

&#160;&#160;x1&#160;=&#160;(ac3&#160;*&#160;b6)>>13;

&#160;&#160;x2&#160;=&#160;(b1&#160;*&#160;((b6&#160;*&#160;b6)>>12))>>16;

&#160;&#160;x3&#160;=&#160;((x1&#160;+&#160;x2)&#160;+&#160;2)>>2;

&#160;&#160;b4&#160;=&#160;(ac4&#160;*&#160;(unsigned long)(x3 + 32768))>>15;

&#160;

&#160;&#160;b7&#160;=&#160;((unsigned long)(up - b3) * (50000>>OSS));

&#160;&#160;if (b7 < 0x80000000)

&#160;&#160;&#160;&#160;p&#160;=&#160;(b7<<1)/b4;

&#160;&#160;else

&#160;&#160;&#160;&#160;p&#160;=&#160;(b7/b4)<<1;

&#160;&#160;&#160;

&#160;&#160;x1&#160;=&#160;(p>>8)&#160;*&#160;(p>>8);

&#160;&#160;x1&#160;=&#160;(x1&#160;*&#160;3038)>>16;

&#160;&#160;x2&#160;=&#160;(-7357&#160;*&#160;p)>>16;

&#160;&#160;p&#160;+=&#160;(x1&#160;+&#160;x2&#160;+&#160;3791)>>4;

&#160;

&#160;&#160;return p;

}

&#160;

&#160;&#160;float getAltitude(long p)

&#160;{

        float al;

       

        al&#160;=&#160;44330*(1-pow(p/p0,1/5.255));

       

        return al;

&#160;}

&#160;

int readInt(int address)                                        //两字节寄存器读取

{

&#160;&#160;unsigned char msb, lsb;

&#160;

&#160;&#160;msb&#160;=&#160;readRegister(BMPAddress,address);

&#160;&#160;lsb&#160;=&#160;readRegister(BMPAddress,address+0x01);

&#160;

&#160;&#160;return (int) msb<<8 | lsb;

}









unsigned int readUT()                                                                                //UT计算

{

        unsigned int ut;

&#160;

&#160;&#160;// Write 0x2E into Register 0xF4

&#160;&#160;// This requests a temperature reading

&#160;

        writeRegister(BMPAddress,0xF4,0x2E);

&#160;

&#160;&#160;// Wait at least 4.5ms

        delay(5);

&#160;

&#160;&#160;// Read two bytes from registers 0xF6 and 0xF7

        ut&#160;=&#160;readInt(0xF6);

        return ut;

}







unsigned long readUP()                                                                                //三字节寄存器读取

{

&#160;&#160;unsigned char msb, lsb, xlsb;

&#160;&#160;unsigned long up = 0;

&#160;

&#160;&#160;// Write 0x34+(OSS<<6) into register 0xF4

&#160;&#160;// Request a pressure reading w/ oversampling setting



&#160;writeRegister(BMPAddress,0xF4,(0x34&#160;+&#160;(OSS<<6)));

&#160;

&#160;&#160;// Wait for conversion, delay time dependent on OSS

&#160;&#160;delay(2 + (3<<OSS));

&#160;

&#160;&#160;// Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)

&#160;

&#160;&#160;msb&#160;=&#160;readRegister(BMPAddress,0xF6);

&#160;&#160;lsb&#160;=&#160;readRegister(BMPAddress,0xF7);

&#160;&#160;xlsb&#160;=&#160;readRegister(BMPAddress,0xF8);

&#160;

&#160;&#160;up&#160;=&#160;(((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);

&#160;

&#160;&#160;return up;

}



int readRegister(int deviceAddress, byte address) // 读寄存器

{

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;

&#160;&#160;&#160;&#160;int v;

&#160;&#160;&#160;&#160;Wire.beginTransmission(deviceAddress);

&#160;&#160;&#160;&#160;Wire.write(address);

&#160;&#160;&#160;&#160;Wire.endTransmission();

&#160;&#160;&#160;&#160;Wire.requestFrom(deviceAddress, 1);

&#160;&#160;&#160;&#160;while(!Wire.available()) {}

&#160;&#160;&#160;&#160;v&#160;=&#160;Wire.read();

&#160;&#160;&#160;&#160;return v;

}



void writeRegister(int deviceAddress, byte address, byte val)  // 写寄存器

{

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;

&#160;&#160;&#160;&#160;Wire.beginTransmission(deviceAddress);

&#160;&#160;&#160;&#160;Wire.write(address);

&#160;&#160;&#160;&#160;Wire.write(val);

&#160;&#160;&#160;&#160;Wire.endTransmission();

}


这一次运行正常了,结果


搞不懂什么原因。求达人指导。

本帖子中包含更多资源

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

x
回复

使用道具 举报

 楼主| 发表于 2012-9-12 21:41:32 | 显示全部楼层
我发了好几个求助贴都没有解决
回复 支持 反对

使用道具 举报

发表于 2012-9-12 23:45:01 | 显示全部楼层
这应该不是陀螺仪的问题
看了你的代码
只见你把temp[]值赋给其他变量,没给temp[]更新啊??
估计这就是问题
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-9-13 00:13:38 | 显示全部楼层
Malc 发表于 2012-9-12 23:45
这应该不是陀螺仪的问题
看了你的代码
只见你把temp[]值赋给其他变量,没给temp[]更新啊??

如果是因为temp[]没更新,那么后面的5883也应该有问题才对。而且我做了很多尝试,屏蔽了其他函数,同样陀螺仪读数不正常。就是四个传感器一起运行,我做过测试,每次temp[]付值前输出都是0。这个是基于C语言的,按照C语言的规则,函数调用变量后并不需要清零,再说了,读取寄存器时已经相当于一次重新付值了,现在的关键是六组数据在陀螺仪中是相同的,而且移动传感器寄存器值不变。
按照网上的另一种说法是陀螺仪寄存器不能用0x28,要用0xA8,最高位要是1寄存器指针才会自动加1,明天测试以下在看了。看了动力老男孩的代码,他用的是0xA8作为地址。
回复 支持 反对

使用道具 举报

发表于 2012-9-13 00:54:30 | 显示全部楼层
萧芸凤 发表于 2012-9-13 00:13
如果是因为temp[]没更新,那么后面的5883也应该有问题才对。而且我做了很多尝试,屏蔽了其他函数,同样 ...

你看一下代码里面的registeRead()
里面那段for里头temp=Wire.read();
这个应该是语法错误,编译无法通过的
查了l3g4200的datasheet,没有0xa8这个寄存器。。
回复 支持 反对

使用道具 举报

发表于 2012-9-13 01:06:49 | 显示全部楼层
http://www.geek-workshop.com/forum.php?mod=viewthread&tid=659
貌似有人曾经也遇到了类似问题,也是读取0xA8解决。。
这个以后再研究
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-9-13 17:49:38 | 显示全部楼层
Malc 发表于 2012-9-13 00:54
你看一下代码里面的registeRead()
里面那段for里头temp=Wire.read();
这个应该是语法错误,编译无法通 ...

解决了,要把0x28改成0xA8,4200中是没有这个寄存器,其实就是哪个数据寄存器28,最高位设1就成了A8了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-9-13 17:59:22 | 显示全部楼层
现在寄存器是输出了,但是,但是这些结果是什么意思,我是说是什么单位。
L345我知道除以256就是g值,但是4200输出的是什么单位,直接积分就是角度吗,还是需要转换以下才能积分?5883输出的又是什么单位,如何才能得到角度,比如说北偏东多少度?

最新的结果如图

我是参考论坛上的几个代码做的转换,很奇怪,只要稍稍的动一下陀螺仪的数据就变的很大,而且也不会再回到原来的水平。
代码如下
void accAngle()

{

        int i;

        float accR = 0,

        acceRead();

       

        for( i = 0 ; i < 3 ; i++ )

        {&#160;&#160;&#160;&#160;&#160;

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;acce&#160;=&#160;acce&#160;+&#160;accofst;

&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;accef&#160;=&#160;acce&#160;/256.00;

        &#160;&#160;&#160;&#160;accR&#160;=&#160;accR&#160;+&#160;accef*accef;

        }

       

        accR&#160;=&#160;sqrt(accR);

       

        for( i = 0 ; i < 3 ; i++ )

        {

                accangle&#160;=&#160;90-(180.00&#160;*&#160;acos(accef/accR) / PI);

        }

       

       

       

}



void gyrAngle()

{

        int i;

       

        gyroRead();

       

        for( i = 0; i < 3 ; i++)

        {

               

                gyrangle&#160;=&#160;gyrangle&#160;+&#160;GYRO_GAIN&#160;*&#160;(gyro&#160;+&#160;gyrofst)&#160;*&#160;i_time/1000;

               

        }



}



void magAngle()

{

        int i;

        float scale = scaleSet(1);

        magnRead();

       

        for( i = 0 ; i < 3 ; i++)

        {

                magn&#160;=scale&#160;*&#160;(&#160;magn&#160;+&#160;magofst&#160;);

        }



        magnf[0]&#160;=&#160;atan2( magn[1] , magn[0] );

        magnf[1]&#160;=&#160;atan2( magn[2] , magn[0] );

        magnf[2]&#160;=&#160;atan2( magn[2] , magn[1] );       

       

        for( i=0; i<3;i++)

        {

                if (magnf<0)

                        magnf&#160;=&#160;magnf&#160;+&#160;2&#160;*&#160;PI;

                else if (magnf > 2*PI )

                        magnf&#160;=&#160;magnf&#160;-&#160;2&#160;*&#160;PI;

               

                magangle&#160;=&#160;magnf&#160;*&#160;180.00&#160;/&#160;PI;

        }

       

               

       

}



float scaleSet(float guass)

{

        int registerB;

        float scale;

       

        switch( guass)

        {

                default :

                               

                        break;

                case 0:      //0.88 :

                        scale&#160;=&#160;0.73;

                        registerB&#160;=&#160;0x00;

                        break;

                case 1:     //1.3 :

                        scale&#160;=&#160;0.92;

                        registerB&#160;=&#160;0x01;

                        break;

                case 2 :  // 1.9

                        scale&#160;=&#160;1.22;

                        registerB&#160;=&#160;0x02;

                        break;

                case 3 :       //2.5 :

                        scale&#160;=&#160;1.52;

                        registerB&#160;=&#160;0x03;

                        break;

                case 4:         //4.0 :

                        scale&#160;=&#160;2.27;

                        registerB&#160;=&#160;0x04;

                        break;       

                case 5:             //4.7 :

                        scale&#160;=&#160;2.56;

                        registerB&#160;=&#160;0x05;

                        break;

                case 6:            //5.6 :

                        scale&#160;=&#160;3.03;

                        registerB&#160;=&#160;0x06;

                        break;

                case 7:           //8.1 :

                        scale&#160;=&#160;4.35;

                        registerB&#160;=&#160;0x07;

                        break;

       

        }

       

        registerSet(HMCAddress,0x01,registerB<<5);

        return scale;

}

本帖子中包含更多资源

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

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-9-14 17:56:26 | 显示全部楼层
代码写完了,输出的结果很奇怪,放在那里不动,角度一直在增加,而如果不断的移动增加的速度居然又跟不上了。主要是在陀螺仪上面,静止的时候有漂移,但要是运动起来输出又不足以让速度(角度) 变化起来。
还有一个问题,在做滤波融合的时候,加速的X轴计算结果应该是和陀螺仪的Y轴进行的吧,X轴移动的角度可以看作绕Y轴的旋转。不知道这样理解是否正确。
到目前为止还不知道磁场测出的结果有什么用。
同样的程序,今天运行后得到的海拔居然是-18米,昨天是24米,气压有变化,不知道是不是和今天杭州下雨有关。
回复 支持 反对

使用道具 举报

发表于 2013-6-30 20:56:01 | 显示全部楼层
陀螺仪有漂移是正常的,会导致角度一直增加,解决方法大概是用加速度传感器来修正,陀螺仪的动态响应不错,所以用来测试角速度和角加速度比较好。
建议查找一本书,两轮自平衡机器人原理,好像是这个书名,里面对陀螺仪和加速度计结合测试角度,角速度和角加速度有深刻的分析,还有各种参考系,还有个惯性导联系统之类,说的就是这些原理性的东西。
回复 支持 反对

使用道具 举报

发表于 2013-6-30 21:37:18 | 显示全部楼层
楼主发帖果然引出了不少高手啊 ,继续学习楼主的10轴为以后做参考
回复 支持 反对

使用道具 举报

发表于 2014-6-30 21:43:37 | 显示全部楼层
好资料 留个爪,以后再看
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-14 09:20 , Processed in 0.086162 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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