Button Status

Lab 7: Hardware Button Status

1. โครงสร้างภาพรวมของ Lab

Why? - ทำไมต้องเรียนรู้เรื่องนี้

การอ่านสถานะปุ่มกดเป็นพื้นฐานสำคัญของ Embedded System:

  • Physical Input: รับ input จากผู้ใช้ผ่านปุ่มจริงบนบอร์ด

  • Polling Pattern: เรียนรู้ Timer-based polling สำหรับอ่าน Hardware

  • Debouncing: เข้าใจปัญหา Mechanical Bounce และวิธีกรอง

  • Active Low Logic: เข้าใจ Hardware logic ของปุ่มกดแบบ Pull-up

  • Industrial Use Case: Emergency Stop, Mode Select, Start/Stop buttons

What? - จะได้เรียนรู้อะไร

  1. Button API: aic_gpio_button_read_raw(AIC_BTN_USER) อ่านปุ่มจริง

  2. Timer Polling: ใช้ lv_timer_create() อ่านสถานะทุก 50ms

  3. Active Low Logic: ปุ่มกด = return 0, ปล่อย = return 1

  4. Debounce Technique: กรอง noise จาก mechanical switch

  5. UI Feedback: แสดง LED widget + Label เปลี่ยนสีตามสถานะปุ่ม

How? - ทำอย่างไร

  1. Initialize GPIO ด้วย aic_gpio_init()

  2. สร้าง LVGL Timer ที่ poll ทุก 50ms

  3. ใน timer callback อ่านสถานะปุ่มด้วย aic_gpio_button_read_raw()

  4. อัพเดท UI ตามสถานะ: LED widget + Label + สีพื้นหลัง


2. หลักการทำงาน (Technical Principles)

2.1 Button Hardware Configuration

2.2 Timer Polling Architecture

2.3 Mechanical Bounce Problem

2.4 UI Layout


3. ฟังก์ชันสำคัญ (API Reference)

3.1 Button Hardware API (aic-eec.h)

Function
Returns
Description

aic_gpio_init()

void

Initialize GPIO (เรียกครั้งเดียว)

aic_gpio_button_read_raw(btn)

int

อ่านค่าดิบ: 0=Pressed, 1=Released

3.2 Button Constants

3.3 LVGL Timer API

Function
Description

lv_timer_create(cb, period_ms, user_data)

สร้าง periodic timer

lv_timer_delete(timer)

ลบ timer

lv_timer_set_period(timer, new_ms)

เปลี่ยน period

lv_timer_reset(timer)

Reset countdown

3.4 LVGL Functions ที่ใช้ในบทนี้

Function
Description

lv_led_create(parent)

สร้าง LED indicator widget

lv_led_on(led) / lv_led_off(led)

เปิด/ปิด LED indicator

lv_led_set_color(led, color)

ตั้งสี LED

lv_label_set_text(label, text)

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

lv_label_set_text_fmt(label, fmt, ...)

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

lv_obj_set_style_text_color(obj, color, 0)

เปลี่ยนสีข้อความ


4. โค้ดตัวอย่าง (Code Examples)

4.1 Minimal Example: Read Button and Update Label

4.2 Full Example: Button Status with Debounce + Press Counter

4.3 อธิบายโค้ดทีละขั้นตอน

ขั้นตอน
โค้ด
คำอธิบาย

1

aic_gpio_init()

เริ่มต้น GPIO subsystem

2

lv_timer_create(poll_btn_cb, 50, NULL)

สร้าง timer poll ทุก 50ms

3

aic_gpio_button_read_raw(AIC_BTN_USER)

อ่านค่าดิบ (0=pressed)

4

Debounce check

นับค่าเดิมติดกัน 3 ครั้ง = เสถียร

5

Edge detection

stable && !prev = just pressed, นับ press

6

lv_led_on/off() + lv_label_set_text()

อัพเดท UI ตามสถานะ


5. องค์ความรู้และเทคนิค

5.1 Pattern: Hardware Polling with LVGL Timer

5.2 Pattern: Edge Detection (ตรวจจับจังหวะกด)

5.3 Pattern: Simple Debounce

5.4 สิ่งที่ต้องระวัง

หัวข้อ
รายละเอียด

Active Low

read_raw() คืน 0 เมื่อกด, 1 เมื่อปล่อย -- กลับจากสัญชาตญาณ

LVGL Thread Safety

อัพเดท UI ได้เฉพาะใน LVGL context (timer callback, event callback)

Timer Period

50ms เป็นค่าที่ดี: เร็วพอสำหรับ UI, ช้าพอไม่กิน CPU

Debounce

ไม่ debounce = นับ press ผิด, ค่า flicker

Static Variables

ตัวแปร state ต้องเป็น static เพราะ callback ถูกเรียกซ้ำหลายครั้ง

5.5 Application ในอุตสาหกรรม

  • Emergency Stop: ปุ่มหยุดฉุกเฉินในโรงงาน ต้อง debounce + edge detect

  • Mode Selection: ปุ่มเลือกโหมดทำงาน (Manual/Auto/Service)

  • Counting: นับจำนวนชิ้นงานที่ผ่าน sensor (press = detect)


6. แบบฝึกหัด (Exercises)

แบบฝึกหัดที่ 1: Press Counter with Long-Press Detection

โจทย์: สร้างระบบนับการกดปุ่มที่แยก Short Press กับ Long Press

ข้อกำหนด:

  • Short Press (กดน้อยกว่า 1 วินาที): เพิ่ม counter +1

  • Long Press (กดค้าง >= 1 วินาที): Reset counter เป็น 0

  • แสดงสถานะ: "Short Press!" (สีเขียว) / "Long Press - Reset!" (สีแดง)

  • แสดง Press Duration ขณะกดค้างอยู่ (เช่น "Holding: 0.8s")

  • LED indicator เปลี่ยนสีตามระยะเวลากด (เขียว -> เหลือง -> แดง)

Hints:

  • ใช้ตัวแปร static uint32_t press_start_tick = 0; เก็บเวลาเริ่มกด

  • lv_tick_get() ได้ค่า milliseconds ปัจจุบัน

  • Long press threshold = 1000ms (20 timer ticks x 50ms)

แบบฝึกหัดที่ 2: Button-Triggered LED Toggle with Visual Feedback

โจทย์: กดปุ่ม USER แต่ละครั้ง ให้สลับสถานะ LED ตามลำดับ

ข้อกำหนด:

  • กดครั้งที่ 1: Red LED ON

  • กดครั้งที่ 2: Red OFF + Green LED ON

  • กดครั้งที่ 3: Green OFF + Blue LED ON

  • กดครั้งที่ 4: ปิดหมด แล้วกลับไปครั้งที่ 1

  • แสดงสถานะบนจอ: LED ตัวไหนติด + หมายเลขครั้งที่กด

  • LVGL LED indicators 3 ตัว แสดงสถานะตรงกับ Hardware LED

Hints:

  • ใช้ static int led_mode = 0; และ led_mode = (led_mode + 1) % 4;

  • ใช้ Edge Detection เพื่อนับเฉพาะจังหวะกดลง

Last updated

Was this helpful?