feat: use lvgl UI library

This commit is contained in:
Fritz Heiden 2025-05-24 14:19:05 +02:00
parent fce458220b
commit 7ab3cd6cc3
4 changed files with 3341 additions and 32 deletions

2132
diagrams/schematic.pdf Normal file

File diff suppressed because it is too large Load Diff

1127
include/lv_conf.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,11 @@ monitor_speed = 115200
lib_deps = lib_deps =
ruiseixasm/Versatile_RotaryEncoder@^1.3.1 ruiseixasm/Versatile_RotaryEncoder@^1.3.1
bodmer/TFT_eSPI@^2.5.43 bodmer/TFT_eSPI@^2.5.43
lvgl/lvgl@^9.2.2
build_flags = build_flags =
-Os -Os
-D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG -DCORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG
-D USER_SETUP_LOADED=1 -DUSER_SETUP_LOADED=1
-DLV_CONF_INCLUDE_SIMPLE
-include $PROJECT_INCLUDE_DIR/TFT_eSPI_Setup_ILI9341_ESP32.h -include $PROJECT_INCLUDE_DIR/TFT_eSPI_Setup_ILI9341_ESP32.h
-include $PROJECT_INCLUDE_DIR/lv_conf.h

View File

@ -1,5 +1,6 @@
#include <Arduino.h> #include <Arduino.h>
#include <Versatile_RotaryEncoder.h> #include <Versatile_RotaryEncoder.h>
#include <lvgl.h>
#include <SPI.h> #include <SPI.h>
#include <TFT_eSPI.h> #include <TFT_eSPI.h>
@ -7,6 +8,9 @@
#define SCREEN_HEIGHT 240 #define SCREEN_HEIGHT 240
#define FONT_SIZE 2 #define FONT_SIZE 2
#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];
const int ONBOARD_LED_PIN = 2; const int ONBOARD_LED_PIN = 2;
const int ANALOG_INPUT_PIN = 34; const int ANALOG_INPUT_PIN = 34;
const int ANALOG_OUTPUT_PIN = 25; const int ANALOG_OUTPUT_PIN = 25;
@ -17,16 +21,24 @@ const int ENCODER_B_PIN = 13;
void handleToneGeneration(void *pvParameters); void handleToneGeneration(void *pvParameters);
void handleInputControls(void *pvParameters); void handleInputControls(void *pvParameters);
void handle_lvgl_logs(lv_log_level_t level, const char *buf);
void handle_pad_inputs(void *pvParameters);
void handle_update_display(void *pvParameters);
void handle_update_values(lv_timer_t *timer);
bool toneOn = false; bool toneOn = false;
int frequency = 220; // A4 int frequency = 220; // A4
String label_text;
Versatile_RotaryEncoder *encoder; Versatile_RotaryEncoder *encoder;
void handlePress(); void handlePress();
void handleRelease(); void handleRelease();
void handleRotate(int8_t rotation); void handleRotate(int8_t rotation);
TFT_eSPI tft = TFT_eSPI(); uint32_t get_time();
lv_obj_t *label;
lv_timer_t *update_values_timer;
void setup() void setup()
{ {
@ -46,35 +58,59 @@ void setup()
xTaskCreate(handleToneGeneration, "handleToneGeneration", 2048, NULL, 1, NULL); xTaskCreate(handleToneGeneration, "handleToneGeneration", 2048, NULL, 1, NULL);
xTaskCreate(handleInputControls, "handleInputContols", 2048, NULL, 1, NULL); xTaskCreate(handleInputControls, "handleInputContols", 2048, NULL, 1, NULL);
xTaskCreate(handle_pad_inputs, "handle_pad_inputs", 2048, NULL, 1, NULL);
tft.init(); lv_init();
tft.setRotation(1); lv_log_register_print_cb(handle_lvgl_logs);
delay(100); lv_tick_set_cb(get_time);
tft.fillScreen(TFT_BLACK); update_values_timer = lv_timer_create(handle_update_values, 5, NULL);
tft.setTextColor(TFT_WHITE, TFT_BLACK); lv_timer_ready(update_values_timer);
int centerX = SCREEN_WIDTH / 2; lv_display_t *display;
int centerY = SCREEN_HEIGHT / 2; display = lv_tft_espi_create(SCREEN_HEIGHT, SCREEN_WIDTH, draw_buf, sizeof(draw_buf));
tft.drawCentreString("Setup complete.", centerX, centerY, FONT_SIZE); lv_display_set_rotation(display, LV_DISPLAY_ROTATION_90);
label = lv_label_create(lv_screen_active());
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
Serial.println("setup complete"); Serial.println("setup complete");
label_text = "Boot complete.";
}
void handle_lvgl_logs(lv_log_level_t level, const char *buf)
{
Serial.printf("LVGL: %s\r\n", buf);
}
uint32_t get_time()
{
return esp_timer_get_time() / 1000;
} }
void loop() void loop()
{ {
int max = 0; lv_timer_handler();
for (int i = 0; i < 100; i++) delay(5);
}
void handle_pad_inputs(void *pvParameters)
{
while (true)
{ {
int value = analogRead(ANALOG_INPUT_PIN); int max = 0;
if (!toneOn && value > 0) for (int i = 0; i < 100; i++)
{ {
toneOn = true; int value = analogRead(ANALOG_INPUT_PIN);
if (!toneOn && value > 0)
{
toneOn = true;
}
if (value > max)
{
max = value;
}
delay(1);
} }
if (value > max)
{
max = value;
}
delay(1);
} }
} }
@ -85,7 +121,7 @@ void handleToneGeneration(void *pvParameters)
{ {
if (toneOn) if (toneOn)
{ {
tone(ANALOG_OUTPUT_PIN, frequency, toneDuration); // tone(ANALOG_OUTPUT_PIN, frequency, toneDuration);
delay(toneDuration); delay(toneDuration);
toneOn = false; toneOn = false;
} }
@ -106,12 +142,7 @@ void handlePress()
{ {
Serial.println("Encoder pressed"); Serial.println("Encoder pressed");
digitalWrite(ONBOARD_LED_PIN, HIGH); digitalWrite(ONBOARD_LED_PIN, HIGH);
label_text = "Button pressed.";
int centerX = SCREEN_WIDTH / 2;
int centerY = SCREEN_HEIGHT / 2;
tft.fillScreen(TFT_BLACK);
tft.drawCentreString("Button pressed.", centerX, centerY, FONT_SIZE);
} }
void handleRelease() void handleRelease()
@ -135,9 +166,25 @@ void handleRotate(int8_t rotation)
Serial.print("Frequency: "); Serial.print("Frequency: ");
Serial.println(frequency); Serial.println(frequency);
int centerX = SCREEN_WIDTH / 2; label_text = "Frequency: " + String(frequency) + "Hz";
int centerY = SCREEN_HEIGHT / 2; }
tft.fillScreen(TFT_BLACK); void handle_update_display(void *pvParameters)
tft.drawCentreString("Frequency: " + String(frequency) + "Hz", centerX, centerY, FONT_SIZE); {
while (true)
{
if (lv_label_get_text(label) != label_text.c_str())
{
lv_label_set_text(label, label_text.c_str());
}
delay(100);
}
}
void handle_update_values(lv_timer_t *timer)
{
if (label != NULL && lv_label_get_text(label) != label_text.c_str())
{
lv_label_set_text(label, label_text.c_str());
}
} }