MEMS Giroscopio BMI055 - picos altos aleatorios en los datos

1

Estoy usando el BMI055 en mi AVR a través de I2C.
Hoja de datos: enlace

Lo puse en salida filtrada a un ODR de 1000Hz y lo sondeamos cada 1005 us.
Lo puse a 1000deg / s de sensibilidad, a 16 bits de salida. Eso da 32.8 LSB / grado
Estoy leyendo los valores del FIFO en modo bypass.

Ahora, para probar, tengo una función que hace lo siguiente (pseudo):

dt = microseconds passed since last call (around 1000)
scale = 1/32.8/1000000;
deltaANGLE[axis] = dt * scale;
static sum[axis] += deltaANGLE[axis];
Every 1000 calls:
{
   print the sums[] to serial;
   sum[axis]=0;
}

Habría esperado un poco de ruido y deriva durante 1 segundo (1000 muestras) pero obtendría un valor de compensación de -3 a -11 en los 3 ejes cuando lo tengo en la tabla fija.
También los valores cambian mucho, incluso una corrección promedio no ayudaría mucho

Time dif 995 us
Angles: -9.944047 -9.904691 -10.001564
Time dif 1003 us
Angles: -9.846170 -9.824638 -9.923825
Time dif 998 us
Angles: -5.871545 -5.805600 -5.935478
Time dif 1005 us
Angles: -8.871223 -9.628742 -8.884630
Time dif 1009 us
Angles: -8.874594 -8.875291 -8.956609
Time dif 1007 us
Angles: -5.902205 -5.916657 -5.970954

También me desconcertó que los tres ejes muestren siempre la misma desviación extraña.
Al mover el tablero dentro de la segunda integración, muestra "sobre" el cambio correcto (= -15 grados desde el valor esperado)

Creo que hago algo mal pero no puedo encontrar el problema.

Addon1: Acabo de encontrar que aumentar el tiempo de mi rutina de sondeo reduce significativamente el error. Tengo la ODR configurada a 1000Hz, si me conecto a 500Hz obtengo un nivel de ruido bajo y un resultado bastante preciso. ¿Aunque debería significar que el sensor está saturado en un 50% del tiempo y espera mi encuesta? ¿Puede este ruido ser el resultado de un problema entre mi sondeo y la configuración de ancho de banda / ODR de los sensores?

Addon2: Otras varias horas desperdiciadas. Experimenté con varias configuraciones relacionadas con la tasa de sondeo y el sensor ODR / ancho de banda.
Cuando el sondeo es más rápido que la ODR, obtengo valores completamente locos de la FIFO, la hoja de datos dice que debería dar valores CERO ..
La nueva interrupción de datos (en el octavo byte de FIFO) se establece de manera permanente en 1 wth. Las interrupciones en 0, incluso si sondeo 3 veces más rápido que la frecuencia de muestreo.
Cuando el sondeo es más lento que la frecuencia de muestreo, obtengo mejores valores, pero el ángulo Y salta esporádicamente en -3 grados cada pocos segundos (todavía se está acumulando, ahora 2 segundos). El eje Z es bastante estable, después de unos pocos minutos de acumulación total, muestra un desplazamiento de 7 grados. El eje X muestra alrededor de 36. El eje Y -133 grados.

No puedo pensar en una manera de compensar estos picos repentinos, no es un desplazamiento general. Mi conclusión actual es que el chip en sí es malo. (?)

Actualización con código real: Inicialización:

    data[0]=0x0F;data[1]=0b000; //001 = 1000deg/sec,000 =2000
    error += twiSend( ACC_BM055_ADDR_GYRO, data, 2 );
    _delay_us(5);

    data[0]=0x10;data[1]=0b0011; // 0011 = 400hz odr 2khz = 0001. decimation factor 2, odr 1000hz (1k=0b0010)
    error += twiSend( ACC_BM055_ADDR_GYRO, data, 2 );
    _delay_us(5);

    data[0]=0x13;data[1]=0b0; // filter 1, shadow 1
    error += twiSend( ACC_BM055_ADDR_GYRO, data, 2 );
    _delay_us(5);

    data[0]=0x15;data[1]=0b0; // all interrupts off
    error += twiSend( ACC_BM055_ADDR_GYRO, data, 2 );
    _delay_us(5);

    data[0]=0x15;data[1]=0b0; // all interrupts off
    error += twiSend( ACC_BM055_ADDR_GYRO, data, 2 );
    _delay_us(5);

    data[0]=0x3E;data[1]=0b00; // FIFO bypass und XYZ modus
    error += twiSend( ACC_BM055_ADDR_GYRO, data, 2 );
    _delay_us(5);


    data[0]=0x31;data[1]=0b11101111; // try to run offset comp
    error += twiSend( ACC_BM055_ADDR_GYRO, data, 2 );
    _delay_ms(1300);    



    data[0]=0x15;data[1]=0b10000010; // auto offset  .. doesnt help
    error += twiSend( ACC_BM055_ADDR_GYRO, data, 2 );
    _delay_us(5);

    data[0]=0x00;
    error += twiSend( ACC_BM055_ADDR_GYRO, data, 1 );   
    error += twiReceive( ACC_BM055_ADDR_GYRO, result, 1 );
    if (result[0] != 0b00001111) error+=32;

    if (error == 100) error=0;
    return error;
}

Estoy sondeando el búfer FIFO para 6 bytes (lectura de ráfaga de la dirección 0x3F) usando un temporizador que golpea cada n microsegundos.
Tan pronto como he recibido los 6 bytes esto sucede:

uint8_t axis;
float scale, deltaGyroAngle[3];
static uint16_t time_last;
uint16_t time_now = get_micros(); 

scale = (time_now - time_last) * GYRO_TO_RAD_FACTOR; // gyro * dt


for (axis = 0; axis < 3; axis++) 
{
    deltaGyroAngle[axis] = attitude.gyro_raw[axis]  * scale; 
}


static float sum[3];
static uint16_t counter;
sum[0] += deltaGyroAngle[0];
sum[1] += deltaGyroAngle[1];
sum[2] += deltaGyroAngle[2];
if (counter++==1000) // at current 400hz it hits once per 2.5 sec, at 1000hz it hits once per second
{
    WRITE("\n\nTime dif %u us\n",time_now-time_last);
    WRITE("\nWinkelsnapshot: %f %f %f\n",(sum[0]),(sum[1]),(sum[2]));uart_wait_rx0_empty();
// This shows that Z is stable
// X is slightly unstable
// Y has random -3.5 degree per second spikes (in 1000hz mode -7)
    //sum[0]=0;
    //sum[1]=0;
    //sum[2]=0;
    counter=0;
}
time_last = time_now;

Otra actualización, esta vez más cerca de la fuente:
Escribí una rutina promedio para encontrar un sesgo, muestro el chip cada 2800 nosotros.
La ODR está configurada a 400 Hz, por lo que 2500 dólares sería la tasa mínima. Los resultados generales son muy buenos, muestra una compensación promedio de cero en 1000 muestras.
Pero cada 1-2 segundos recibo un gran aumento en uno de los valores, cerca de la lectura máxima.
El sensor se comporta como si recibiera una patada repentina dentro de dos milisegundos, pero simplemente está sentado en la mesa. Aquí los valores en formato de 16 bits firmado y sin firmar:

Sampled 00001 -0001 00005        00001 65535 00005
Sampled 00001 00000 00002        00001 00000 00002
Sampled 00001 00001 00000        00001 00001 00000
Sampled 00001 00000 00001        00001 00000 00001
Sampled -0001 -0001 00001        65535 65535 00001
Sampled 00001 00000 00000        00001 00000 00000
Sampled 00003 00006 -0001        00003 00006 65535
Sampled 00001 00007 00000        00001 00007 00000
Sampled 00000 00004 00002        00000 00004 00002
Sampled 00001 00000 00002        00001 00000 00002
Sampled 00003 -0001 00001        00003 65535 00001
Sampled 00003 00001 00001        00003 00001 00001
Sampled 00002 00000 00001        00002 00000 00001
Sampled 00002 -18497 -0001       00002 47039 65535   <-----
Sampled -0002 00002 -0002        65534 00002 65534
Sampled 00000 -0001 00000        00000 65535 00000
Sampled 00000 00001 00000        00000 00001 00000
Sampled 00000 00002 -0001        00000 00002 65535
Sampled 00001 00001 -0003        00001 00001 65533
Sampled 00003 -0001 -0002        00003 65535 65534
Sampled 00004 -0001 00001        00004 65535 00001
Sampled 00003 -0001 00002        00003 65535 00002
Sampled 00002 -0004 00000        00002 65532 00000
Sampled 00003 -0003 00000        00003 65533 00000
Sampled 00002 00000 00000        00002 00000 00000
Sampled 00001 00001 00001        00001 00001 00001
Sampled 00002 00000 00002        00002 00000 00002

Puedes ver que los valores son realmente bajos con la excepción de un pico de -18497.
Si reduzco la demora entre muestras, estos picos se vuelven más frecuentes.

Realmente empiezo a creer que hago todo bien y Bosch tiene un problema con su chip BMI055 o este solo chip es una locura.

Una solución potencial en la que pensé sería dejar que todo el algoritmo del sensor se demorara un cuadro (alrededor de 2500us) e ignorar por completo un pico repentino de 1 ms. Pero agregaría un cierto retraso de respuesta a mi proyecto. Un filtro de paso bajo digital también podría hacer un buen trabajo con menos retraso, pero un aumento de 0 a 16000 (y también he visto 32k) también tendrá un impacto en toda la lectura.

Deseo que un experto me ilumine

    
pregunta John

2 respuestas

1

Editar: He encontrado la causa de los picos. El chip BMI055 tiene fallas internas, estoy seguro de ello ahora. Si lee el FIFO en modo Bypass (lo que significa que solo se conserva un cuadro) debe esperar errores de datos. Si lo lee más rápido que la frecuencia de muestreo, recibirá un 10% de 0x8000 (el número más pequeño posible) en la mezcla. No es cero, no es el último valor .. un valor MÁXIMO!

Si lee los datos un poco más lento que la frecuencia de muestreo, recibirá datos válidos con 1-8 picos por segundo.

Esto sucede si utiliza el registro FIFO en modo de ráfaga de 6 u 8 bytes.
Ahora tengo curiosidad, leí el registro 0x02 en una ráfaga de 6 bytes y esto da los mismos datos (x, y, z) y no cambié absolutamente nada más.
Las espigas son fiables y se han ido.

texto anterior:

Parece que el giroscopio en sí tiene fallas y no es solo esa.

Primero esperé un error en la comunicación I2C, reduje la velocidad e intercambié el circuito de cambio de voltaje sin ningún cambio en los resultados.

Ahora, cuando identifiqué el problema proveniente de picos altos aleatorios, también pude encontrar muchas otras personas con problemas o informes similares.
El hecho sorprendente es que rara vez hay respuestas.

Mi primera prueba fue un filtro de promedio exponencial móvil, pero como esperaba, arruina muchas lecturas posteriores y solo amortigua los picos.

La mejor solución en la que puedo pensar es usar dos giroscopios, eso es lo que haré a largo plazo. Es probable que ambos tengan picos y al comparar ambos marcos entre sí, debería ser posible obtener un resultado muy bueno y no picos.

La solución simple es filtrar los picos según un valor de cambio máximo codificado.
Primero consideré capturar datos al doble de la velocidad actual y luego quedarme siempre detrás de un cuadro.
De esa manera sabría el "futuro" y el pasado, si los datos "actuales" están muy lejos del futuro y el pasado es un pico (o alguien golpeó un martillo en el sensor).

Pero para los giroscopios con alta resolución / s y uso práctico fuera de 2000deg / s, el filtrado puede ser más fácil.
Jugué y estaba sacudiendo fuertemente el giro, los valores brutos rara vez excedían los +10k y, sin importar lo que hiciera, no tenían cambios tan repentinos, ni siquiera durante una caída en la mesa.
Utilizo esto ahora:

if (abs(old-current)>0x3000) use_value();

Entonces, si el resultado está desactivado por más de 12,000 valores brutos en comparación con el valor anterior, el valor anterior permanecerá en la variable. De lo contrario, la variable se actualiza con el nuevo valor.

Ahora tengo una deriva bastante baja que incluso funciona durante muchos minutos.

Notas al margen sobre el giroscopio usado:
a) El giroscopio BMI055 está especificado para devolver CERO si lo muestrea demasiado rápido, en realidad devuelve valores aleatorios. b) El giroscopio BMI055 bloquea el bus I2C si le envía un soft_reset (el ACC de onchip no lo hace) c) Los picos repentinos no se describen en las hojas de datos de los giroscopios y aún muchas personas los notan. Eso es bastante extraño.

Apreciaría una mejor respuesta, tal vez me equivoque.
Sin embargo, la filtración de picos hizo que mi programa funcionara bastante confiable en comparación con los resultados inutilizables anteriores.

    
respondido por el John
1

Información adicional para BMI055 Gyro and Acceleration sensor:

También tengo picos aleatorios en los datos convertidos y encontré la razón .
Preparar:

  • ACC: ancho de banda 250Hz = 500 Hz ODR, modo FIFO STREAM e interrupción de marca de agua habilitada, marca de agua = 60 = 10 marcos de datos, medición para todos los ejes
  • GYR: 400 Hz ODR, modo FIFO STREAM e interrupción de marca de agua habilitada, marca de agua = 60 = 10 marcos de datos, medición para todos los ejes
  • el microcontrolador lee los datos del sensor (exactamente 10 cuadros) a través de SPI cuando se activan las interrupciones y las convierte en datos enteros de 16 bits

Problema:
aleatoriamente, a veces los paquetes de datos leídos se rellenan con ceros que generan picos elevados en el gráfico de datos de medición

Razón:

  • en la hoja de datos de BMI055: Si se lee el FIFO más allá del nivel de llenado FIFO, se leerán los ceros (0). - > esto no debería suceder con la configuración nombrada porque la interrupción de marca de agua FIFO solo se dispara cuando hay suficientes datos en el FIFO
  • Pero !!! la interrupción de la marca de agua FIFO se activa de nuevo cuando se lee el primer fotograma y cuando en este momento (o algunos segundos después) el sensor adquiere el siguiente paquete de datos, lo que significa que almacena un nuevo marco en el FIFO - > luego, la condición de la marca de agua se completa durante la lectura de SPI y se activa la interrupción - > así que después de leer los 10 cuadros, el microcontrolador vuelve a leer inmediatamente 10 cuadros pero no hay suficientes datos adquiridos - > se leen los ceros

Solución:
  • cuando se activa la interrupción de la marca de agua - > deshabilite la interrupción en el microcontrolador antes de leer el FIFO sobre SPI
  • vuelva a habilitar la interrupción en el microcontrolador después de que termine la lectura FIFO - > los datos ahora están bien
respondido por el scrat

Lea otras preguntas en las etiquetas