Hi, Nordic Team and Community!
I'm trying to develop a display that shows information dynamically. Each information will shown in the display for about 2 seconds and then move to another, as in pages, each page showing a different information.
But to make this happen I need to use the lv_tick_inc to track time in the code, according to LGVL library docs. But when I call this function, and only this function the compiler shows an "undefined reference to this function", but I don't know why, as IntelliSense C/C++ can open its definition of this function in the correct path.
Looking into the library code, enabling a Kconfig like LV_TICK_CUSTOM appears necessary as I'm doing. But the problem remains.
The display I'm using is a SSD1306 128x64p, there is a reason to create this. And when I build to show only one page it does normally. So the problem isn't the library itself. I guess I'm missing some configuration but I don't know where to look it anymore.
My dev setup: NCS v2.5.0 for vscode.
macOS 14.3.1
Here is my code and my prj.conf to this part of the display for my project.
Any help on this I'm grateful!
Best Regards.
#include "display.h" //calling also lvgl.h #include <zephyr/kernel.h> #include <zephyr/device.h> #include <zephyr/devicetree.h> #include <zephyr/drivers/display.h> #include <zephyr/logging/log.h> LOG_MODULE_REGISTER(display, LOG_LEVEL_DBG); #include "common.h" #define NUMBER_OF_PAGES 4 /* Fecth display device from Devicetree */ const struct device *display_dev; /* Setup timer for page switching */ static void lv_tick_handler(struct k_timer *timer_id); static void update_display_page(lv_timer_t *timer); K_TIMER_DEFINE(lvgl_tick, lv_tick_handler, NULL); static void lv_tick_handler(struct k_timer *timer_id) { lv_tick_inc(K_MSEC(2)); //Call this every 2 milliseconds. } static void update_display_page(lv_timer_t *timer) { static uint8_t current_page = 0; current_page = (current_page + 1) % NUMBER_OF_PAGES; lv_obj_clean(lv_scr_act()); // Clean the current screen. switch (current_page) { case 0: display_channel_levels(); break; case 1: display_lte_status(); break; case 2: display_mqtt_status(); break; case 3: display_soil_temperature(); break; default: break; } lv_task_handler(); // Tell LVGL that tick happened. } /* Display init function */ void display_init(void) { display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); if (!device_is_ready(display_dev)) { LOG_ERR("Device not ready, aborting test"); return; } // Initialize LVGL library lv_init(); // Start the LVGL timer lv_timer_create(update_display_page, 2000, NULL); // Start the Zeohyr timer for LVGL tick increment k_timer_start(&lvgl_tick, K_MSEC(2), K_MSEC(2)); // lv_obj_t *label = lv_label_create(lv_scr_act()); // lv_label_set_text(label, "TLAMP"); // lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 0); // Update the display //lv_task_handler(); return; } /* Page Functions */ void display_lte_status(void) { lv_obj_t *label = lv_label_create(lv_scr_act()); lv_label_set_text(label, true ? "LTE: Connected" : "LTE: Disconnected"); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); } void display_channel_levels(void) { // Example for one channel, repeat for others lv_obj_t *label = lv_label_create(lv_scr_act()); char text[64]; sprintf(text, "CH1: %d%%", 10); lv_label_set_text(label, text); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); // Position other labels accordingly } void display_soil_temperature(void) { lv_obj_t *label = lv_label_create(lv_scr_act()); char text[64]; snprintf(text, sizeof(text),"Soil Temp: %.2f°C", 20.00); lv_label_set_text(label, text); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); } void display_mqtt_status(void) { lv_obj_t *label = lv_label_create(lv_scr_act()); lv_label_set_text(label, true ? "MQTT: Connected" : "MQTT: Disconnected"); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); }
the prj.conf
# Display Options CONFIG_I2C=y CONFIG_DISPLAY=y CONFIG_SSD1306=y CONFIG_SSD1306_SH1106_COMPATIBLE=y CONFIG_SSD1306_DEFAULT=y CONFIG_SSD1306_REVERSE_MODE=y #lvgl CONFIG_LVGL=y CONFIG_LV_MEM_CUSTOM=y CONFIG_LV_USE_LABEL=y CONFIG_LV_USE_CANVAS=y CONFIG_LV_USE_LOG=y CONFIG_LV_TICK_CUSTOM=y CONFIG_LV_DPI_DEF=148 CONFIG_LV_Z_BITS_PER_PIXEL=1 CONFIG_LV_COLOR_DEPTH_1=y #CONFIG_LV_FONT_DEFAULT_MONTSERRAT_12=y CONFIG_LV_FONT_MONTSERRAT_8=y CONFIG_LV_Z_MEM_POOL_NUMBER_BLOCKS=8