# พื้นฐาน 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;
}
```
