This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EK-TM4C129EXL: EK-TM4C129EXL – Unable to Display IMU Sensor Values on 0.96 OLED Display

Part Number: EK-TM4C129EXL

Hello TI Team,

I am currently working on the EK-TM4C129EXL LaunchPad board.

In my project, I have interfaced:

  • An IMU sensor
  • A 0.96-inch OLED display

Current Status:

  • IMU sensor communication is working correctly.
  • I am able to read sensor values successfully through UART/terminal debugging.
  • OLED display initialization is also working correctly.
  • When I send normal characters or static strings to the OLED, they are displayed properly.

Issue:
When I try to display the IMU sensor values on the OLED display, the values are showing as:
0000

instead of the actual sensor readings.

Observations:

  • Static text display works fine on the OLED.
  • Sensor data is being received correctly in the code.
  • The issue appears only while converting or passing sensor values to the OLED display function.

I suspect the problem may be related to:

  • Integer/float to string conversion
  • sprintf()/snprintf() formatting
  • Data type mismatch
  • OLED display buffer handling

Could you please help me identify what could be causing the issue or suggest the correct way to display sensor values on the OLED?

Hardware Used:

  • EK-TM4C129EXL LaunchPad
  • IMU Sensor (mention exact sensor part number)
  • 0.96" OLED Display (SSD1306/I2C)

Software/IDE:

  • Code Composer Studio
  • TivaWare

Thank you.output_0.96 oled.txt pic.jpg

  • Hello,

    Based on what you've described it sounds like all of the components: Display and IMU are working as expected leading me to believe it may be an issue of how the data is formatted from the IMU sensor to the display.

    For the previous displayed information how was it formatted to be shown on the display? how is the IMU data stored? My guess is if the IMU data is in the format of a floating point or uint32_t and the displayed information is in an integer format you may need to cast it to be formatted as expected.

  • We need to know the format you get from the imu and the format you want to display.

    What I would do is print the string you want to display to a buffer and then display it to both serial and the OLED.

    Usually this kind of thing is due to not creating the proper buffers for the strings.

    Can you share the code snippet that does the formatting and displaying?

  • Thank you for the response.

    Currently, I am receiving the IMU sensor values correctly through UART debugging. The IMU data is coming in numeric format, and I am trying to display the same values on the 0.96" OLED display.

    The OLED display is working correctly for static strings and characters. However, when I try to display the sensor values, the OLED shows only:
    0000

    As you suggested, I checked by printing the formatted string through serial UART, and the values appear correctly there. The issue seems to occur while formatting or passing the sensor data to the OLED display function.

    I suspect there may be an issue related to:

    • Buffer allocation

    • sprintf()/snprintf() formatting

    • Integer/float conversion

    • OLED display string handling

    I am attaching the OLED display formatting and display code snippet below for reference. Please review and suggest any corrections required.

    /******************************************************************************
     * TM4C129ENCPDT + LSM6DSV16X + SSD1306 OLED
     * FULLY CORRECTED - Proper sensor initialization for LSM6DSV16X   kumar
     ******************************************************************************/
    
    #include <stdint.h>
    #include <stdbool.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/i2c.h"
    #include "driverlib/uart.h"
    
    /* =========================================================
       OLED
    ========================================================= */
    #define OLED_ADDR              0x3C
    #define OLED_WIDTH             128
    #define OLED_HEIGHT            64
    #define OLED_PAGES             (OLED_HEIGHT / 8)
    
    /* =========================================================
       LSM6DSV16X - CORRECT REGISTER VALUES FROM DATASHEET
    ========================================================= */
    #define LSM6DSV16X_ADDR        0x6A
    #define WHO_AM_I_REG           0x0F
    #define WHO_AM_I_VALUE         0x70
    
    /* Control registers - CORRECT for LSM6DSV16X */
    #define CTRL1_XL               0x10
    #define CTRL2_G                0x11
    #define CTRL3_C                0x12
    #define CTRL4_C                0x13
    #define CTRL5_C                0x14
    #define CTRL6_C                0x15
    #define CTRL7_G                0x16
    #define CTRL8_XL               0x17
    #define CTRL9_XL               0x18
    #define CTRL10_C               0x19
    
    /* Output registers */
    #define OUT_TEMP_L             0x20
    #define OUT_TEMP_H             0x21
    #define OUTX_L_G               0x22
    #define OUTX_H_G               0x23
    #define OUTY_L_G               0x24
    #define OUTY_H_G               0x25
    #define OUTZ_L_G               0x26
    #define OUTZ_H_G               0x27
    #define OUTX_L_A               0x28
    #define OUTX_H_A               0x29
    #define OUTY_L_A               0x2A
    #define OUTY_H_A               0x2B
    #define OUTZ_L_A               0x2C
    #define OUTZ_H_A               0x2D
    
    /* Configuration values - CORRECT for LSM6DSV16X */
    /* For CTRL1_XL: ODR=104Hz (0x30) + FS=±4g (0x04) = 0x34 */
    /* For CTRL2_G:  ODR=104Hz (0x30) + FS=±1000dps (0x0C) = 0x3C */
    #define XL_ODR_104Hz           0x30
    #define XL_FS_4g               0x04
    #define G_ODR_104Hz            0x30
    #define G_FS_1000dps           0x0C
    
    #define I2C_RETRY_COUNT        5
    
    uint32_t g_ui32SysClock;
    uint8_t g_sensor_addr = 0;
    
    /* Frame buffer */
    uint8_t oled_buffer[OLED_WIDTH * OLED_PAGES];
    uint8_t g_font_scale = 1;
    
    /* Sensor data - using int16_t for raw values */
    typedef struct {
        int16_t ax, ay, az;
        int16_t gx, gy, gz;
        int16_t temperature;
    } sensor_raw_t;
    sensor_raw_t sensor_raw;
    
    /* Function prototypes */
    void OLED_Clear(void);
    void OLED_Update(void);
    void OLED_Command(uint8_t cmd);
    void OLED_SetCursor(uint8_t col, uint8_t page);
    void OLED_DrawPixel(uint8_t x, uint8_t y, bool color);
    void OLED_DrawChar(uint8_t x, uint8_t y, char ch);
    void OLED_DrawString(uint8_t x, uint8_t y, char *str);
    void OLED_TestPattern(void);
    void Display_Data(bool sensor_ok);
    
    /* =========================================================
       8x8 Font (same as your existing)
    ========================================================= */
    const uint8_t Font8x8[][8] = {
        {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
        {0x00,0x00,0x18,0x3C,0x3C,0x18,0x18,0x00},
        {0x00,0x66,0x66,0x24,0x00,0x00,0x00,0x00},
        {0x00,0x36,0x36,0x7F,0x36,0x36,0x7F,0x36},
        {0x08,0x1C,0x2A,0x2A,0x08,0x1C,0x2A,0x2A},
        {0x00,0x62,0x64,0x08,0x10,0x20,0x46,0x86},
        {0x00,0x1C,0x22,0x22,0x14,0x2A,0x4A,0x44},
        {0x00,0x18,0x18,0x08,0x00,0x00,0x00,0x00},
        {0x00,0x0C,0x18,0x30,0x30,0x30,0x18,0x0C},
        {0x00,0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30},
        {0x00,0x00,0x18,0x5A,0x3C,0x5A,0x18,0x00},
        {0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00},
        {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18},
        {0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00},
        {0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18},
        {0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x40},
        {0x3E,0x63,0x73,0x7B,0x6F,0x67,0x3E,0x00},
        {0x0C,0x0E,0x0C,0x0C,0x0C,0x0C,0x3F,0x00},
        {0x1E,0x33,0x30,0x1C,0x06,0x33,0x3F,0x00},
        {0x1E,0x33,0x30,0x1C,0x30,0x33,0x1E,0x00},
        {0x38,0x3C,0x36,0x33,0x7F,0x30,0x78,0x00},
        {0x3F,0x03,0x1F,0x30,0x30,0x33,0x1E,0x00},
        {0x1C,0x06,0x03,0x1F,0x33,0x33,0x1E,0x00},
        {0x3F,0x33,0x30,0x18,0x0C,0x0C,0x0C,0x00},
        {0x1E,0x33,0x33,0x1E,0x33,0x33,0x1E,0x00},
        {0x1E,0x33,0x33,0x3E,0x30,0x18,0x0E,0x00},
        {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00},
        {0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x08},
        {0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10},
        {0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00},
        {0x00,0x20,0x10,0x08,0x04,0x02,0x04,0x08},
        {0x1E,0x33,0x30,0x1C,0x0C,0x00,0x0C,0x00},
        {0x3C,0x4A,0x56,0x52,0x52,0x4E,0x3C,0x00},
        {0x0C,0x1E,0x33,0x33,0x3F,0x33,0x33,0x00},
        {0x3F,0x66,0x66,0x3E,0x66,0x66,0x3F,0x00},
        {0x3C,0x66,0x03,0x03,0x03,0x66,0x3C,0x00},
        {0x1F,0x36,0x66,0x66,0x66,0x36,0x1F,0x00},
        {0x7F,0x46,0x16,0x1E,0x16,0x46,0x7F,0x00},
        {0x7F,0x46,0x16,0x1E,0x16,0x06,0x0F,0x00},
        {0x3C,0x66,0x03,0x03,0x73,0x66,0x7C,0x00},
        {0x33,0x33,0x33,0x3F,0x33,0x33,0x33,0x00},
        {0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00},
        {0x78,0x30,0x30,0x30,0x33,0x33,0x1E,0x00},
        {0x67,0x66,0x36,0x1E,0x36,0x66,0x67,0x00},
        {0x0F,0x06,0x06,0x06,0x46,0x66,0x7F,0x00},
        {0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00},
        {0x63,0x67,0x6F,0x7B,0x73,0x63,0x63,0x00},
        {0x1C,0x36,0x63,0x63,0x63,0x36,0x1C,0x00},
        {0x3F,0x66,0x66,0x3E,0x06,0x06,0x0F,0x00},
        {0x1E,0x33,0x33,0x33,0x3B,0x1E,0x38,0x00},
        {0x3F,0x66,0x66,0x3E,0x36,0x66,0x67,0x00},
        {0x1E,0x33,0x07,0x0E,0x38,0x33,0x1E,0x00},
        {0x3F,0x2D,0x0C,0x0C,0x0C,0x0C,0x1E,0x00},
        {0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x00},
        {0x33,0x33,0x33,0x33,0x33,0x1E,0x0C,0x00},
        {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00},
        {0x63,0x36,0x1C,0x1C,0x36,0x63,0x63,0x00},
        {0x33,0x33,0x1E,0x0C,0x0C,0x0C,0x1E,0x00},
        {0x7F,0x63,0x31,0x18,0x4C,0x66,0x7F,0x00},
        {0x3C,0x20,0x20,0x20,0x20,0x20,0x3C,0x00},
        {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01},
        {0x3C,0x04,0x04,0x04,0x04,0x04,0x3C,0x00},
        {0x08,0x14,0x22,0x41,0x00,0x00,0x00,0x00},
        {0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00},
        {0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00},
        {0x00,0x00,0x1C,0x22,0x22,0x22,0x3C,0x00},
        {0x00,0x20,0x20,0x3C,0x22,0x22,0x3C,0x00},
        {0x00,0x00,0x1C,0x20,0x20,0x20,0x1C,0x00},
        {0x00,0x04,0x04,0x1C,0x24,0x24,0x1C,0x00},
        {0x00,0x00,0x1C,0x22,0x3E,0x20,0x1C,0x00},
        {0x00,0x0E,0x10,0x10,0x7C,0x10,0x10,0x00},
        {0x00,0x00,0x1C,0x22,0x22,0x1C,0x02,0x3C},
        {0x00,0x20,0x20,0x3C,0x22,0x22,0x22,0x00},
        {0x00,0x08,0x00,0x18,0x08,0x08,0x1C,0x00},
        {0x00,0x04,0x00,0x0C,0x04,0x24,0x24,0x18},
        {0x00,0x20,0x20,0x24,0x28,0x30,0x2C,0x00},
        {0x00,0x18,0x08,0x08,0x08,0x08,0x1C,0x00},
        {0x00,0x00,0x00,0x36,0x49,0x49,0x49,0x00},
        {0x00,0x00,0x00,0x3C,0x22,0x22,0x22,0x00},
        {0x00,0x00,0x00,0x1C,0x22,0x22,0x1C,0x00},
        {0x00,0x00,0x3C,0x22,0x22,0x3C,0x20,0x20},
        {0x00,0x00,0x1C,0x24,0x24,0x1C,0x04,0x06},
        {0x00,0x00,0x00,0x2C,0x30,0x20,0x20,0x00},
        {0x00,0x00,0x1C,0x20,0x1C,0x04,0x38,0x00},
        {0x00,0x10,0x10,0x7C,0x10,0x10,0x0C,0x00},
        {0x00,0x00,0x00,0x22,0x22,0x22,0x1C,0x00},
        {0x00,0x00,0x00,0x22,0x22,0x14,0x08,0x00},
        {0x00,0x00,0x00,0x49,0x49,0x49,0x36,0x00},
        {0x00,0x00,0x00,0x22,0x14,0x08,0x14,0x22},
        {0x00,0x00,0x22,0x22,0x22,0x1C,0x08,0x30},
        {0x00,0x00,0x00,0x3E,0x08,0x10,0x3E,0x00},
    };
    
    const uint8_t* Font8x8_GetBitmap(char ch) {
        if (ch < 32 || ch > 126) ch = ' ';
        return Font8x8[ch - 32];
    }
    
    /* =========================================================
       Delay and UART
    ========================================================= */
    void DelayUs(uint32_t us) {
        SysCtlDelay((g_ui32SysClock / 3 / 1000000) * us);
    }
    
    void DelayMs(uint32_t ms) {
        SysCtlDelay((g_ui32SysClock / 3 / 1000) * ms);
    }
    
    void UART0_Init(void) {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART0));
        GPIOPinConfigure(GPIO_PA0_U0RX);
        GPIOPinConfigure(GPIO_PA1_U0TX);
        GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
        UARTConfigSetExpClk(UART0_BASE, g_ui32SysClock, 115200,
                            UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE);
        UARTEnable(UART0_BASE);
    }
    
    void UART_Print(char *str) {
        while(*str) UARTCharPut(UART0_BASE, *str++);
    }
    
    /* =========================================================
       I2C Functions
    ========================================================= */
    void I2C0_Init(void) {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C0));
        GPIOPinConfigure(GPIO_PB2_I2C0SCL);
        GPIOPinConfigure(GPIO_PB3_I2C0SDA);
        GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
        GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
        I2CMasterInitExpClk(I2C0_BASE, g_ui32SysClock, false);
        DelayMs(10);
    }
    
    bool I2C0_Write(uint8_t addr, uint8_t *data, uint32_t len) {
        uint32_t i;
        uint32_t timeout;
    
        I2CMasterSlaveAddrSet(I2C0_BASE, addr, false);
    
        for(i = 0; i < len; i++) {
            timeout = 10000;
            while(I2CMasterBusy(I2C0_BASE) && timeout--) DelayUs(1);
            if(timeout == 0) return false;
    
            I2CMasterDataPut(I2C0_BASE, data[i]);
    
            if(len == 1) {
                I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
            } else if(i == 0) {
                I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
            } else if(i == len-1) {
                I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
            } else {
                I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
            }
    
            timeout = 10000;
            while(I2CMasterBusy(I2C0_BASE) && timeout--) DelayUs(1);
            if(timeout == 0) return false;
            if(I2CMasterErr(I2C0_BASE)) return false;
            if(i < len-1) DelayUs(10);
        }
        return true;
    }
    
    void I2C1_Init(void) {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C1));
        GPIOPinConfigure(GPIO_PG0_I2C1SCL);
        GPIOPinConfigure(GPIO_PG1_I2C1SDA);
        GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0);
        GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);
        I2CMasterInitExpClk(I2C1_BASE, g_ui32SysClock, false);
    }
    
    bool I2C1_Write(uint8_t addr, uint8_t reg, uint8_t data) {
        uint32_t timeout = 10000;
        while(I2CMasterBusy(I2C1_BASE) && timeout--) DelayUs(1);
        if(timeout == 0) return false;
    
        I2CMasterSlaveAddrSet(I2C1_BASE, addr, false);
        I2CMasterDataPut(I2C1_BASE, reg);
        I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_START);
    
        timeout = 10000;
        while(I2CMasterBusy(I2C1_BASE) && timeout--) DelayUs(1);
        if(timeout == 0) return false;
        if(I2CMasterErr(I2C1_BASE)) return false;
    
        I2CMasterDataPut(I2C1_BASE, data);
        I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
    
        timeout = 10000;
        while(I2CMasterBusy(I2C1_BASE) && timeout--) DelayUs(1);
        if(timeout == 0) return false;
        return (I2CMasterErr(I2C1_BASE) == 0);
    }
    
    bool I2C1_Read(uint8_t addr, uint8_t reg, uint8_t *data) {
        uint32_t timeout = 10000;
        while(I2CMasterBusy(I2C1_BASE) && timeout--) DelayUs(1);
        if(timeout == 0) return false;
    
        I2CMasterSlaveAddrSet(I2C1_BASE, addr, false);
        I2CMasterDataPut(I2C1_BASE, reg);
        I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    
        timeout = 10000;
        while(I2CMasterBusy(I2C1_BASE) && timeout--) DelayUs(1);
        if(timeout == 0) return false;
        if(I2CMasterErr(I2C1_BASE)) return false;
    
        I2CMasterSlaveAddrSet(I2C1_BASE, addr, true);
        I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
    
        timeout = 10000;
        while(I2CMasterBusy(I2C1_BASE) && timeout--) DelayUs(1);
        if(timeout == 0) return false;
        if(I2CMasterErr(I2C1_BASE)) return false;
    
        *data = I2CMasterDataGet(I2C1_BASE);
        return true;
    }
    
    bool I2C1_Write_Retry(uint8_t addr, uint8_t reg, uint8_t data) {
        uint8_t attempt;
        for(attempt = 0; attempt < I2C_RETRY_COUNT; attempt++) {
            if(I2C1_Write(addr, reg, data)) return true;
            DelayMs(5);
        }
        return false;
    }
    
    bool I2C1_Read_Retry(uint8_t addr, uint8_t reg, uint8_t *data) {
        uint8_t attempt;
        for(attempt = 0; attempt < I2C_RETRY_COUNT; attempt++) {
            if(I2C1_Read(addr, reg, data)) return true;
            DelayMs(5);
        }
        return false;
    }
    
    /* =========================================================
       Sensor Functions - CORRECTED
    ========================================================= */
    void Sensor_Probe(void) {
        uint8_t whoami;
        char msg[64];
    
        UART_Print("Probing LSM6DSV16X...\r\n");
    
        if(I2C1_Read_Retry(0x6A, WHO_AM_I_REG, &whoami)) {
            sprintf(msg, "  0x6A: WHO_AM_I = 0x%02X\r\n", whoami);
            UART_Print(msg);
            if(whoami == WHO_AM_I_VALUE) {
                g_sensor_addr = 0x6A;
                UART_Print(">>> Sensor found at 0x6A!\r\n");
                return;
            }
        }
    
        if(I2C1_Read_Retry(0x6B, WHO_AM_I_REG, &whoami)) {
            sprintf(msg, "  0x6B: WHO_AM_I = 0x%02X\r\n", whoami);
            UART_Print(msg);
            if(whoami == WHO_AM_I_VALUE) {
                g_sensor_addr = 0x6B;
                UART_Print(">>> Sensor found at 0x6B!\r\n");
                return;
            }
        }
    
        g_sensor_addr = 0;
        UART_Print(">>> SENSOR NOT FOUND!\r\n");
    }
    
    bool Sensor_Init(void) {
        uint8_t reg;
        char msg[64];
    
        if(g_sensor_addr == 0) return false;
    
        UART_Print("\r\nInitializing LSM6DSV16X...\r\n");
    
        /* Software reset */
        UART_Print("  Software reset...\r\n");
        if(!I2C1_Write_Retry(g_sensor_addr, CTRL3_C, 0x01)) {
            UART_Print("  FAILED!\r\n");
            return false;
        }
        DelayMs(100);
    
        /* Enable BDU (Block Data Update) and IF_INC */
        UART_Print("  Enabling BDU...\r\n");
        if(!I2C1_Write_Retry(g_sensor_addr, CTRL3_C, 0x44)) {
            UART_Print("  FAILED!\r\n");
            return false;
        }
        DelayMs(10);
    
        /* Configure accelerometer: 104Hz, ±4g */
        UART_Print("  Configuring accelerometer (104Hz, ±4g)...\r\n");
        if(!I2C1_Write_Retry(g_sensor_addr, CTRL1_XL, XL_ODR_104Hz | XL_FS_4g)) {
            UART_Print("  FAILED!\r\n");
            return false;
        }
        DelayMs(10);
    
        /* Configure gyroscope: 104Hz, ±1000dps */
        UART_Print("  Configuring gyroscope (104Hz, ±1000dps)...\r\n");
        if(!I2C1_Write_Retry(g_sensor_addr, CTRL2_G, G_ODR_104Hz | G_FS_1000dps)) {
            UART_Print("  FAILED!\r\n");
            return false;
        }
        DelayMs(10);
    
        /* Verify configuration */
        I2C1_Read_Retry(g_sensor_addr, CTRL1_XL, &reg);
        sprintf(msg, "  CTRL1_XL = 0x%02X (Expected: 0x34)\r\n", reg);
        UART_Print(msg);
    
        I2C1_Read_Retry(g_sensor_addr, CTRL2_G, &reg);
        sprintf(msg, "  CTRL2_G  = 0x%02X (Expected: 0x3C)\r\n", reg);
        UART_Print(msg);
    
        UART_Print(">>> Sensor initialized!\r\n");
        return true;
    }
    
    bool Sensor_Read(sensor_raw_t *data) {
        uint8_t low, high;
    
        if(g_sensor_addr == 0) return false;
    
        /* Read temperature */
        if(!I2C1_Read_Retry(g_sensor_addr, OUT_TEMP_L, &low)) return false;
        if(!I2C1_Read_Retry(g_sensor_addr, OUT_TEMP_H, &high)) return false;
        data->temperature = (int16_t)((high << 8) | low);
    
        /* Read gyroscope */
        if(!I2C1_Read_Retry(g_sensor_addr, OUTX_L_G, &low)) return false;
        if(!I2C1_Read_Retry(g_sensor_addr, OUTX_H_G, &high)) return false;
        data->gx = (int16_t)((high << 8) | low);
    
        if(!I2C1_Read_Retry(g_sensor_addr, OUTY_L_G, &low)) return false;
        if(!I2C1_Read_Retry(g_sensor_addr, OUTY_H_G, &high)) return false;
        data->gy = (int16_t)((high << 8) | low);
    
        if(!I2C1_Read_Retry(g_sensor_addr, OUTZ_L_G, &low)) return false;
        if(!I2C1_Read_Retry(g_sensor_addr, OUTZ_H_G, &high)) return false;
        data->gz = (int16_t)((high << 8) | low);
    
        /* Read accelerometer */
        if(!I2C1_Read_Retry(g_sensor_addr, OUTX_L_A, &low)) return false;
        if(!I2C1_Read_Retry(g_sensor_addr, OUTX_H_A, &high)) return false;
        data->ax = (int16_t)((high << 8) | low);
    
        if(!I2C1_Read_Retry(g_sensor_addr, OUTY_L_A, &low)) return false;
        if(!I2C1_Read_Retry(g_sensor_addr, OUTY_H_A, &high)) return false;
        data->ay = (int16_t)((high << 8) | low);
    
        if(!I2C1_Read_Retry(g_sensor_addr, OUTZ_L_A, &low)) return false;
        if(!I2C1_Read_Retry(g_sensor_addr, OUTZ_H_A, &high)) return false;
        data->az = (int16_t)((high << 8) | low);
    
        return true;
    }
    
    /* =========================================================
       OLED Driver
    ========================================================= */
    void OLED_Command(uint8_t cmd) {
        uint8_t d[2] = {0x00, cmd};
        I2C0_Write(OLED_ADDR, d, 2);
        DelayUs(50);
    }
    
    void OLED_Init(void) {
        DelayMs(100);
        OLED_Command(0xAE);
        DelayMs(10);
        OLED_Command(0xD5);
        OLED_Command(0x80);
        DelayUs(10);
        OLED_Command(0xA8);
        OLED_Command(0x3F);
        DelayUs(10);
        OLED_Command(0xD3);
        OLED_Command(0x00);
        DelayUs(10);
        OLED_Command(0x40);
        DelayUs(10);
        OLED_Command(0x8D);
        OLED_Command(0x14);
        DelayMs(50);
        OLED_Command(0x20);
        OLED_Command(0x02);
        DelayUs(10);
        OLED_Command(0xA1);
        DelayUs(10);
        OLED_Command(0xC8);
        DelayUs(10);
        OLED_Command(0xDA);
        OLED_Command(0x12);
        DelayUs(10);
        OLED_Command(0x81);
        OLED_Command(0xCF);
        DelayUs(10);
        OLED_Command(0xD9);
        OLED_Command(0xF1);
        DelayUs(10);
        OLED_Command(0xDB);
        OLED_Command(0x20);
        DelayUs(10);
        OLED_Command(0xA4);
        DelayUs(10);
        OLED_Command(0xA6);
        DelayUs(10);
        OLED_Command(0xAF);
        DelayMs(100);
        OLED_Clear();
        OLED_Update();
    }
    
    void OLED_SetCursor(uint8_t col, uint8_t page) {
        OLED_Command(0xB0 | (page & 0x07));
        OLED_Command(0x00 | (col & 0x0F));
        OLED_Command(0x10 | ((col >> 4) & 0x0F));
        DelayUs(10);
    }
    
    void OLED_Clear(void) {
        memset(oled_buffer, 0x00, sizeof(oled_buffer));
    }
    
    void OLED_Update(void) {
        uint8_t page;
        uint8_t tx_buffer[129];
        tx_buffer[0] = 0x40;
    
        for(page = 0; page < OLED_PAGES; page++) {
            OLED_SetCursor(0, page);
            memcpy(&tx_buffer[1], &oled_buffer[page * OLED_WIDTH], OLED_WIDTH);
            I2C0_Write(OLED_ADDR, tx_buffer, OLED_WIDTH + 1);
            DelayUs(100);
        }
    }
    
    void OLED_DrawPixel(uint8_t x, uint8_t y, bool color) {
        uint16_t index;
        uint8_t bit;
        if(x >= OLED_WIDTH || y >= OLED_HEIGHT) return;
        index = x + ((y >> 3) * OLED_WIDTH);
        bit = y & 0x07;
        if(color)
            oled_buffer[index] |= (1 << bit);
        else
            oled_buffer[index] &= ~(1 << bit);
    }
    
    void OLED_DrawChar(uint8_t x, uint8_t y, char ch) {
        const uint8_t *bitmap = Font8x8_GetBitmap(ch);
        uint8_t row, col, sx, sy;
        uint8_t scale = g_font_scale;
        int16_t pixel_x, pixel_y;
        uint8_t line;
    
        for(row = 0; row < 8; row++) {
            line = bitmap[row];
            for(col = 0; col < 8; col++) {
                if(line & (1 << (7 - col))) {
                    for(sx = 0; sx < scale; sx++) {
                        for(sy = 0; sy < scale; sy++) {
                            pixel_x = x + col * scale + sx;
                            pixel_y = y + row * scale + sy;
                            if(pixel_x < OLED_WIDTH && pixel_y < OLED_HEIGHT) {
                                OLED_DrawPixel(pixel_x, pixel_y, true);
                            }
                        }
                    }
                }
            }
        }
    }
    
    void OLED_DrawString(uint8_t x, uint8_t y, char *str) {
        uint8_t scale = g_font_scale;
        uint8_t orig_x = x;
    
        while(*str) {
            OLED_DrawChar(x, y, *str++);
            x += 8 * scale;
            if(x + 8 * scale >= OLED_WIDTH) {
                x = orig_x;
                y += 8 * scale;
                if(y + 8 * scale >= OLED_HEIGHT) break;
            }
        }
    }
    
    void OLED_TestPattern(void) {
       // uint8_t i;
    
        OLED_Clear();
        OLED_DrawString(0, 0, "OLED Test");
        OLED_DrawString(0, 16, "LSM6DSV16X");
        OLED_DrawString(0, 32, "TM4C129");
        OLED_DrawString(0, 48, "Ready!");
        OLED_Update();
        DelayMs(2000);
        OLED_Clear();
    }
    
    /* =========================================================
       Display Function - Shows live sensor values
    ========================================================= */
    void Display_Data(bool sensor_ok) {
        char buf[32];
        int16_t ax_mg, ay_mg, az_mg;
        int16_t gx_dps, gy_dps, gz_dps;
        int16_t temp_c;
        static uint16_t counter = 0;
    
        OLED_Clear();
    
        if(sensor_ok) {
            /* Convert raw values to readable units */
            ax_mg = (int16_t)(((int32_t)sensor_raw.ax * 488) / 1000);
            ay_mg = (int16_t)(((int32_t)sensor_raw.ay * 488) / 1000);
            az_mg = (int16_t)(((int32_t)sensor_raw.az * 488) / 1000);
            gx_dps = (int16_t)(((int32_t)sensor_raw.gx * 175) / 10000);
            gy_dps = (int16_t)(((int32_t)sensor_raw.gy * 175) / 10000);
            gz_dps = (int16_t)(((int32_t)sensor_raw.gz * 175) / 10000);
            temp_c = (int16_t)(25 + (sensor_raw.temperature / 256));
    
            /* Line 0: Title */
            OLED_DrawString(0, 0, "LSM6DSV16X");
    
            /* Line 1: Temperature */
            sprintf(buf, "T:%3dC  R:%4d", temp_c, sensor_raw.temperature);
            OLED_DrawString(0, 8, buf);
    
            /* Line 2: Accelerometer X */
            sprintf(buf, "AX:%+5d mg", ax_mg);
            OLED_DrawString(0, 16, buf);
    
            /* Line 3: Accelerometer Y */
            sprintf(buf, "AY:%+5d mg", ay_mg);
            OLED_DrawString(0, 24, buf);
    
            /* Line 4: Accelerometer Z */
            sprintf(buf, "AZ:%+5d mg", az_mg);
            OLED_DrawString(0, 32, buf);
    
            /* Line 5: Gyroscope X & Y */
            sprintf(buf, "GX:%+3d GY:%+3d", gx_dps, gy_dps);
            OLED_DrawString(0, 40, buf);
    
            /* Line 6: Gyroscope Z */
            sprintf(buf, "GZ:%+4d", gz_dps);
            OLED_DrawString(0, 48, buf);
    
            /* Line 7: Counter */
            counter++;
            if(counter > 999) counter = 0;
            sprintf(buf, "OK  #%04d", counter);
            OLED_DrawString(0, 56, buf);
    
        } else {
            OLED_DrawString(0, 0, "SENSOR ERROR!");
            OLED_DrawString(0, 16, "Check wiring:");
            OLED_DrawString(0, 24, "VCC->3.3V");
            OLED_DrawString(0, 32, "GND->GND");
            OLED_DrawString(0, 40, "SCL->PG0");
            OLED_DrawString(0, 48, "SDA->PG1");
            OLED_DrawString(0, 56, "Pullups:4.7k");
        }
    
        OLED_Update();
    }
    
    /* =========================================================
       MAIN
    ========================================================= */
    int main(void) {
        char msg[128];
        uint32_t loop_count = 0;
        bool sensor_ok = false;
        uint32_t error_count = 0;
    
        g_ui32SysClock = SysCtlClockFreqSet(SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN |
                                            SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000);
    
        UART0_Init();
        DelayMs(100);
    
        UART_Print("\r\n========================================\r\n");
        UART_Print("TM4C129 + LSM6DSV16X + SSD1306 OLED\r\n");
        UART_Print("System Clock: 120MHz\r\n");
        UART_Print("========================================\r\n\r\n");
    
        I2C0_Init();
        I2C1_Init();
    
        OLED_Init();
        UART_Print("OLED Initialized\r\n");
    
        OLED_TestPattern();
    
        Sensor_Probe();
    
        if(g_sensor_addr != 0) {
            sensor_ok = Sensor_Init();
            if(sensor_ok) {
                UART_Print("\r\n>>> SENSOR READY! <<<\r\n");
                UART_Print("========================================\r\n\r\n");
            } else {
                UART_Print("Sensor init failed!\r\n");
            }
        } else {
            UART_Print("Sensor not found!\r\n");
        }
    
        while(1) {
            bool success = false;
    
            if(sensor_ok) {
                success = Sensor_Read(&sensor_raw);
    
                if(success) {
                    error_count = 0;
    
                    int16_t ax_mg = (int16_t)(((int32_t)sensor_raw.ax * 488) / 1000);
                    int16_t ay_mg = (int16_t)(((int32_t)sensor_raw.ay * 488) / 1000);
                    int16_t az_mg = (int16_t)(((int32_t)sensor_raw.az * 488) / 1000);
                    int16_t gx_dps = (int16_t)(((int32_t)sensor_raw.gx * 175) / 10000);
                    int16_t gy_dps = (int16_t)(((int32_t)sensor_raw.gy * 175) / 10000);
                    int16_t gz_dps = (int16_t)(((int32_t)sensor_raw.gz * 175) / 10000);
                    int16_t temp_c = (int16_t)(25 + (sensor_raw.temperature / 256));
    
                    if(loop_count % 10 == 0) {
                        sprintf(msg, "[%4lu] T=%2dC AX=%+4dmg AY=%+4dmg AZ=%+4dmg | GX=%+3d GY=%+3d GZ=%+3d dps\r\n",
                                loop_count, temp_c, ax_mg, ay_mg, az_mg,
                                gx_dps, gy_dps, gz_dps);
                        UART_Print(msg);
                    }
                    loop_count++;
    
                } else {
                    error_count++;
                    if(error_count == 1) {
                        UART_Print("Read error! Retrying...\r\n");
                    }
                    if(error_count > 20) {
                        UART_Print("Too many errors, reinitializing...\r\n");
                        sensor_ok = Sensor_Init();
                        error_count = 0;
                    }
                    DelayMs(50);
                    continue;
                }
            }
    
            Display_Data(success);
            DelayMs(200);
        }
    }
    

    UART TERMINAL DISPLAYING imu VALUES
    T=24.5 AX=1536mg AY=0mg AZ=909mg

    T=-90.-4 AX=1348mg AY=-3mg AZ=-31mg

    T=-82.-4 AX=-994mg AY=0mg AZ=1160mg

    T=25.0 AX=-992mg AY=0mg AZ=-62mg

    T=24.6 AX=-87mg AY=-62mg AZ=-61mg

    0x6A WHO_AM_I = 0x70

    Initializing Sensor...

    CTRL3_C = 0x44

    CTRL8 = 0x44

    CTRL9 = 0x00

    Sensor OK.

    T=-87.0 AX=-1987mg AY=-1348mg AZ=-93mg

    T=24.9 AX=-2853mg AY=-3mg AZ=-93mg

    T=25.0 AX=-1986mg AY=-4mg AZ=16mg

    T=-58.-3 AX=-1986mg AY=-5mg AZ=-93mg

    T=24.6 AX=-1986mg AY=-3mg AZ=3166mg

    T=25.0 AX=-1998mg AY=-5mg AZ=-93mg

    T=24.6 AX=1787mg AY=-878mg AZ=-93mg

    T=25.0 AX=-1987mg AY=-7mg AZ=-112mg

    T=25.0 AX=-1984mg AY=-1348mg AZ=-110mg

    T=25.0 AX=-1975mg AY=-815mg AZ=-93mg

    T=-64.0 AX=-3888mg AY=-7mg AZ=-93mg

    T=25.0 AX=3041mg AY=-3mg AZ=3480mg

    T=24.0 AX=-1987mg AY=-4mg AZ=-112mg

    T=24.6 AX=-1985mg AY=0mg AZ=-114mg

    T=24.0 AX=3229mg AY=-2mg AZ=-93mg

    T=24.0 AX=-1987mg AY=-1097mg AZ=-113mg

    T=24.6 AX=-1998mg AY=-846mg AZ=-111mg

    T=-52.-3 AX=-1975mg AY=-972mg AZ=-93mg

    T=-63.0 AX=-1998mg AY=-3mg AZ=-112mg

    T=24.9 AX=-1998mg AY=-3mg AZ=3260mg

    T=25.0 AX=-1998mg AY=-1mg AZ=-111mg

    T=24.9 AX=-1990mg AY=-1066mg AZ=-93mg

    T=-80.-4 AX=2759mg AY=-1097mg AZ=-93mg

    T=24.9 AX=-1986mg AY=-2mg AZ=2978mg

    T=25.0 AX=-1986mg AY=-7mg AZ=-93mg

    T=24.5 AX=-1998mg AY=-2mg AZ=-93mg

    T=24.0 AX=-1998mg AY=-376mg AZ=-93mg

    T=24.0 AX=2853mg AY=-7mg AZ=-113mg

    T=24.0 AX=-1998mg AY=-1mg AZ=-113mg

    T=24.0 AX=3919mg AY=-3mg AZ=-93mg

    T=25.0 AX=-1975mg AY=-3mg AZ=-93mg

    T=24.0 AX=-3355mg AY=-7mg AZ=-112mg

    T=150.4 AX=-1975mg AY=-2mg AZ=-113mg

    T=24.0 AX=-3605mg AY=-815mg AZ=3135mg

    T=24.0 AX=-1984mg AY=-7mg AZ=-93mg

    T=24.0 AX=-1987mg AY=-1316mg AZ=-113mg

    T=24.9 AX=-1987mg AY=-4mg AZ=-93mg

    T=24.0 AX=2665mg AY=-1066mg AZ=3135mg

    T=25.0 AX=3229mg AY=-595mg AZ=2529mg

    T=24.5 AX=-1985mg AY=0mg AZ=-112mg

    T=24.0 AX=-1998mg AY=-689mg AZ=-93mg

    T=-96.-4 AX=-1998mg AY=-4mg AZ=-111mg

    T=-96.0 AX=-3888mg AY=-7mg AZ=3185mg

  • You are darn close to 32 characters for the string. I suggest making buf 64.

  • You can also try a serial print from *inside* the OLed print string function.

    You can also look inside the oled draw character function and make sure it is getting the right characters.

  • >  sprintf(buf, "AX:%+5d mg", ax_mg);

    "%d" expects an "int" ("int32_t" in this case), not an "int16_t". Try instead:

    >  sprintf(buf, "AX:%+5d mg", (int32_t)ax_mg);

  • Any word on this? I am curious as to what the issue is.