# พื้นฐาน Embedded C - ตอนที่ 3

## C Programming - Control Flow

### 1. Conditional Statements (if-else)

**ทำไมต้องใช้?** ตัดสินใจตาม sensor input, user action, states

```c
int16_t temperature = 28;

/* Simple if */
if (temperature > 30)
{
    printf("Hot!\r\n");
}

/* if-else */
if (temperature > 30)
{
    set_led_color(RED);
}
else
{
    set_led_color(GREEN);
}

/* if-else if-else */
if (temperature > 35)
{
    printf("Very Hot!\r\n");
    set_led_color(RED);
}
else if (temperature > 30)
{
    printf("Hot\r\n");
    set_led_color(YELLOW);
}
else if (temperature < 15)
{
    printf("Cold\r\n");
    set_led_color(BLUE);
}
else
{
    printf("Normal\r\n");
    set_led_color(GREEN);
}
```

**Common Patterns:**

```c
/* Error checking */
cy_rslt_t result = cyhal_gpio_init(/* ... */);
if (result != CY_RSLT_SUCCESS)
{
    printf("Init failed!\r\n");
    return result;  /* Early return */
}

/* Null check */
void process_data(imu_data_t *data)
{
    if (data == NULL)
    {
        printf("Error: NULL pointer\r\n");
        return;
    }
    /* Safe to use */
    printf("X: %d\r\n", data->acc_x);
}

/* Range validation */
void set_brightness(int level)
{
    if (level < 0 || level > 100)
    {
        printf("Invalid level\r\n");
        return;
    }
    /* Apply brightness */
}
```

**Ternary Operator:**

```c
int a = 10, b = 20;
int max = (a > b) ? a : b;  /* max = 20 */

/* In printf */
bool led_on = true;
printf("LED is %s\r\n", led_on ? "ON" : "OFF");
```

***

### 2. Switch Statement

**ทำไมต้องใช้?** Multi-way branching, State Machines

```c
typedef enum {
    STATE_IDLE,
    STATE_RUNNING,
    STATE_PAUSED,
    STATE_ERROR
} system_state_t;

system_state_t state = STATE_IDLE;

switch (state)
{
    case STATE_IDLE:
        printf("System idle\r\n");
        break;

    case STATE_RUNNING:
        printf("System running\r\n");
        break;

    case STATE_PAUSED:
        printf("System paused\r\n");
        break;

    case STATE_ERROR:
        printf("Error!\r\n");
        break;

    default:
        printf("Unknown state\r\n");
        break;
}
```

**Fall-through Pattern:**

```c
char command = 'a';

switch (command)
{
    case 'A':
    case 'a':  /* Fall-through: both do same thing */
        printf("Command A\r\n");
        break;

    case 'Q':
    case 'q':
        printf("Quit\r\n");
        break;

    default:
        printf("Unknown: %c\r\n", command);
        break;
}
```

***

### 3. Loops

**for Loop:**

```c
/* Basic */
for (int i = 0; i < 10; i++)
{
    printf("i = %d\r\n", i);
}

/* Array iteration */
int values[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5; i++)
{
    printf("values[%d] = %d\r\n", i, values[i]);
}

/* Nested */
for (int row = 0; row < 3; row++)
{
    for (int col = 0; col < 4; col++)
    {
        printf("[%d,%d] ", row, col);
    }
    printf("\r\n");
}
```

**while Loop:**

```c
/* Wait for button */
while (cyhal_gpio_read(BUTTON_PIN) == true)
{
    Cy_SysLib_Delay(10);
}
printf("Button pressed!\r\n");

/* Retry pattern */
int retry = 0;
while (connect_wifi() != SUCCESS && retry < 5)
{
    retry++;
    printf("Retry %d...\r\n", retry);
    Cy_SysLib_Delay(1000);
}
```

**do-while Loop:**

```c
/* Execute at least once */
int attempts = 0;
bool success = false;

do {
    attempts++;
    printf("Attempt %d\r\n", attempts);

    if (sensor_init() == SUCCESS)
    {
        success = true;
    }
    else
    {
        Cy_SysLib_Delay(500);
    }
} while (!success && attempts < 3);
```

**break และ continue:**

```c
/* break - exit loop */
for (int i = 0; i < 100; i++)
{
    if (values[i] == target)
    {
        printf("Found at %d\r\n", i);
        break;  /* Exit loop */
    }
}

/* continue - skip iteration */
for (int i = 0; i < 10; i++)
{
    if (i == 5)
    {
        continue;  /* Skip when i == 5 */
    }
    printf("i = %d\r\n", i);  /* Prints 0-4, 6-9 */
}
```

**Infinite Loop (Main Loop):**

```c
/* Standard embedded pattern */
for (;;)
{
    process_sensors();
    update_display();
    check_buttons();
    Cy_SysLib_Delay(10);
}
```

***

### 4. State Machine Pattern

```c
typedef enum {
    SCREEN_HOME,
    SCREEN_SENSORS,
    SCREEN_SETTINGS,
    SCREEN_COUNT
} ui_screen_t;

typedef struct {
    ui_screen_t current;
    ui_screen_t previous;
    bool needs_update;
} ui_state_t;

ui_state_t g_ui = {
    .current = SCREEN_HOME,
    .previous = SCREEN_HOME,
    .needs_update = true
};

void ui_change_screen(ui_screen_t new_screen)
{
    if (new_screen >= SCREEN_COUNT) return;

    if (new_screen != g_ui.current)
    {
        g_ui.previous = g_ui.current;
        g_ui.current = new_screen;
        g_ui.needs_update = true;
    }
}

void ui_update(void)
{
    if (!g_ui.needs_update) return;

    switch (g_ui.current)
    {
        case SCREEN_HOME:
            show_home_screen();
            break;

        case SCREEN_SENSORS:
            show_sensor_screen();
            break;

        case SCREEN_SETTINGS:
            show_settings_screen();
            break;

        default:
            break;
    }

    g_ui.needs_update = false;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aic-eec.com/interfacing-with-infineon-psoc-tm-edge/hmi-development/gpio-to-hmi-display/embedded-c-3.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
