From 43b70a3ea8880b072db8ca1851b2afb42680cf25 Mon Sep 17 00:00:00 2001 From: Thomas Farstrike Date: Tue, 22 Apr 2025 14:01:11 +0200 Subject: [PATCH] Add LVGLTest --- .../com.example.lvgltest/META-INF/MANIFEST.MF | 2 + apps/com.example.lvgltest/assets/main.py | 117 ++++++++++++++++++ .../res/mipmap-mdpi/launcher_icon.png | Bin 0 -> 6728 bytes 3 files changed, 119 insertions(+) create mode 100644 apps/com.example.lvgltest/META-INF/MANIFEST.MF create mode 100644 apps/com.example.lvgltest/assets/main.py create mode 100644 apps/com.example.lvgltest/res/mipmap-mdpi/launcher_icon.png diff --git a/apps/com.example.lvgltest/META-INF/MANIFEST.MF b/apps/com.example.lvgltest/META-INF/MANIFEST.MF new file mode 100644 index 00000000..9492539b --- /dev/null +++ b/apps/com.example.lvgltest/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Name: LVGLTest diff --git a/apps/com.example.lvgltest/assets/main.py b/apps/com.example.lvgltest/assets/main.py new file mode 100644 index 00000000..b7eb9e45 --- /dev/null +++ b/apps/com.example.lvgltest/assets/main.py @@ -0,0 +1,117 @@ +import lvgl as lv +import time +import random +import display_driver # Replace with your display driver (e.g., ILI9341, ST7796) + +# Configuration +SPRITE_SIZE = 20 # Size of each sprite (rectangle) in pixels +UPDATE_INTERVAL_MS = 100 # Update metrics display and add sprite every 100ms + +# Global variables +sprite_count = 0 +metrics_label = None + +def update_metrics(timer): + """Update on-screen metrics (sprite count).""" + global sprite_count, metrics_label + if metrics_label: + metrics_label.set_text(f"Sprites: {sprite_count}") + +def create_sprite(parent, index): + """Create a single animated sprite (rectangle).""" + sprite = lv.obj(parent) + sprite.set_size(SPRITE_SIZE, SPRITE_SIZE) + sprite.set_style_bg_color(lv.color_hex(random.randint(0, 0xFFFFFF)), 0) + sprite.set_pos(random.randint(0, lv.screen_active().get_width() - SPRITE_SIZE), + random.randint(0, lv.screen_active().get_height() - SPRITE_SIZE)) + + try: + # Create animation for random movement in X + anim = lv.anim_t() + anim.init() + anim.set_var(sprite) + anim.set_time(1000) # Animation duration (ms) + anim.set_repeat_count(lv.ANIM_REPEAT_INFINITE) + x_start = sprite.get_x() + x_end = random.randint(0, lv.screen_active().get_width() - SPRITE_SIZE) + anim.set_values(x_start, x_end) + anim.set_path_cb(lv.anim_t.path_ease_in_out) + # Use direct method call to avoid callback issues + def x_cb(anim, val): + anim.get_var().set_x(val) + anim.set_exec_cb(x_cb) + lv.anim_t.start(anim) + + # Create animation for random movement in Y + anim_y = lv.anim_t() + anim_y.init() + anim_y.set_var(sprite) + anim_y.set_time(1000) + anim_y.set_repeat_count(lv.ANIM_REPEAT_INFINITE) + y_start = sprite.get_y() + y_end = random.randint(0, lv.screen_active().get_height() - SPRITE_SIZE) + anim_y.set_values(y_start, y_end) + anim_y.set_path_cb(lv.anim_t.path_ease_in_out) + def y_cb(anim, val): + anim.get_var().set_y(val) + anim_y.set_exec_cb(y_cb) + lv.anim_t.start(anim_y) + except Exception as e: + print(f"Failed to create animation for sprite {index}: {e}") + sprite.delete() + return None + + return sprite + +def run_benchmark(): + global sprite_count, metrics_label + print("Starting LVGL animation benchmark...") + + # Initialize LVGL and screen + try: + lv.init() + except Exception as e: + print(f"Failed to initialize LVGL: {e}") + return + + scr = lv.screen_active() + scr.set_style_bg_color(lv.color_black(), 0) + + # Create metrics label + metrics_label = lv.label(scr) + metrics_label.set_style_text_color(lv.color_white(), 0) + metrics_label.set_style_bg_color(lv.color_black(), 0) + metrics_label.set_style_bg_opa(lv.OPA.COVER, 0) + metrics_label.set_pos(10, 10) + metrics_label.set_text("Sprites: 0") + + # Create timer for updating metrics and adding sprites + def add_sprite_and_update(timer): + global sprite_count + sprite = create_sprite(scr, sprite_count) + if sprite: + sprite_count += 1 + print(f"Added sprite {sprite_count}") + update_metrics(timer) + + try: + lv.timer_create(add_sprite_and_update, UPDATE_INTERVAL_MS, None) + except Exception as e: + print(f"Failed to create timer: {e}") + return + + # Run indefinitely until user resets the board + try: + while True: + lv.task_handler() + time.sleep_ms(10) # Yield to LVGL tasks + except Exception as e: + print(f"Test failed: {e}") + +if __name__ == "__main__": + try: + run_benchmark() + except Exception as e: + print(f"Error in benchmark: {e}") + + diff --git a/apps/com.example.lvgltest/res/mipmap-mdpi/launcher_icon.png b/apps/com.example.lvgltest/res/mipmap-mdpi/launcher_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f28f284c74819ee21d89cde77605f08f94aa9b98 GIT binary patch literal 6728 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 literal 0 HcmV?d00001