C in ModusToolBox (MTB)

1. ภาพรวมของ LVGL

LVGL คืออะไร?

LVGL (Light and Versatile Graphics Library) เป็น Open-source Graphics Library สำหรับระบบ Embedded ที่ต้องการสร้าง UI บนหน้าจอ

┌─────────────────────────────────────────────────────────────┐
│                    Application Layer                        │
│              (Your Code - GPIO, ADC, Sensors)               │
├─────────────────────────────────────────────────────────────┤
│                      LVGL Library                           │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐            │
│  │ Widgets │ │ Events  │ │ Styles  │ │Animation│            │
│  └─────────┘ └─────────┘ └─────────┘ └─────────┘            │
├─────────────────────────────────────────────────────────────┤
│                    Display Driver                           │
│              (Frame Buffer, VG-Lite GPU)                    │
├─────────────────────────────────────────────────────────────┤
│                      Hardware                               │
│              (LCD Display, Touch Panel)                     │
└─────────────────────────────────────────────────────────────┘

2. สถาปัตยกรรมของ LVGL

2.1 Object Model

องค์ประกอบ
คำอธิบาย
ตัวอย่าง

Screen

หน้าจอหลัก (Container สูงสุด)

lv_screen_active()

Object

วัตถุพื้นฐาน (Base class)

lv_obj_t *

Widget

วัตถุที่มี function เฉพาะทาง

Button, Label, Slider

Part

ส่วนประกอบย่อยของ Widget

MAIN, INDICATOR, KNOB

State

สถานะของ Object

DEFAULT, PRESSED, CHECKED

WHY: ทำไมต้องเข้าใจ Object Model?

  • UI ทุกตัวใน LVGL เป็น Object ที่มี Parent-Child relationship

  • การจัดการ Memory และ Layout ขึ้นอยู่กับโครงสร้างนี้

  • Event จะ propagate ตาม hierarchy

HOW: การประยุกต์ใช้จริง

CAUTION: ข้อควรระวัง

  • ห้าม delete parent ก่อน children (จะ crash)

  • Object ที่สร้างแล้วจะถูก LVGL จัดการ Memory (ห้าม free เอง)

  • Screen เดียวกันไม่ควรมี Object เกิน ~100 ตัว (performance)


3. Basic Widgets

3.1 Label - แสดงข้อความ

ตัวอย่างจาก: examples/get_started/lv_example_get_started_1.c

Function
หน้าที่
Parameter

lv_label_create()

สร้าง Label widget

parent object

lv_label_set_text()

ตั้งค่าข้อความ

object, string

lv_label_set_text_fmt()

ตั้งค่าข้อความแบบ format

object, format, ...

lv_obj_align()

จัดตำแหน่ง

object, alignment, x_offset, y_offset

WHY: ทำไม Label สำคัญ?

  • ใช้แสดงค่าจาก Sensor (ADC, IMU, Temperature)

  • Debug output บนหน้าจอแทน UART

  • Status message ให้ผู้ใช้

CAUTION: ข้อควรระวัง Label

  • ข้อความยาวเกินไปจะ overflow (ใช้ lv_label_set_long_mode())

  • lv_label_set_text() จะ copy string ทุกครั้ง (memory allocation)

  • ใช้ lv_label_set_text_static() ถ้า string เป็น constant


3.2 Button - ปุ่มกด

ตัวอย่างจาก: examples/get_started/lv_example_get_started_2.c

WHY: ทำไม Button สำคัญ?

  • เป็น input หลักสำหรับ user interaction

  • ใช้ควบคุม GPIO (ON/OFF LED, Motor)

  • Trigger การทำงานต่างๆ (Start measurement, Reset)

HOW: เชื่อมโยงกับ GPIO จากสัปดาห์ที่ 1


3.3 Switch - สวิตช์เปิด/ปิด

ตัวอย่างจาก: examples/widgets/switch/lv_example_switch_1.c

WHY: ทำไม Switch เหมาะกับ GPIO?

  • แสดงสถานะ ON/OFF ชัดเจน

  • เหมาะกับการควบคุม Binary Output (LED, Relay, Motor)

  • User-friendly กว่า Button สำหรับ toggle state


3.4 LED Widget - แสดงสถานะ

ตัวอย่างจาก: examples/widgets/led/lv_example_led_1.c

Function
หน้าที่

lv_led_create()

สร้าง LED widget

lv_led_on()

เปิด LED (สว่างสุด)

lv_led_off()

ปิด LED (มืด)

lv_led_set_brightness()

ตั้งความสว่าง 0-255

lv_led_set_color()

ตั้งสี

WHY: ทำไมต้องมี Virtual LED?

  • แสดงสถานะ Hardware LED บนหน้าจอ

  • ใช้เมื่อ Physical LED ไม่พอ

  • สื่อสาร Status ให้ผู้ใช้ (Error, Warning, OK)


4. Event Handling

4.1 Event Callback Pattern

4.2 Event Types ที่สำคัญ

Event Code
เมื่อไหร่ถูกเรียก
ใช้กับ Widget

LV_EVENT_CLICKED

Click (Press + Release)

Button, Image

LV_EVENT_VALUE_CHANGED

ค่าเปลี่ยน

Slider, Switch, Arc

LV_EVENT_PRESSED

กดค้าง

ทุก Object

LV_EVENT_LONG_PRESSED

กดค้างนาน (>400ms)

ทุก Object

LV_EVENT_RELEASED

ปล่อย

ทุก Object

WHY: ทำไม Event-Driven สำคัญ?

  • ไม่ต้อง Polling สถานะ (ประหยัด CPU)

  • แยก Logic ออกจาก UI (Maintainable)

  • รองรับ Multiple Events บน Object เดียว

HOW: ส่ง User Data ผ่าน Event

CAUTION: ข้อควรระวัง Event

  • User Data ต้อง valid ตลอด lifetime ของ Object

  • ห้ามใช้ local variable เป็น User Data (จะหาย)

  • หลาย Event อาจเกิดพร้อมกัน (ต้องกรองด้วย code)

Functions สำหรับการวางตำแหน่ง (LVGL v9.2 API)

Functions สำหรับการกำหนดขนาด (Size Functions)

Layout Pattern สำหรับ 480x320 Screen

Pattern 1: Vertical Stacking (ใช้บ่อยที่สุด)

Pattern 2: Multiple Widgets at CENTER with Y-offset

Pattern 3: Container with Grid Layout

Widget Sizing Guidelines (แนะนำสำหรับ 480x320)

Widget Type
Recommended Size
Notes

Title Label

Auto (text length)

Font: montserrat_24

Button

Padding 30x15

ใช้ padding แทน set_size

LED

40x40 to 80x80

ขึ้นกับความสำคัญ

Switch

60x30 to 80x40

Default size ก็ใช้ได้

Slider

Width 200-300

Height auto

Bar

300x25

ปรับ width ตาม layout

Arc

140x140 to 200x200

ควรเป็น square

Chart

400x260 max

ลดถ้ามี labels ด้านข้าง

Container

420x200 typical

สำหรับ dashboard 4 items

Common Background Colors (จาก Course Examples)

CAUTION: ข้อควรระวังในการวาง Layout

  1. ห้ามวาง Widget นอกขอบจอ: ค่า y ที่เกิน 319 หรือ x ที่เกิน 479 จะทำให้ widget หายไป

  2. ลำดับการสร้างสำคัญ: Widget ที่สร้างทีหลังจะอยู่ด้านบน (z-order)

  3. align_to ต้องทำหลัง base object ถูก position แล้ว:

  4. ใช้ padding แทน set_size สำหรับ Button:

  5. Container ควรปิด scroll flag:

Last updated

Was this helpful?