This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Text Flicker with ILI9341 GFX Library

I'm working with Fantel's adaptation of the nrf52840 (EV-BT840F). I have gotten the GFX example working with Adafruit's ILI9341 in SPI mode, however I am having a problem with text flickering.

When I display text I have to erase that text to show the next string. Currently I am re-writing only the pixels containing text to the background color and then writing the new text on the cleared section. The text is still flickering significantly though.

Looking at Arduino and Adafruit forums I notice that the Adafruit library has a function where you can set the foreground and background colors for text which helps with this flickering problem. I haven't seen anything like that in Nordic's GFX library. Has anyone incorporated that or found a fix for this text flickering?

  • Hello, 

    I'm not able to see the video you have attached. And unfortunately, I do not have any displays available for testing at the moment.

    What version of the SDK are you using? Have you tried to change the delay time in the while loop? Have you verified the connections are correct?

    Kind regards,
    Øyvind

  • Hi Oyvind,

    I am using SDK "nRF5_SDK_16.0.0_98a08e2" there is no delay in the while loop, so it is running at max speed at the moment. I am simply using the GFX example provided in the SDK, the only modifications I have made are the pinout for the Fanstel development board.

    The screen is displaying text, images, and everything fine so I believe the connections are correct. The problem is the update rate of the screen is very low. When I want to write new text to the screen I have to "erase" the old text by writing over it with a rectangle, then the new text slowly writes on the screen. When I want to update a number, like a readout from the ADC, the number appears to flicker because it is erased and then re-written slowly. I have re-uploaded the video below as an mp4, hopefully it will show this time.

    Here is my main loop:

    int main(void)
    {
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("GFX usage example application started.")
        NRF_LOG_FLUSH();
    
        gfx_initialization();
        screen_clear();
    
        while (1)
        {
           nrf_gfx_rotation_set(p_lcd, NRF_LCD_ROTATE_90);
    
           nrf_gfx_point_t text_start = NRF_GFX_POINT(20, 100);
           nrf_gfx_print(p_lcd, &text_start, GRAY, "Hello World!", p_font, false);
           nrf_gfx_screen_fill_area(p_lcd,20,104,235,31,0);
           nrf_gfx_print(p_lcd, &text_start, GRAY, "Test Text", p_font, false);
           nrf_gfx_screen_fill_area(p_lcd,20,104,235,31,0);
    
    //       brackground_set();
    //       text_print();
    //       nrf_delay_ms(1000);
    //       screen_clear();
    //       line_draw();
    //       nrf_delay_ms(1000);
    //       screen_clear();
    //       circle_draw();
    //       nrf_delay_ms(1000);
    //       screen_clear();
    //       test_rect_draw();
    //       nrf_delay_ms(1000);
        }
    }

  • Hello, 

    My apologies for the late reply. I have been waiting for a display, which I received today. Will get back to you within tomorrow or Friday. 

    Kind regards,
    Øyvind

  • I'm experiencing this as well. The cause is that you're using screen fill to erase the area first. Like writing an image, it happens slowly over the spi bus. Once the whole rectangle has been written it writes pixel by pixel of the text, only writing needed pixels, but not overwriting the background.

    As an improvement I tried writing the old text first with the background colour and then write the text, this reduces flicker but it still shows clearing and then writing the pixels. What we both need is to blank the background 

    The two methods that might avoid this is to convert the text to an image temporarily and write the whole image, thus overwriting the background. The second method is to re-write the nrf_gfx_print and write_character function to accept an old and new text string and generate pixel writes for both the old and new text.

    I'm working on this now but it's tricky. The second method is difficult unless font width is constant. So still trying to figure this out.

  • Modifying the write_character function, I included a rect_draw for a single line. This sets the line to the bckgnd_color (which now needs to be specified, and I modified  nrf_gfx_print to accept a background color and pass it forward). If you 

    This works better than a full clear of the area or the write old character to background as you won't perceive the line clears versus a rectangle clear. It is displaying very cleanly on a ST7789 LCD BUT it leaves artifacts if the width of the new character(s) is smaller than the old. My goal is to use this for numerics and it seems okay to do a constant width font using The Dot Factory. But I Limited the font to the numbers, as some characters are wider and cause the min width to be large making it look bad. 

    static void write_character_bckgnd(nrf_lcd_t const * p_instance,
                                nrf_gfx_font_desc_t const * p_font,
                                uint8_t character,
                                uint16_t * p_x,
                                uint16_t y,
                                uint16_t font_color,
                                uint16_t bckgnd_color)
    {
        uint8_t char_idx = character - p_font->startChar;
        uint16_t bytes_in_line = CEIL_DIV(p_font->charInfo[char_idx].widthBits, 8);
    
        if (character == ' ')
        {
            *p_x += p_font->height / 2;
            return;
        }
    
        for (uint16_t i = 0; i < p_font->height; i++)
        {
            rect_draw(p_instance, *p_x, y+i, p_font->charInfo[char_idx].widthBits + p_font->spacePixels,1,bckgnd_color);
            for (uint16_t j = 0; j < bytes_in_line; j++)
            {
                for (uint8_t k = 0; k < 8; k++)
                {
                    if ((1 << (7 - k)) &
                        p_font->data[p_font->charInfo[char_idx].offset + i * bytes_in_line + j])
                    {
                        pixel_draw(p_instance, *p_x + j * 8 + k, y + i, font_color);
                    }
                }
            }
        }
    
        *p_x += p_font->charInfo[char_idx].widthBits + p_font->spacePixels;
    }

Related