Gyro pregunta si los números no permanecen estables al quedarse quieto

1

Estoy usando un giroscopio de 3 ejes Parallax L3G4200D. Cuando se deja un giro en una superficie plana sin que nada que interactúe con él en todas las salidas debería ser "0", ¿correcto? Lo mío es saltar entre números. Por ejemplo, "X_L = 0" y "X_H = 17219" con un "retraso (500)" entre la actualización, X_H saltará mientras que X_L se mantiene prácticamente en 0, pero ocasionalmente saltará muy alto. ¿Crees que esto es un problema con el sensor o algo relacionado con el código? Si levanto el Gyro y lo agito alrededor, todos los números comienzan a actualizarse y funcionan correctamente. A continuación se muestra el resultado del que estoy hablando. Esto es cuando está plano y nada interactúa con él:

Value of X is: 20
Value of Y is: 85
Value of Z is: 147168
Y_L equals: 0
Y_H equals: 9766
X_L equals: 2313
X_H equals: 0
Z_L equals: 34782
Z_H equals: 65535
The temperature is: 75


Value of X is: 22
Value of Y is: 49
Value of Z is: 147167
Y_L equals: 0
Y_H equals: 5654
X_L equals: 3855
X_H equals: 0
Z_L equals: 51143
Z_H equals: 65535
The temperature is: 75


Value of X is: 29
Value of Y is: 76
Value of Z is: 147168
Y_L equals: 0
Y_H equals: 8995
X_L equals: 65021
X_H equals: 65535
Z_L equals: 46260
Z_H equals: 65535
The temperature is: 77

Aquí está el código que estoy usando para obtener los valores que estoy usando la biblioteca I2C para la Pi de AQUÍ

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>

#include <wiringPi.h>
#include <wiringPiI2C.h>

#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23


int fd;
int x = 0;
int y = 0;
int z = 0;
int main (){



    fd = wiringPiI2CSetup(0x69); // I2C address of gyro
    wiringPiI2CWriteReg8(fd, CTRL_REG1, 0x1F); //Turn on all axes, disable power down
    wiringPiI2CWriteReg8(fd, CTRL_REG3, 0x08); //Enable control ready signal
    wiringPiI2CWriteReg8(fd, CTRL_REG4, 0x80); // Set scale (500 deg/sec)
    delay(100);                    // Wait to synchronize

void getGyroValues (){
    int MSB, LSB;

    LSB = wiringPiI2CReadReg16(fd, 0x28);
    MSB = wiringPiI2CReadReg16(fd, 0x29);
    x = ((MSB << 8) | LSB);

    MSB = wiringPiI2CReadReg16(fd, 0x2B);
    LSB = wiringPiI2CReadReg16(fd, 0x2A);
    y = ((MSB << 8) | LSB);

    MSB = wiringPiI2CReadReg16(fd, 0x2D);
    LSB = wiringPiI2CReadReg16(fd, 0x2C);
    z = ((MSB << 8) | LSB);
}

    for (int i=0;i<10;i++){
    getGyroValues();
    // In following Divinding by 114 reduces noise
    printf("Value of X is: %d\n", x / 114);
    printf("Value of Y is: %d\n", y / 114);
    printf("Value of Z is: %d\n", z / 114);
    int t = wiringPiI2CReadReg8(fd, 0x26);
    t = (t*1.8)+32;//convert Celcius to Fareinheit
    int a = wiringPiI2CReadReg16(fd,0x2B);
    int b = wiringPiI2CReadReg16(fd,0x2A);
    printf("Y_L equals: %d\n", a);
    printf("Y_H equals: %d\n", b);
    int c = wiringPiI2CReadReg16(fd,0x28);
    int d = wiringPiI2CReadReg16(fd,0x29);
    printf("X_L equals: %d\n", c);
    printf("X_H equals: %d\n", d);
    int e = wiringPiI2CReadReg16(fd,0x2C);
    int f = wiringPiI2CReadReg16(fd,0x2D);
    printf("Z_L equals: %d\n", e);
    printf("Z_H equals: %d\n", f); 

    printf("The temperature is: %d\n\n\n", t); 
    delay(500);
}
};
    
pregunta Yamaha32088

1 respuesta

1
  

Estoy usando un giroscopio de 3 ejes Parallax L3G4200D.

¿No te refieres a un giroscopio STMicroelectronics? Derecho.

  

Cuando se deja un giro en una superficie plana sin que nada interactúe con él en todas las salidas, ¿todo debería ser "0" correcto? Lo mío es saltar entre números.

No, se supone que deben generar valores, que varían de una parte a otra y su distribución es aproximada a una curva gaussiana (forma de histograma menos frecuente, más frecuente, menos frecuente). Debe tomar un promedio de estos valores (desplazamiento) y luego restar del valor que lee cada vez para usarlo (por lo que el valor más frecuente es más cercano a cero).

vale = value - offset;
  

Por ejemplo, "X_L = 0" y "X_H = 17219" con un "retraso (500)" entre la actualización, la X_H saltará mientras que X_L se mantiene prácticamente en 0 pero ocasionalmente saltará muy alto.

¿Es posible que estés invirtiendo el orden de los bytes? El byte bajo representa las lecturas más sensibles.

  

¿Crees que esto es un problema con el sensor o algo relacionado con el código? Si levanto el Gyro y lo agito alrededor, todos los números comienzan a actualizarse y funcionan correctamente.

No exactamente, supongo, ya que los valores que lee en estado inactivo son solo ruido intrínseco.

Wire.beginTransmission(0x69);
Wire.write(0xA8);
Wire.endTransmission();
Wire.requestFrom(0x69, 6);
while (Wire.available() < 6); //you need to wait for the date to be ready
low   = Wire.read();
high  = Wire.read();
X  = ((high << 8) | low);     //you need to read the 3 registers 1 by 1   

low   = Wire.read();
high  = Wire.read();
Y  = ((high << 8) | low);

low   = Wire.read(); 
high  = Wire.read();
Z  = ((high << 8) | low);


X -= <offset here>;           //you need to take average (offset) and subtract
y -= <offset here>;
Z -= <offset here>;

Solo entonces puedes comenzar a usar los valores. Todavía están en 2 complementos (MSB es bit de signo) y aún no están en grados por segundo (dps). Cada valor que tengas que multiplicar por una constante (sensibilidad). Esta constante varía con el rango de medición. Si es 500 dps, entonces la constante es 0.0175.

Xdps = X*0.0175;

Puede que estés interesado en calcular el ángulo, luego debes integrar la velocidad angular. Si el tiempo de bucle para la lectura es de 1 ms, multiplique Xdps por 0.001.

Xdps = X*0.0175*0.001; 

Debido a la falta de precisión de sincronización, el giro girará con el tiempo. Nunca volverá al ángulo cero si lo lleva físicamente a la posición cero, pero mantendrá un desplazamiento. Necesitas fusionar el acelerómetro para matar este desplazamiento.

Pero todavía (probablemente) necesitas filtrar los valores:

Xflt = Xflt*0.9 + Xdps*0.1;

Esto asegurará que solo una variación considerable en la magnitud de Xdps afectará el valor final Xflt (es decir, suprime los valores de ruido).

    
respondido por el tozheneznayu

Lea otras preguntas en las etiquetas