Problem getting LVGL to draw objects correctly when updated

Problem getting LVGL to draw objects correctly when updated

What MCU/Processor/Board and compiler are you using?

STM32F4_BLACK (STM32F407VET6)

What LVGL version are you using?

7.9.1

What do you want to achieve?

I want to get LVGL running properly on the cheap STM32F4 Black board, currently have it wired up 16-bit parallel on FSMC.

What have you tried so far?

I believe my error is with how I am drawing LVGL.
“void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p);”

I have tried several combination, I can get LVGL to draw correctly if I use tft.drawPixel command but obviously this is very inefficient way to do it but good to know it is working.

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t x, y;
for (y = area->y1; y <= area->y2; y++) {
    for (x = area->x1; x <= area->x2; x++) {
        tft.drawPixel(x, y, color_p->full); // Put a pixel to the display.
        color_p++;
    }
} 

Code to reproduce

This draws everything correct until you interact with an object or an object value gets updated on screen.

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
  uint16_t c;
  tft.setWindow(area->x1, area->y1, (area->x2 - area->x1), (area->y2 - area->y1)); // set the working window 
  for (int y = area->y1; y <= area->y2; y++) {
    for (int x = area->x1; x <= area->x2; x++) {
      c = color_p->full;
      tft.pushColor(c, 1);
      color_p++;
    }
  }
  lv_disp_flush_ready(disp); // tell lvgl that flushing is done 
}

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.

Current screenshots and video (.zip) using tft.setWindow


20210118_014055_360x360.zip (2.6 MB)

Could be that your calculation of width and height for tft.setWindow is wrong!?

area->x1 = 0
area->x2 = 2

How many pixels per line should be copied? Two or three?

Or what does tft.setWindow expect?
Really x, y, width, height or x1, y1, x2, y2?

Thanks for the reply, I suspect it is my calculation. I was using a few examples but don’t think it is correct; is there an easy way for calculating the draw window.
The screen is 800 x 480 and driver is SSD1963

The library I’m using is GxTFT and so the setWindow() expects:
tft.setWindow(x0, y0, x1, y1)

The correct usage would be

tft.setWindow (area->x1, area->y1, area->x2, area->y2);

I see in this example (https://www.arduinoforum.de/arduino-Thread-Frage-zu-Grafik), the next line after tft.setWindow would be:

tft.setColors (color_p,  (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1));

In this case, you can omitt the two for loops.

2 Likes

Awesome, really appreciate your help with this.

I will have a look when I get to the workshop tonight and let you know.

Its working with the code used below, thank you for your help with this.

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
  uint16_t c;
    tft.setWindow(area->x1, area->y1, area->x2, area->y2 ); /* set the working window */
    for (int y = area->y1; y <= area->y2; y++) {
      for (int x = area->x1; x <= area->x2; x++) {
        c = color_p->full; 
        tft.pushColor(c, 1);
        color_p++;
     }
  }
  lv_disp_flush_ready(disp); // tell lvgl that flushing is done 
}

Removing the loop and adding the second line you recommended just displayed a blank screen.

I now just need to tweak the touch screen, the current library I’m using is a bit outdated but I should be good to go.

1 Like