Search code examples
cstm32microcontrollerhardwaredisplay

How to display values in a OLED Display without the entire text blinking when continuous values are being sent?


I am trying to display the values I read from my NTC temperature sensors using a STM32 Microcontroller and write it on a OLED Display. However as I am continuously sending the values the entire text and value keep blinking instead of just the values. I only want the updated values to blink and the supporting text like "Temperature NTC1: " not to blink.

This is my code below which I tried inside the while loop, and I used the display library from this website : https://controllerstech.com/oled-display-using-i2c-stm32/

char tempStr[32];  ///16
                            SSD1306_Init (); // initialize the display
                        SSD1306_Clear();  // Clear the screen
                        SSD1306_GotoXY(10, 10);  // Adjust Y position for the first temperature value
                    snprintf(tempStr, sizeof(tempStr),"Temp NTC1: %.2f °C" , temperature_ntc1);  // Format NTC1 temperature value to string and store in tempStr array
                    SSD1306_Puts(tempStr, &Font_7x10, SSD1306_COLOR_WHITE);    //Print/ Display NTC1 temperature
                    SSD1306_GotoXY(10, 30);  //Adjust the Y position for the second temperature value
                    snprintf(tempStr, sizeof(tempStr),"Temp NTC2: %.2f °C" , temperature_ntc2); //Format NTC2 temperature
                    SSD1306_Puts(tempStr, &Font_7x10, SSD1306_COLOR_WHITE); //Print/ Display NTC2 temperature
                    SSD1306_UpdateScreen(); //Update the display by sending buffer data to controller
                    HAL_Delay(5000);

I tried giving this particular string outside the while loop (code given below) as a static text however still the entire text keeps blinking when new values are send.

What I exactly want is "Temp NTC1: and Temp NTC2:" to stay static and the reading values to keep blinking every second when new values are being updated.

char staticText1[] = "Temp NTC1: ";
char staticText2[] = "Temp NTC2: ";
char tempStr1[32];
char tempStr2[32];

SSD1306_Init();   // Initialize OLED

while (1)
{
    // .temperature calculation code for NTC1 ...

    // Format NTC1 temperature value
    snprintf(tempStr1, sizeof(tempStr1), "%.2f °C", temperature_ntc1);

    // ... temperature calculation code for NTC2 ...

    // Format NTC2 temperature value
    snprintf(tempStr2, sizeof(tempStr2), "%.2f °C", temperature_ntc2);

    SSD1306_Clear();  // Clear the entire screen

    // Display static text for NTC1
    SSD1306_GotoXY(10, 10);
    SSD1306_Puts(staticText1, &Font_7x10, SSD1306_COLOR_WHITE);

    // Display NTC1 temperature value
    SSD1306_GotoXY(10 + strlen(staticText1) * 7, 10);
    SSD1306_Puts(tempStr1, &Font_7x10, SSD1306_COLOR_WHITE);

    // Display static text for NTC2
    SSD1306_GotoXY(10, 30);
    SSD1306_Puts(staticText2, &Font_7x10, SSD1306_COLOR_WHITE);

    // Display NTC2 temperature value
    SSD1306_GotoXY(10 + strlen(staticText2) * 7, 30);
    SSD1306_Puts(tempStr2, &Font_7x10, SSD1306_COLOR_WHITE);

    SSD1306_UpdateScreen();

    HAL_Delay(1000);  // Update the values every second
}

Solution

  • Looking at the source for the SSD1306 library (reproduced in this Gist for convenience), SSD1306_Clear is implemented as

    void SSD1306_Clear (void)
    {
        SSD1306_Fill (0);
        SSD1306_UpdateScreen();
    }
    

    However, you do not want to immediately update the internal (now cleared) buffer to the screen (that causes the flicker).

    Replace your SSD1306_Clear(); call with just a SSD1306_Fill(0); and you're good to go.