He estado jugando recientemente con una fuga GY521 con el chip MPU6050, aunque me encontré con un pequeño problema que no puedo resolver.
Sé que cuando giré la placa, giré ~ 90 grados sobre el eje Y, y usando los números de sensibilidad de la hoja de datos (131) e integrando, logré obtener algo que parece creíble desde el giroscopio, pero tengo problemas con el acelerómetro
De varias fuentes, siendo esta una de ellas , logré obtener las tres ecuaciones que se ven aquí, sin embargo, cuando las aplico a los datos sin procesar o escalados (ya que son escaladores, no debería hacer una diferencia ?) Obtengo un conjunto de datos que varía de 0 a 90, pero solo en los ejes X y Z, mientras que en el Y no pasa nada.
Actualizado para incluir código:
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"
MPU6050 accelgyro;
int16_t ax, ay, az, gx, gy, gz;
double timeStep, time, timePrev;
double arx, ary, arz, grx, gry, grz, gsx, gsy, gsz, rx, ry, rz;
int i;
double gyroScale = 131;
void setup() {
Wire.begin();
Serial.begin(9600);
accelgyro.initialize();
time = millis();
i = 1;
}
void loop() {
// set up time for integration
timePrev = time;
time = millis();
timeStep = (time - timePrev) / 1000; // time-step in s
// collect readings
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// apply gyro scale from datasheet
gsx = gx/gyroScale; gsy = gy/gyroScale; gsz = gz/gyroScale;
// calculate accelerometer angles
arx = (180/3.141592) * atan(ax / sqrt(square(ay) + square(az)));
ary = (180/3.141592) * atan(ay / sqrt(square(ax) + square(az)));
arz = (180/3.141592) * atan(sqrt(square(ay) + square(ax)) / az);
// set initial values equal to accel values
if (i == 1) {
grx = arx;
gry = ary;
grz = arz;
}
// integrate to find the gyro angle
else{
grx = grx + (timeStep * gsx);
gry = gry + (timeStep * gsy);
grz = grz + (timeStep * gsz);
}
// apply filter
rx = (0.1 * arx) + (0.9 * grx);
ry = (0.1 * ary) + (0.9 * gry);
rz = (0.1 * arz) + (0.9 * grz);
// print result
Serial.print(i); Serial.print("\t");
Serial.print(timePrev); Serial.print("\t");
Serial.print(time); Serial.print("\t");
Serial.print(timeStep, 5); Serial.print("\t\t");
Serial.print(ax); Serial.print("\t");
Serial.print(ay); Serial.print("\t");
Serial.print(az); Serial.print("\t\t");
Serial.print(gx); Serial.print("\t");
Serial.print(gy); Serial.print("\t");
Serial.print(gz); Serial.print("\t\t");
Serial.print(arx); Serial.print("\t");
Serial.print(ary); Serial.print("\t");
Serial.print(arz); Serial.print("\t\t");
Serial.print(grx); Serial.print("\t");
Serial.print(gry); Serial.print("\t");
Serial.print(grz); Serial.print("\t\t");
Serial.print(rx); Serial.print("\t");
Serial.print(ry); Serial.print("\t");
Serial.println(rz);
i = i + 1;
delay(50);
}
Resultados:
Me parece un poco extraño, ya que esperaba solo un cambio rotacional en Y. ¿Alguna sugerencia?
Prueba esto:
arx = (180/3.141592) * atan(ax / sqrt(square(ay, 2) + square(az, 2)));
ary = (180/3.141592) * atan(ay / sqrt(square(ax, 2) + square(az, 2)));
arz = (180/3.141592) * atan(sqrt(square(ay) + square(ax)) / az);
Ahora nos vemos arx
y ary
.
también cambiar
rx = (0.1 * arx) + (0.9 * grx);
ry = (0.1 * ary) + (0.9 * gry);
rz = (0.1 * arz) + (0.9 * grz);
a:
rx = (0.96 * arx) + (0.04 * grx);
ry = (0.96 * ary) + (0.04 * gry);
rz = (0.96 * arz) + (0.04 * grz);
darudude
Laurengineer
darudude
Laurengineer