Hello,
Following help from Ralph Jacobi regarding printing of floating point number over UART in this post:
I wrote the following code:
//////////////////////////////////////////////////////////////////////////////////////////////////// #include <stdbool.h> #include <stdint.h> #include "driverlib/debug.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "driverlib/pwm.h" #include "driverlib/rom.h" #include "driverlib/sysctl.h" #include "inc/hw_gpio.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include <math.h> #include <stddef.h> // For using the NULL pointer #define PWM_FREQUENCY 55 //////////////////////////////////////////////////////////////////////////////////////////////////// // My I2C defines & includes #include "driverlib/i2c.h" #include "driverlib/interrupt.h" #include "inc/hw_i2c.h" #include "inc/hw_ints.h" #include "sensorlib/i2cm_drv.h" #include "sensorlib/mpu6050.h" #include "sensorlib/hw_mpu6050.h" #define DEBUG //////////////////////////////////////////////////////////////////////////////////////////////////// // My UART defines & includes #include "driverlib/uart.h" #include "utils/uartstdio.h" //////////////////////////////////////////////////////////////////////////////////////////////////// #include "definitions_mpu6050.h" tI2CMInstance g_sI2CInst; // I2C master driver structure. "tI2CMInstance" is defined in the i2cm_drv.h file. tMPU6050 g_sMPU6050Inst; // MPU6050 sensor driver structure. "tMPU6050" is defined in the mpu6050.h file. volatile unsigned long g_vui8DataFlag; // Data ready flag volatile unsigned long g_vui8ErrorFlag; // Error flag void ISL29023I2CIntHandler(void) { I2CMIntHandler(&g_sI2CInst); } //////////////////////////////////////////////////////////////////////////////////////////////////// int main(void) { float fAccel[3], fGyro[3] = {0.0} ; uint8_t register_mpu6050_o_pwr_mgmt_1 ; // Used for debug uint8_t register_mpu6050_o_who_am_i ; // Used for debug uint8_t index = 0 ; uint32_t counter = 0 ; int32_t i32IntegerPart = 0 ; int32_t i32FractionPart = 0 ; // Configure the clock SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); //////////////////////////////////////////////////////////////////////////////////////////////////// // My I2C initialization code // Enable GPIO peripheral that contains I2C 2 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // Enable I2C module 2 SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2); // Configure the pin muxing for I2C2 functions on port E4 and E5. GPIOPinConfigure(GPIO_PE4_I2C2SCL); GPIOPinConfigure(GPIO_PE5_I2C2SDA); // Select the I2C function for these pins. GPIOPinTypeI2CSCL(GPIO_PORTE_BASE, GPIO_PIN_4); GPIOPinTypeI2C(GPIO_PORTE_BASE, GPIO_PIN_5); IntMasterEnable(); // USER_I2CMInit(&g_sI2CInst, I2C2_BASE, INT_I2C2, 0xFF, 0xFF, SysCtlClockGet()); // Set SCL to 100KHz instead of the original 400KHz. I2CMInit(&g_sI2CInst, I2C2_BASE, INT_I2C2, 0xFF, 0xFF, SysCtlClockGet()); SysCtlDelay(SysCtlClockGet() / 3); // USER_MPU6050Callback will modify the g_bMPU6050Done variable to true if the functions that use it succeed. // Initialize the MPU6050 g_bMPU6050Done = false; MPU6050Init(&g_sMPU6050Inst, &g_sI2CInst, MPU6050_I2C_ADDRESS, USER_MPU6050Callback, 0); while(!g_bMPU6050Done) { } g_bMPU6050Done = false; // SysCtlDelay(SysCtlClockGet() / 3); g_bMPU6050Done = false; MPU6050Read(&g_sMPU6050Inst, MPU6050_O_WHO_AM_I , ®ister_mpu6050_o_who_am_i, 1 ,USER_MPU6050Callback , 0); while(!g_bMPU6050Done) { } g_bMPU6050Done = false; SysCtlDelay(SysCtlClockGet() / 3); g_bMPU6050Done = false; MPU6050Read(&g_sMPU6050Inst, MPU6050_O_PWR_MGMT_1 , ®ister_mpu6050_o_pwr_mgmt_1, 1 ,USER_MPU6050Callback , 0); // Someone forgot to take the device out of sleep. while(!g_bMPU6050Done) { } g_bMPU6050Done = false; SysCtlDelay(SysCtlClockGet() / 3); g_bMPU6050Done = false; // Writing 0x00 Wakes up the device from sleep. // Writing 0x01 wakes up the device from sleep and also makes the main clock PLL with X axis gyroscope reference. // MPU6050Write(&g_sMPU6050Inst, MPU6050_O_PWR_MGMT_1 , 0x00 , 1 , USER_MPU6050Callback , 0); MPU6050Write(&g_sMPU6050Inst, MPU6050_O_PWR_MGMT_1 , 0x01 , 1 , USER_MPU6050Callback , 0); while(!g_bMPU6050Done) { } g_bMPU6050Done = false; SysCtlDelay(SysCtlClockGet() / 3); g_bMPU6050Done = false; MPU6050Read(&g_sMPU6050Inst, MPU6050_O_PWR_MGMT_1 , ®ister_mpu6050_o_pwr_mgmt_1 , 1 ,USER_MPU6050Callback , 0); while(!g_bMPU6050Done) { } g_bMPU6050Done = false; SysCtlDelay(SysCtlClockGet() / 3); g_bMPU6050Done = false; // Configure the MPU6050 for +/- 4 g accelerometer range. // MPU6050ReadModifyWrite(&g_sMPU6050Inst, MPU6050_O_ACCEL_CONFIG, ~MPU6050_ACCEL_CONFIG_AFS_SEL_M, MPU6050_ACCEL_CONFIG_AFS_SEL_4G, USER_MPU6050Callback, 0); MPU6050ReadModifyWrite(&g_sMPU6050Inst, MPU6050_O_ACCEL_CONFIG, ~MPU6050_ACCEL_CONFIG_AFS_SEL_M, MPU6050_ACCEL_CONFIG_AFS_SEL_2G, USER_MPU6050Callback, 0); while(!g_bMPU6050Done) { } g_bMPU6050Done = false; SysCtlDelay(SysCtlClockGet() / 3); //////////////////////////////////////////////////////////////////////////////////////////////////// // My UART initialization code SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); UARTStdioConfig(0, 115200, 16000000); UARTprintf("The UART Works\n"); //////////////////////////////////////////////////////////////////////////////////////////////////// while(1) { g_bMPU6050Done = false; while ( counter < 1000000 ) { counter ++ ; } counter = 0 ; // Get the new accelerometer and gyroscope readings. // MPU6050DataAccelGetFloat(&g_sMPU6050Inst, &fAccel[0], &fAccel[1], &fAccel[2]); // MPU6050DataGyroGetFloat(&g_sMPU6050Inst, &fGyro[0], &fGyro[1], &fGyro[2]); sample_accumulate_average ( &g_sMPU6050Inst , 256 , fAccel , fGyro ) ; float angle = atan2 (fAccel[0],fAccel[2]) * ( 180.0 / PI ) ; i32IntegerPart = (int32_t)angle; i32FractionPart = (int32_t)(angle * 1000.0f); i32FractionPart = i32FractionPart - (i32IntegerPart * 1000); UARTprintf("angle: %3d.%03d\t\n", i32IntegerPart, i32FractionPart); // Convert floating point to an integer and send it via UART for ( index = 0 ; index <= 2 ; index ++ ) { i32IntegerPart = (int32_t)fAccel[index]; i32FractionPart = (int32_t)(fAccel[index] * 1000.0f); i32FractionPart = i32FractionPart - (i32IntegerPart * 1000); if(i32FractionPart < 0) { i32FractionPart *= -1; } if ( index == 0 ) { UARTprintf("Accelerometer X: %3d.%03d\t\n", i32IntegerPart, i32FractionPart); } if ( index == 1 ) { UARTprintf("Accelerometer Y: %3d.%03d\t\n", i32IntegerPart, i32FractionPart); } if ( index == 2 ) { UARTprintf("Accelerometer Z: %3d.%03d\t\n", i32IntegerPart, i32FractionPart); } } for ( index = 0 ; index <= 2 ; index ++ ) { i32IntegerPart = (int32_t)fGyro[index]; i32FractionPart = (int32_t)(fGyro[index] * 1000.0f); i32FractionPart = i32FractionPart - (i32IntegerPart * 1000); if(i32FractionPart < 0) { i32FractionPart *= -1; } if ( index == 0 ) { UARTprintf("Gyro X: %3d.%03d\t\n", i32IntegerPart, i32FractionPart); } if ( index == 1 ) { UARTprintf("Gyro Y: %3d.%03d\t\n", i32IntegerPart, i32FractionPart); } if ( index == 2 ) { UARTprintf("Gyro Z: %3d.%03d\t\n\n\n\n\n", i32IntegerPart, i32FractionPart); } } /* We're interested in: Accelerometer readings in the X axis ( perpendicular to the table ). Gyro readings in the Y axis ( the ball bearing axis ). */ fAccel[0] = 0.0 ; fAccel[1] = 0.0 ; fAccel[2] = 0.0 ; fGyro[0] = 0.0 ; fGyro[1] = 0.0 ; fGyro[2] = 0.0 ; } }
Everything works fine - except of on thing,
When the values of "angle" assume a negative value - the print of the (-) sign doesn't work well (a screenshot is attached)
Please help me fix the code.