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
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
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 ที่สำคัญ
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)
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
ห้ามวาง Widget นอกขอบจอ: ค่า y ที่เกิน 319 หรือ x ที่เกิน 479 จะทำให้ widget หายไป
ลำดับการสร้างสำคัญ: Widget ที่สร้างทีหลังจะอยู่ด้านบน (z-order)
align_to ต้องทำหลัง base object ถูก position แล้ว:
ใช้ padding แทน set_size สำหรับ Button:
Container ควรปิด scroll flag:
Last updated
Was this helpful?