¿Cómo interpretar los valores enviados por un MPU-9255?

Bueno, estoy usando estas vacaciones en Brasil para mejorar mis habilidades en C. Aprendí a usar I2C y cómo comunicarme con el MPU9255 (con la ayuda de esta pregunta). El último problema al que me enfrento es que el sensor está devolviendo valores incorrectos. El valor devuelto es flotante de 0 a 65000, pero no es lineal.

Creo que se debe a que estoy confundiendo los tipos de datos o la combinación de bytes en mi código. ¿Puede alguien ayudarme a revisar mi código?

    uint8_t Test[] = "\n AccelX: \n";
    HAL_UART_Transmit(&huart1,Test,sizeof(Test),100);

    //SET X_HIGH REGISTER ADDRESS 
    i2cData = 0x3B;
    HAL_I2C_Master_Transmit(&hi2c1, adressMPU, &i2cData, 1, 100);

    //REQUEST 6 BYTES OF DATA (ACCEL X, Y AND Z)
    HAL_I2C_Master_Receive(&hi2c1, adressMPU, receive_buffer, 6, 100); 

    AccelX = (char)receive_buffer[0]<<8 | (char)receive_buffer[1];
    AccelY = (char)receive_buffer[2]<<8 | (char)receive_buffer[3];
    AccelZ = (char)receive_buffer[4]<<8 | (char)receive_buffer[5];

    //PRINTA NA SERIAL 1
    len = sprintf(buffer, " %i\r\n", AccelX); //sprintf will return the length of 'buffer'  
    HAL_UART_Transmit(&huart1, (uint8_t *)buffer, len, 1000);  

    HAL_Delay(500); 

Actualizar:

Solo noté una cosa: de 0 a 16768, las medidas del sensor son correctas, pero cuando invierto el eje, el sensor pasa de 65536 a ~ 49000 cuando debería ser de 0 a -16768. Seguramente es un error de conversión, pero todavía no puedo ver dónde está exactamente el error.

Entonces, ¿supongo que cuando compila el código, no hay errores ni advertencias? ¿Simplemente no está funcionando como lo necesita? ¿Has depurado tu código paso a paso? Aprender a programar no se trata de aprender el lenguaje, sino de aprender a resolver problemas y utilizar algoritmos. Intenta depurar tu código paso a paso. Afortunadamente, este no es un código largo, por lo que no tomará demasiado tiempo. Vea las interacciones de su código cuando lo realiza paso a paso.
¿Quiere decir usar depuración y agregar puntos de interrupción en el código?
Supongo que hay mucho más código, en alguna parte.
La depuración y los puntos de interrupción son una parte esencial del desarrollo de un código de trabajo, leería sobre eso para su IDE en particular.
El código es corto, pero acabo de notar una cosa: de 0 a 16768, las medidas del sensor son correctas, pero cuando invierto el eje, el sensor pasa de 65536 a ~49000 cuando debería ser de 0 a -16768. Seguramente es un error de conversión, pero todavía no puedo ver dónde está exactamente el error.
El problema está en la parte negativa. Esto debería ocurrir porque la función lee los bytes como caracteres sin firmar. Alguien sabe como puedo solucionar esto?
¿ Cuál es el tipo de AccelX?

Respuestas (1)

El MPU-9255 le proporciona un entero con signo de 16 bits. Su código lo interpreta como sin firmar.

Un número de 16 bits sin signo puede representar valores de 0 a 65535. Un número de 16 bits con signo representa -32768 a +32767.

Aquí hay un ejemplo de 8 bits de Wikipedia :

FirmadoSin firmar

Para hacer la conversión, primero mire el bit alto. Si esto es 0 , entonces no es necesaria ninguna conversión. Si esto es 1 , entonces s i gramo norte mi d = ( tu norte s i gramo norte mi d 2 norte ) , dónde norte es el número de bits. Dieciséis, en su caso.

Aquí hay un método simple para 16 bits:

uint16_t unsignedAccelX;
int16_t signedAccelX;

if (unsignedAccelX < 32768)
{
    signedAccelX = unsignedAccelX;
}
else
{
    signedAccelX = unsignedAccelX - 65536;
}

Hay muchas formas más elegantes y/o eficientes de hacer esto. Aquí hay algo de discusión .

¡Buena suerte!

He resuelto este problema exactamente de esta manera jajaja Hoy buscaré una forma más eficiente