¿El acelerómetro Bosch BMI055 devuelve valores desbordados de 8 bits?

Trato de usar un aclerómetro BMI055 y la salida me está volviendo loco.

Lo configuré en sensibilidad 2G a 1000 Hz, eso significa que tengo una salida entre 0 y 4096 (12 bits).
Se dice que la salida es dos complementada, por lo que espero que 2048 sea 0G

El sensor se configura para que sea lo más plano posible usando medidores.

Ahora le pregunto en un bucle por sus datos FIFO (fifo de derivación de 1 cuadro) que me devuelve 6 bytes.
Según ficha técnica: LSB X MSB X LSB Y MSB Y LSB Z MSB Z

LSB X debe desplazarse a la derecha 4 veces y ORd con MSB X, que se desplaza a la izquierda 4 veces.
Entonces recibo un número de 12 bits.

¡El simple análisis de los valores X muestra que MSB X está saltando entre 0 y 255!

Código:

temp[0]=(result[1]<<4) | ((result[0])>>4);

Esto muestra LSB MSB 12BIT sin firmar

Data X:  1       0       0 
Data X:  85      255     4085 
Data X:  201     255     4092 
Data X:  201     255     4092 
Data X:  221     255     4093 
Data X:  157     0       9 
Data X:  49      0       3 
Data X:  181     255     4091 
Data X:  229     255     4094 
Data X:  17      0       1 
Data X:  161     255     4090 
Data X:  117     255     4087 
Data X:  221     255     4093 
Data X:  5       0       0 
Data X:  209     255     4093 

Debería devolverme 2048 ya que X está en 0G.
4096 sería fuerza 2G.
0 sería una fuerza -2G.

Al poner X en -1G y +1G los valores parecen correctos (1000 y 3000).
Solo el centro 0G está en 0/4000 dependiendo de vibraciones menores en lugar del esperado 2046-2049

Son las 4 de la mañana, supongo que superviso algo muy crítico. iluminación por favor

No miré la hoja de datos, pero si esos valores están firmados, todas las lecturas están razonablemente cerca de cero y su lectura de 3000 sería de alrededor de -1000.
Hmm, ¿entonces parece que los números de 8 bits están realmente firmados cada uno? ¿A pesar de que son solo un subconjunto de un número mayor (12 bits)? Hubiera esperado que el número de 12 bits en estado firmado se almacenara en 8 bits + 4 bits. Solo trato de darle sentido a las matemáticas que antes habrían sido tan simples.
No estoy seguro, pero si está firmado, podría usar su número sin firmar y algo como if (x >= 2048) x = x - 4096.
hmm tal vez, todavía no estoy seguro de cómo tratar los registros que recibo. La hoja de datos dice que MSB es dos complementos. LSB no es dos complementados (¿supongo?) ¿Significa que los valores de ejemplo como lsb 10 msb 255 = -10? 10 1 sería entonces 26 ?
Correcto, el LSB no debe interpretarse por sí mismo como un valor de complemento a dos. Su primer ejemplo en realidad tiene un valor de -6 (su segundo es correcto); Si no entiende por qué, le sugiero que repase cómo funciona el complemento a dos.
Upvote para todos ustedes, gracias por las sugerencias. Estaba demasiado cansado ayer para 'ver a través'.

Respuestas (2)

Creo que te estás liando por la necesidad de que el signo del número se extienda hacia la izquierda. Mi lectura de la hoja de datos es que los registros MSB y LSB le brindan un conjunto de 12 bits que, como un número de 12 bits, debe considerarse en formato de complemento a dos.

Por lo tanto, primero debe combinar los valores, luego, si es necesario, realizar cualquier corrección para asegurarse de que sea un número de complemento a dos legítimo dado el tamaño del tipo de datos en el que lo ha ingresado. Luego escálelo si es necesario.

Sugeriría: primero elija un tamaño de datos de destino que sea lo suficientemente grande como para contener el resultado. Digamos que está usando C en una MCU, y puede elegir una abreviatura firmada, y es de 16 bits. (Ninguno de estos es un hecho, por cierto).

Supongamos también que MSB y LSB son números de 8 bits. Ahora:

resultado corto firmado = (MSB << 8) | (LSB y 0xF0)

Esto debería darte un número que ya está en formato de complemento a dos, como se espera que sea el signo corto. Esto le dará un rango de números que es 16 veces el número bruto de 12 bits, pero que oscila correctamente alrededor de cero.

Luego, es posible que desee escalarlo dividiendo por 16. Puede pensar en realizar esa división usando scaledresult = (resultado >> 4), pero si es así, deberá verificar si el desplazamiento a la derecha realiza la extensión de signo. Es decir, establece scaledresult[15..12] en 1 si result[15] era 1.

De hecho, ya lo había hecho, pero estaba obsesionado con mantener mi número de 12 bits y un código lo más eficiente posible. También pensé que LSB no está en realidad en dos complementos. Tal vez fue un poco tarde para mí ayer :) Ahora lo implementé exactamente como usted sugirió y probablemente incluso mantendré los 16 bits ya que mi giroscopio también da resultados de 16 bits.
Es uno de esos casos en los que el formato de los datos que le entregan los registros es el formato que necesita menos esfuerzo para volverse útil en su programa... siempre y cuando sepa cuál era la intención, en este caso el tipo de datos de destino. .

Hay API listas para usar para la parte del acelerómetro en el BMI055. Por favor refiérase a:

Controlador de sensor Bosch Sensortec BMA2x2