Label alignment with ePaper

Description

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

Configuration:

  • NUCLEO-L452RE
  • ICE Driving Board connected through SPI
  • ED043WC3 ePaper display
  • arm-gcc with -O1

What do you want to achieve?

Align labels with coordinate modification OR
Set the position of a label.

The Problem

After I change the text of the label it will have this angled look. See the attached picture.
This happens only if the X coordinate is not equal with 0.

What have you tried so far?

Code

static lv_style_t style200_txt;
static lv_obj_t* label1 = NULL;

void LoadScreen()
{
  LV_FONT_DECLARE(bpreplay_bold_200);
  
  /*Create a new style*/
  lv_style_copy(&style200_txt, &lv_style_plain);
  style200_txt.text.font = &bpreplay_bold_200;
  style200_txt.text.letter_space = 2;
  style200_txt.text.line_space = 1;
  style200_txt.text.color = LV_COLOR_BLACK;
  style200_txt.body.main_color = LV_COLOR_GRAY;
  style200_txt.body.padding.bottom = 10;
  style200_txt.body.padding.top = 10;
  
  /*Create a new label*/
  label1 = lv_label_create(lv_scr_act(), NULL);
  lv_obj_set_style(label1, &style200_txt); 
  lv_label_set_long_mode(label1, LV_LABEL_LONG_CROP);
  lv_obj_set_width(label1, 400); 
  #if(ERROR_CASE)
  lv_obj_align(label1, lv_scr_act(), LV_ALIGN_CENTER, 10, 45); 
  #else
  lv_obj_align(label1, lv_scr_act(), LV_ALIGN_CENTER, 0, 45); 
  #endif
  lv_label_set_align(label1, LV_LABEL_ALIGN_CENTER); 
}

void SetLabel1Text(const char * text)
{
  lv_label_set_text(label1, text);
}

This looks like an issue with your display driver.

I am not sure what I am doing wrong.
Do you know about any example for 4BPP?

The display works with 4BPP and has 16 shades of gray.
In Lvgl I am using RGB233 and I convert it with set_px_cb.
Could you please take a look at this conversion?

disp_driver.set_px_cb = lv_vdb_wr_bpp4;
...
void lv_vdb_wr_bpp4(lv_disp_drv_t * disp_drv, uint8_t * buf, lv_coord_t buf_w, lv_coord_t x, lv_coord_t y, lv_color_t color, lv_opa_t opa)
{
  (void)opa;
  (void)disp_drv;
  uint8_t brightness_4BPP;

  buf += buf_w / 2 * y; //(buf + ((buf_w * y) / 2))
  buf += x / 2; //buf + (x / 2)

  brightness_4BPP = lv_color_brightness(color) / 17; //[0xFF, 0x0] to [0xF, 0x0]

  if (x % 2 == 0)
  {
    (*buf) = brightness_4BPP << 4;
  }
  else
  {
    (*buf) |= brightness_4BPP;
  }
}

How does your flush_cb look like?

Thank you for your answers guys. I have just figured out the issue. Actually I had two.
The first was what I mentioned above and the second is that the characters’ edge was pixeled.

Solution for the angeled look:

The X coordinate and the X+Width must be the multiplies of 4. If not, then you have to add padding.
I have decided I will just use multiples of 4. The 4 pixel accurate positioning is acceptable. Also If you add padding then you have to send double data.

Solution for the pixeled characters:

I had a mistake in the conversion from 8BPP to 4BPP. You should clear the nibble before OR it.

...
  if (x % 2 == 0)
  {
    (*buf) &= 0xF0;
    (*buf) |= brightness_4BPP;
  }
  else
  {
    (*buf) &= 0x0F;
    (*buf) |= (brightness_4BPP << 4);
  }
...

Glad to hear that!

round_cb might help to handle “non-multiple of 4” positions:
https://docs.littlevgl.com/en/html/porting/display.html#display-driver