本帖最後由 Bhai 於 2012-11-21 20:34 編輯
我目前在用 Arduino 做四軸,
我用的是 L3G4200D 的陀螺儀,
但是我在做積分時,陀螺儀靜止時候的角度也會一直加上去,
請問...這該怎麼解決?
下面是我用 L3G4200D 求角度的程式。
- #include <Wire.h>
- #define CTRL_REG1 0x20
- #define CTRL_REG2 0x21
- #define CTRL_REG3 0x22
- #define CTRL_REG4 0x23
- #define CTRL_REG5 0x24
- int L3G4200D_Address = 105; //I2C address of the L3G4200D
- int x;
- int y;
- int z;
- float angleG;
- float gyroSpeed;
- unsigned long o_timer, timer;
- void setup(){
- Wire.begin();
- Serial.begin(9600);
- Serial.println("starting up L3G4200D");
- setupL3G4200D(250); // Configure L3G4200 - 250, 500 or 2000 deg/sec
- angleG = 0;
- gyroSpeed = 0;
- o_timer = 0;
- timer = 0;
- delay(1500); //wait for the sensor to be ready
- timer = millis();
- }
- void loop() {
- long o_timer = timer;
- getGyroValues(); // This will update x, y, and z with new values
- timer = millis();
- int dt = timer - o_timer;
- gyroSpeed = x * 8.75 / 1000;
- angleG = angleG + gyroSpeed * dt / 1000;
- Serial.print("angle_x: ");
- Serial.println(angleG,6);
-
- //delay(100); //Just here to slow down the serial to make it more readable
- }
- void getGyroValues(){
- //(deg/sec)
- byte xMSB = readRegister(L3G4200D_Address, 0x29);
- byte xLSB = readRegister(L3G4200D_Address, 0x28);
- x = ((xMSB << 8) | xLSB);
- byte yMSB = readRegister(L3G4200D_Address, 0x2B);
- byte yLSB = readRegister(L3G4200D_Address, 0x2A);
- y = ((yMSB << 8) | yLSB);
- byte zMSB = readRegister(L3G4200D_Address, 0x2D);
- byte zLSB = readRegister(L3G4200D_Address, 0x2C);
- z = ((zMSB << 8) | zLSB);
- }
- int setupL3G4200D(int scale){
- //From Jim Lindblom of Sparkfun's code
- // Enable x, y, z and turn off power down:
- writeRegister(L3G4200D_Address, CTRL_REG1, 0b00001111);
- // If you'd like to adjust/use the HPF, you can edit the line below to configure CTRL_REG2:
- writeRegister(L3G4200D_Address, CTRL_REG2, 0b00000000);
- // Configure CTRL_REG3 to generate data ready interrupt on INT2
- // No interrupts used on INT1, if you'd like to configure INT1
- // or INT2 otherwise, consult the datasheet:
- writeRegister(L3G4200D_Address, CTRL_REG3, 0b00001000);
- // CTRL_REG4 controls the full-scale range, among other things:
- if(scale == 250){
- writeRegister(L3G4200D_Address, CTRL_REG4, 0b00000000);
- }else if(scale == 500){
- writeRegister(L3G4200D_Address, CTRL_REG4, 0b00010000);
- }else{
- writeRegister(L3G4200D_Address, CTRL_REG4, 0b00110000);
- }
- // CTRL_REG5 controls high-pass filtering of outputs, use it
- // if you'd like:
- writeRegister(L3G4200D_Address, CTRL_REG5, 0b00000000);
- }
- void writeRegister(int deviceAddress, byte address, byte val) {
- Wire.beginTransmission(deviceAddress); // start transmission to device
- Wire.write(address); // send register address
- Wire.write(val); // send value to write
- Wire.endTransmission(); // end transmission
- }
- int readRegister(int deviceAddress, byte address){
- int v;
- Wire.beginTransmission(deviceAddress);
- Wire.write(address); // register to read
- Wire.endTransmission();
- Wire.requestFrom(deviceAddress, 1); // read a byte
- v = Wire.read();
- return v;
- }
複製代碼 |