# AIC-EEC API

ไลบรารี Hardware Abstraction Layer และ UI helpers สำหรับ **Embedded Systems and IoT Development**, ภาควิชาวิศวกรรมไฟฟ้า คณะวิศวกรรมศาสตร์ มหาวิทยาลัยบูรพา นี่คือเวอร์ชัน **PC Simulator** — API ตรงกับเวอร์ชัน PSoC Edge E84 ทุกประการ โดยใช้ mock implementation แทนการเข้าถึงฮาร์ดแวร์จริง

> รศ.วิรุฬห์ ศรีบริรักษ์ ภาควิชาวิศวกรรมไฟฟ้า คณะวิศวกรรมศาสตร์ มหาวิทยาลัยบูรพา

***

### โมดูลทั้งหมด <a href="#e0-b9-82-e0-b8-a1-e0-b8-94-e0-b8-b9-e0-b8-a5-e0-b8-97-e0-b8-b1-e0-b9-89-e0-b8-87-e0-b8-ab-e0-b8-a1-e" id="e0-b9-82-e0-b8-a1-e0-b8-94-e0-b8-b9-e0-b8-a5-e0-b8-97-e0-b8-b1-e0-b9-89-e0-b8-87-e0-b8-ab-e0-b8-a1-e"></a>

#### Framework (โครงสร้างพื้นฐาน) <a href="#framework-e0-b9-82-e0-b8-84-e0-b8-a3-e0-b8-87-e0-b8-aa-e0-b8-a3-e0-b9-89-e0-b8-b2-e0-b8-87-e0-b8-9e" id="framework-e0-b9-82-e0-b8-84-e0-b8-a3-e0-b8-87-e0-b8-aa-e0-b8-a3-e0-b9-89-e0-b8-b2-e0-b8-87-e0-b8-9e"></a>

<table><thead><tr><th width="151.1591796875">ไฟล์</th><th>คำอธิบาย</th></tr></thead><tbody><tr><td><code>aic-eec.h/c</code></td><td>UI components กลาง — footer, header, logo, theme, container</td></tr><tr><td><code>aic_layout.h/c</code></td><td>ตัวช่วยจัด layout แบบ Flexbox — row, column, card, gauge, progress bar</td></tr><tr><td><code>aic_event.h/c</code></td><td>ระบบ Event Bus แบบ publish-subscribe — sensor/button/system events</td></tr><tr><td><code>aic_log.h/c</code></td><td>ระบบ Logging — แบ่ง level (Error/Warn/Info/Debug/Verbose), output ทาง printf + LVGL</td></tr></tbody></table>

#### Hardware Abstraction (Mock — จำลองฮาร์ดแวร์) <a href="#hardware-abstraction-mock-e0-b8-88-e0-b8-b3-e0-b8-a5-e0-b8-a-d-e0-b8-87-e0-b8-ae-e0-b8-b2-e0-b8-a3-e" id="hardware-abstraction-mock-e0-b8-88-e0-b8-b3-e0-b8-a5-e0-b8-a-d-e0-b8-87-e0-b8-ae-e0-b8-b2-e0-b8-a3-e"></a>

<table><thead><tr><th width="133.7620849609375">ไฟล์</th><th>คำอธิบาย</th></tr></thead><tbody><tr><td><code>gpio.h/c</code></td><td>ควบคุม LED (RGB), อ่านปุ่มกด, ปรับความสว่าง PWM — เก็บค่าในหน่วยความจำ</td></tr><tr><td><code>sensors.h/c</code></td><td>ADC (5 channels), IMU (BMI270), อุณหภูมิ, CAPSENSE — ข้อมูลจำลอง</td></tr></tbody></table>

#### Signal Processing (ประมวลผลสัญญาณ) <a href="#signal-processing-e0-b8-9b-e0-b8-a3-e0-b8-b0-e0-b8-a1-e0-b8-a7-e0-b8-a5-e0-b8-9c-e0-b8-a5-e0-b8-aa-e" id="signal-processing-e0-b8-9b-e0-b8-a3-e0-b8-b0-e0-b8-a1-e0-b8-a7-e0-b8-a5-e0-b8-9c-e0-b8-a5-e0-b8-aa-e"></a>

<table><thead><tr><th width="143.485107421875">ไฟล์</th><th>คำอธิบาย</th></tr></thead><tbody><tr><td><code>ma_filter.h</code></td><td>Moving average filter (header-only, ค่าเริ่มต้น window = 3 samples)</td></tr><tr><td><code>tilt.h/c</code></td><td>Complementary filter — คำนวณ roll/pitch จาก accelerometer + gyroscope</td></tr><tr><td><code>scope.h/c</code></td><td>สร้างสัญญาณ (sine, square, triangle, sawtooth), FFT</td></tr></tbody></table>

***

### ตัวอย่างการใช้งาน <a href="#e0-b8-95-e0-b8-b1-e0-b8-a7-e0-b8-a-d-e0-b8-a2-e0-b9-88-e0-b8-b2-e0-b8-87-e0-b8-81-e0-b8-b2-e0-b8-a3" id="e0-b8-95-e0-b8-b1-e0-b8-a7-e0-b8-a-d-e0-b8-a2-e0-b9-88-e0-b8-b2-e0-b8-87-e0-b8-81-e0-b8-b2-e0-b8-a3"></a>

#### GPIO — ควบคุม LED และปุ่มกด <a href="#gpio-e0-b8-84-e0-b8-a7-e0-b8-9a-e0-b8-84-e0-b8-b8-e0-b8-a1-led-e0-b9-81-e0-b8-a5-e0-b8-b0-e0-b8-9b-e" id="gpio-e0-b8-84-e0-b8-a7-e0-b8-9a-e0-b8-84-e0-b8-b8-e0-b8-a1-led-e0-b9-81-e0-b8-a5-e0-b8-b0-e0-b8-9b-e"></a>

```c
#include "gpio.h"

aic_gpio_init();                              // เริ่มต้นระบบ GPIO (คืนค่า bool)
aic_gpio_led_set(AIC_LED_RED, true);          // เปิด/ปิด LED
aic_gpio_led_toggle(AIC_LED_GREEN);           // สลับสถานะ LED
aic_gpio_pwm_set_brightness(AIC_LED_BLUE, 50);  // ปรับ PWM 0-100%

bool pressed = aic_gpio_button_read(AIC_BTN_USER);     // อ่านปุ่ม (มี debounce)
bool edge    = aic_gpio_button_was_pressed(AIC_BTN_USER); // ตรวจจับขอบ (กดแล้วเคลียร์)
aic_gpio_button_set_callback(AIC_BTN_USER, my_func);   // ลงทะเบียน callback
```

**LED ที่มี:** `AIC_LED_RED`, `AIC_LED_GREEN`, `AIC_LED_BLUE` **ปุ่มที่มี:** `AIC_BTN_USER` (SW2), `AIC_BTN_USER2` (SW4)

#### Sensors — เซ็นเซอร์ <a href="#sensors-e0-b9-80-e0-b8-8b-e0-b9-87-e0-b8-99-e0-b9-80-e0-b8-8b-e0-b8-a-d-e0-b8-a3-e0-b9-8c" id="sensors-e0-b9-80-e0-b8-8b-e0-b9-87-e0-b8-99-e0-b9-80-e0-b8-8b-e0-b8-a-d-e0-b8-a3-e0-b9-8c"></a>

```c
#include "sensors.h"

aic_sensors_init();                           // เริ่มต้นเซ็นเซอร์ทั้งหมด

// ADC — อ่านค่าแอนะล็อก
uint16_t raw = aic_adc_read(AIC_ADC_CH0);    // ค่าดิบ (0-4095 ที่ 12-bit)
float volts  = aic_adc_read_voltage(AIC_ADC_CH0);  // แรงดัน (0-3.3V)
float temp   = aic_adc_read_temperature();    // อุณหภูมิภายใน (องศา C)

// IMU — ตัวตรวจจับการเคลื่อนไหว (BMI270)
float ax, ay, az;
aic_imu_read_accel(&ax, &ay, &az);           // ความเร่ง (หน่วย g)
float gx, gy, gz;
aic_imu_read_gyro(&gx, &gy, &gz);           // ความเร็วเชิงมุม (deg/s)

aic_imu_data_t data;
aic_imu_read_all(&data);                     // อ่านข้อมูล IMU ทั้งหมดพร้อมกัน
```

**ADC channels:** `AIC_ADC_CH0` (Pot), `CH1`, `CH2`, `CH3`, `AIC_ADC_TEMP`

#### Layout — จัด UI ด้วย LVGL <a href="#layout-e0-b8-88-e0-b8-b1-e0-b8-94-ui-e0-b8-94-e0-b9-89-e0-b8-a7-e0-b8-a2-lvgl" id="layout-e0-b8-88-e0-b8-b1-e0-b8-94-ui-e0-b8-94-e0-b9-89-e0-b8-a7-e0-b8-a2-lvgl"></a>

```c
#include "aic_layout.h"

aic_apply_dark_theme(NULL);                   // ธีมมืดบนหน้าจอปัจจุบัน
lv_obj_t *row  = aic_row_create(parent);      // แถวแนวนอน (flex)
lv_obj_t *col  = aic_col_create(parent);      // คอลัมน์แนวตั้ง (flex)
lv_obj_t *card = aic_card_create(parent, "Title");  // การ์ดพร้อมหัวข้อ
lv_obj_t *val  = aic_value_display_create(parent, "Temp:");  // แสดง label + ค่า
lv_obj_t *bar  = aic_progress_bar_create(parent, "CPU");     // แถบความคืบหน้า
aic_create_footer(parent);                    // footer ลิขสิทธิ์
aic_create_header(parent, "My App");          // header พร้อมชื่อ
```

#### Event Bus — ระบบ Event <a href="#event-bus-e0-b8-a3-e0-b8-b0-e0-b8-9a-e0-b8-9a-event" id="event-bus-e0-b8-a3-e0-b8-b0-e0-b8-9a-e0-b8-9a-event"></a>

```c
#include "aic_event.h"

aic_event_init();

// subscribe รับ event เมื่อกดปุ่ม
aic_event_subscribe(AIC_EVENT_BUTTON_PRESS, my_callback, NULL);

// publish ส่ง event
aic_event_publish_button(AIC_BTN_USER, true);    // event ปุ่มกด
aic_event_publish_adc(0, raw_value, voltage_mv); // event ADC

// ประมวลผล event queue (ต้องเรียกเป็นระยะบน PC)
aic_event_process();
```

**กลุ่ม Event ที่สำคัญ:**

* Sensor: `AIC_EVENT_IMU_UPDATE`, `AIC_EVENT_ADC_UPDATE`, `AIC_EVENT_TEMP_UPDATE`
* Input: `AIC_EVENT_BUTTON_PRESS`, `AIC_EVENT_BUTTON_RELEASE`
* System: `AIC_EVENT_IPC_CONNECTED`, `AIC_EVENT_ERROR`
* Custom: `AIC_EVENT_CUSTOM_1` ถึง `AIC_EVENT_CUSTOM_5`

#### Logging — ระบบบันทึกข้อความ <a href="#logging-e0-b8-a3-e0-b8-b0-e0-b8-9a-e0-b8-9a-e0-b8-9a-e0-b8-b1-e0-b8-99-e0-b8-97-e0-b8-b6-e0-b8-81-e0" id="logging-e0-b8-a3-e0-b8-b0-e0-b8-9a-e0-b8-9a-e0-b8-9a-e0-b8-b1-e0-b8-99-e0-b8-97-e0-b8-b6-e0-b8-81-e0"></a>

```c
#include "aic_log.h"

aic_log_init();
aic_log_set_level(AIC_LOG_DEBUG);   // กำหนด level ต่ำสุดที่จะแสดง

AIC_LOGE("Error: %s", msg);        // ข้อผิดพลาด (สีแดง)
AIC_LOGW("Warning: %d", val);      // คำเตือน (สีเหลือง)
AIC_LOGI("Info: started");         // ข้อมูลทั่วไป
AIC_LOGD("Debug: x=%f", x);       // ดีบัก (สำหรับพัฒนา)
AIC_LOGV("Verbose: detail");      // รายละเอียดทั้งหมด
```

***

### เปรียบเทียบ PC Simulator กับ PSoC Edge E84 <a href="#e0-b9-80-e0-b8-9b-e0-b8-a3-e0-b8-b5-e0-b8-a2-e0-b8-9a-e0-b9-80-e0-b8-97-e0-b8-b5-e0-b8-a2-e0-b8-9a-p" id="e0-b9-80-e0-b8-9b-e0-b8-a3-e0-b8-b5-e0-b8-a2-e0-b8-9a-e0-b9-80-e0-b8-97-e0-b8-b5-e0-b8-a2-e0-b8-9a-p"></a>

<table><thead><tr><th width="133.0198974609375">ด้าน</th><th width="271.16900634765625">PC Simulator</th><th>PSoC Edge E84</th></tr></thead><tbody><tr><td><strong>API</strong></td><td>เหมือนกันทุกประการ</td><td>เหมือนกันทุกประการ</td></tr><tr><td><strong>GPIO</strong></td><td>เก็บค่าในหน่วยความจำ</td><td>ควบคุม GPIO pin จริง</td></tr><tr><td><strong>ADC</strong></td><td>ค่าจำลอง</td><td>SAR ADC จริง</td></tr><tr><td><strong>IMU</strong></td><td>สร้างข้อมูล sine wave</td><td>อ่านจาก BMI270 ผ่าน shared memory</td></tr><tr><td><strong>CAPSENSE</strong></td><td>stub (คืนค่า false เสมอ)</td><td>อ่านจาก PSoC 4000T ผ่าน I2C</td></tr><tr><td><strong>Event Bus</strong></td><td>circular buffer (single-thread)</td><td>FreeRTOS queue (multi-thread)</td></tr><tr><td><strong>Logging</strong></td><td>printf ไปที่ terminal</td><td>printf + ส่ง IPC ไปยัง CM33</td></tr></tbody></table>

#### ฟังก์ชันเฉพาะ PC Simulator <a href="#e0-b8-9f-e0-b8-b1-e0-b8-87-e0-b8-81-e0-b9-8c-e0-b8-8a-e0-b8-b1-e0-b8-99-e0-b9-80-e0-b8-89-e0-b8-9e-e" id="e0-b8-9f-e0-b8-b1-e0-b8-87-e0-b8-81-e0-b9-8c-e0-b8-8a-e0-b8-b1-e0-b8-99-e0-b9-80-e0-b8-89-e0-b8-9e-e"></a>

ฟังก์ชันเหล่านี้ใช้ได้เฉพาะบน PC สำหรับจำลองการทดสอบ:

```c
// จำลองการกดปุ่มจาก UI/keyboard
aic_gpio_sim_set_button(AIC_BTN_USER, true);

// ตั้งค่าเซ็นเซอร์จำลอง
aic_sensors_sim_set_adc(AIC_ADC_CH0, 75);      // ตั้ง ADC เป็น 75%
aic_sensors_sim_tick();                          // เคลื่อนไหว IMU อัตโนมัติ
aic_imu_set_simulated_accel(0.0f, 0.0f, 1.0f); // ตั้งค่าเฉพาะเจาะจง
```

***

### วิธี Build (PC Simulator) <a href="#e0-b8-a7-e0-b8-b4-e0-b8-98-e0-b8-b5-build-pc-simulator" id="e0-b8-a7-e0-b8-b4-e0-b8-98-e0-b8-b5-build-pc-simulator"></a>

[#id-3](https://docs.aic-eec.com/interfacing-with-infineon-psoc-tm-edge/hmi-development/..#id-3 "mention")

***

### ชุดสี (กำหนดใน aic\_layout.h) <a href="#e0-b8-8a-e0-b8-b8-e0-b8-94-e0-b8-aa-e0-b8-b5-e0-b8-81-e0-b8-b3-e0-b8-ab-e0-b8-99-e0-b8-94-e0-b9-83-e" id="e0-b8-8a-e0-b8-b8-e0-b8-94-e0-b8-aa-e0-b8-b5-e0-b8-81-e0-b8-b3-e0-b8-ab-e0-b8-99-e0-b8-94-e0-b9-83-e"></a>

<table><thead><tr><th width="220.92828369140625">Macro</th><th width="202.55963134765625">สี</th><th>การใช้งาน</th></tr></thead><tbody><tr><td><code>AIC_COLOR_BG_DARK</code></td><td><code>#16213e</code></td><td>พื้นหลังหน้าจอ</td></tr><tr><td><code>AIC_COLOR_BG_CARD</code></td><td><code>#1f4068</code></td><td>พื้นหลังการ์ด</td></tr><tr><td><code>AIC_COLOR_PRIMARY</code></td><td><code>#00d4ff</code></td><td>สีหลัก</td></tr><tr><td><code>AIC_COLOR_SECONDARY</code></td><td><code>#ff6b6b</code></td><td>สีรอง</td></tr><tr><td><code>AIC_COLOR_SUCCESS</code></td><td><code>#4ade80</code></td><td>สถานะสำเร็จ</td></tr><tr><td><code>AIC_COLOR_WARNING</code></td><td><code>#fbbf24</code></td><td>สถานะเตือน</td></tr><tr><td><code>AIC_COLOR_ERROR</code></td><td><code>#ef4444</code></td><td>สถานะข้อผิดพลาด</td></tr><tr><td><code>AIC_COLOR_TEXT</code></td><td><code>#ffffff</code></td><td>ข้อความปกติ</td></tr><tr><td><code>AIC_COLOR_TEXT_DIM</code></td><td><code>#94a3b8</code></td><td>ข้อความจางๆ</td></tr></tbody></table>

***

### การย้ายโค้ดจาก PC ไปบอร์ดจริง <a href="#e0-b8-81-e0-b8-b2-e0-b8-a3-e0-b8-a2-e0-b9-89-e0-b8-b2-e0-b8-a2-e0-b9-82-e0-b8-84-e0-b9-89-e0-b8-94-e" id="e0-b8-81-e0-b8-b2-e0-b8-a3-e0-b8-a2-e0-b9-89-e0-b8-b2-e0-b8-a2-e0-b9-82-e0-b8-84-e0-b9-89-e0-b8-94-e"></a>

เนื่องจาก API เหมือนกัน 100% การย้ายโค้ดทำได้ง่าย:

1. **คัดลอกโค้ด** จาก PC Simulator ไปใส่ในโปรเจค PSoC Edge
2. **เปลี่ยน include path** — `"lvgl/lvgl.h"` เป็น `"lvgl.h"` (ถ้าจำเป็น)
3. **ลบฟังก์ชัน sim** — ลบ `aic_gpio_sim_set_button()`, `aic_sensors_sim_tick()` ฯลฯ
4. **Build และทดสอบ** บนบอร์ดจริง

ไม่ต้องเปลี่ยนชื่อฟังก์ชัน, ชนิดข้อมูล, หรือ parameter ใดๆ ทั้งสิ้น

***
