I change the variable after the event, but it does not print correctly on the screen.
Board Nucleo. MCU STM32F446RE.
LVGL version 8.0.2.
What am I doing wrong?
Help me please!
After the event, the text moves up slightly.
void my_event_cb(lv_event_t *e)
{
static unsigned int cnt = 101;
lv_obj_t *label = lv_event_get_user_data(e);
lv_label_set_text_fmt(label, "%d", cnt);
cnt++;
}
lv_obj_t *buildFrameTemperature(void)
{
lv_obj_t *frame_display = lv_obj_create(NULL);
lv_obj_set_size(frame_display, 128, 64);
lv_obj_set_align(frame_display, LV_ALIGN_TOP_LEFT);
LV_IMG_DECLARE(icons8_temp_64x64);
lv_obj_t *imageTemperature = lv_img_create(frame_display);
lv_img_set_src(imageTemperature, &icons8_temp_64x64);
lv_obj_set_align(imageTemperature, LV_ALIGN_LEFT_MID);
lv_obj_t *label1 = lv_label_create(frame_display);
lv_obj_set_align(label1, LV_ALIGN_TOP_RIGHT);
lv_label_set_text(label1, "Temperature");
lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_RIGHT, 0);
lv_obj_t *label2 = lv_label_create(frame_display);
lv_obj_set_align(label2, LV_ALIGN_BOTTOM_RIGHT);
lv_label_set_text(label2, "100");
lv_obj_set_style_text_align(label2, LV_TEXT_ALIGN_RIGHT, 0);
lv_obj_add_event_cb(frame_display, my_event_cb, LV_EVENT_CLICKED, label2);
return frame_display;
}
Screenshot
After pressing the button
Solution.
The problem was in the rendering functions.
This article helped.
LittlevGL on a Monochrome OLED
All the code for initializing and working with the display.
#define SSD1306_HEIGHT 64
#define SSD1306_WIDTH 128
#define SSD1306_BUFFER_SIZE ((SSD1306_WIDTH * SSD1306_HEIGHT) / 8)
#define BIT_SET(a, b) ((a) |= (1U << (b)))
#define BIT_CLEAR(a, b) ((a) &= ~(1U << (b)))
static void flush_cb(struct _lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
/*The most simple case (but also the slowest) to put all pixels to the screen one-by-one*/
uint8_t row1 = area->y1 >> 3;
uint8_t row2 = area->y2 >> 3;
uint8_t *buf = (uint8_t *)color_p;
for (uint8_t row = row1; row <= row2; row++)
{
writeCommandSsd1306(0xB0 | row); // Set the page start address
writeCommandSsd1306(0x00 | (area->x1 & 0xF)); // Set the lower start column address
writeCommandSsd1306(0x10 | ((area->x1 >> 4) & 0xF)); // Set the upper start column address
for (uint16_t x = area->x1; x <= area->x2; x++)
{
writeDataSsd1306(buf, 1);
buf++;
}
}
/* IMPORTANT!!!
* Inform the graphics library that you are ready with the flushing. */
lv_disp_flush_ready(disp_drv);
}
static void set_px_cb(struct _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)disp_drv;
(void)opa;
uint16_t byte_index = x + ((y >> 3) * buf_w);
uint8_t bit_index = y & 0x7;
// == 0 inverts, so we get blue on black
if (color.full == 0)
{
BIT_SET(buf[byte_index], bit_index);
}
else
{
BIT_CLEAR(buf[byte_index], bit_index);
}
}
static void rounder_cb(struct _lv_disp_drv_t *disp_drv, lv_area_t *area)
{
(void)disp_drv;
area->y1 = (area->y1 & (~0x7));
area->y2 = (area->y2 & (~0x7)) + 7;
}
static void lv_port_disp_init(void)
{
static lv_disp_draw_buf_t draw_buf; /* Descriptor of a display buffer */
static lv_color_t screenBuffer1[SSD1306_BUFFER_SIZE]; /* Memory area used as display buffer */
static lv_color_t screenBuffer2[SSD1306_BUFFER_SIZE]; /* Memory area used as display buffer */
lv_disp_draw_buf_init(&draw_buf, screenBuffer1, screenBuffer2, SSD1306_BUFFER_SIZE); /* Initialize the display buffer */
/*-----------------------------------
* Register the display in LVGL
*----------------------------------*/
static lv_disp_drv_t disp_drv_ssd1306; /* Descriptor of a display driver */
lv_disp_drv_init(&disp_drv_ssd1306); /* Basic initialization */
/*Set up the functions to access to your display*/
/*Set the resolution of the display*/
disp_drv_ssd1306.hor_res = SSD1306_WIDTH; /** < Horizontal resolution */
disp_drv_ssd1306.ver_res = SSD1306_HEIGHT; /** < Vertical resolution */
disp_drv_ssd1306.full_refresh = 1; /** < 1: Always make the whole screen redrawn */
disp_drv_ssd1306.rotated = LV_DISP_ROT_NONE; /** < 1: turn the display by 90 degree. Does not update coordinates for you! */
/* Used to copy the buffer's content to the display */
disp_drv_ssd1306.flush_cb = flush_cb; /** < Write the internal buffer (draw_buf) to the display */
disp_drv_ssd1306.rounder_cb = rounder_cb;
disp_drv_ssd1306.set_px_cb = set_px_cb;
/* Set a display buffer */
disp_drv_ssd1306.draw_buf = &draw_buf;
/* Finally register the driver */
lv_disp_drv_register(&disp_drv_ssd1306);
}