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