2026年2月17日 星期二

[OTTO GO] 動畫測試-LVGL + lv_spinner Loading 動畫



arduino:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <lvgl.h>

// TFT 腳位(保持原樣)
#define TFT_MOSI 19
#define TFT_SCLK 18
#define TFT_CS   5
#define TFT_DC   16
#define TFT_RST  23

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// LVGL v9 需要的緩衝區(大小單位:bytes,不是 pixels)
#define DRAW_BUF_SIZE (240 * 40 * sizeof(lv_color_t))   // 約 19KB,1/10 螢幕
// 緩衝區(v9 用 uint8_t 陣列)
#define DRAW_BUF_SIZE (320 * 240 / 10 * sizeof(lv_color_t))  // 約 1/10 螢幕大小
static uint8_t draw_buf1[DRAW_BUF_SIZE];
static uint8_t draw_buf2[DRAW_BUF_SIZE];  // 雙緩衝更好(防閃爍),RAM 夠的話用

void my_disp_flush(lv_display_t * display, const lv_area_t * area, uint8_t * px_map) {
  uint32_t w = lv_area_get_width(area);
  uint32_t h = lv_area_get_height(area);

  tft.startWrite();
  tft.setAddrWindow(area->x1, area->y1, w, h);
  tft.writePixels((uint16_t *)px_map, w * h, true, false);
  tft.endWrite();

  lv_display_flush_ready(display);
}

void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.println("Starting LVGL v9 + Adafruit ST7789");

  SPI.begin(TFT_SCLK, -1, TFT_MOSI, TFT_CS);
  tft.init(240, 320);           // 你的螢幕解析度(如果 240x240 就改)
  tft.setRotation(1);
  tft.fillScreen(ST77XX_BLACK);

  lv_init();

  // 建立 display(注意寬高依 rotation 調整:寬 320、高 240)
  lv_display_t * disp = lv_display_create(320, 240);

  // 設定緩衝區(PARTIAL 模式最常用,適合小緩衝)
  lv_display_set_buffers(disp, draw_buf1, draw_buf2, DRAW_BUF_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL);

  // 設定 flush callback
  lv_display_set_flush_cb(disp, my_disp_flush);

  // 建立 spinner 測試
  lv_obj_t * spinner = lv_spinner_create(lv_screen_active());
  lv_obj_set_size(spinner, 100, 100);
  lv_obj_center(spinner);
  lv_obj_set_style_arc_width(spinner, 12, 0);
  lv_obj_set_style_arc_color(spinner, lv_color_hex(0x2196F3), LV_PART_INDICATOR);

  Serial.println("Setup complete - spinner should rotate now!");
}

unsigned long last_tick = 0;
void loop() {
  unsigned long now = millis();
  if (now - last_tick >= 5) {
    lv_tick_inc(now - last_tick);   // 更新時間
    lv_timer_handler();
    last_tick = now;
  }
  // delay(1);  // 可選,小 delay 避免 CPU 100%
}

沒有留言:

張貼留言