ในฐานะ CODESYS Solutions Architect ผมขอสรุปการเขียน Control Flow Statements ในภาษา ST ให้คุณเข้าใจง่ายๆ โดยเปรียบเทียบกับ C# ครับ

หัวใจสำคัญของการเขียน Logic ใน PLC คือ “ความชัดเจน” (Readability) และ “ความปลอดภัย” (Safety) ครับ เพราะ Code ของเราควบคุมเครื่องจักรที่มีอันตราย ไม่ใช่แค่จัดการ Data เหมือนฝั่ง IT เรามาดูรายละเอียดกันครับ

1. IF…THEN…ELSIF…ELSE (The Decision Maker)

ใน C# คุณใช้ if (condition) { } แต่ใน ST เราไม่มีปีกกา เราใช้ THEN และปิดท้ายด้วย END_IF; เสมอ

Scenario: ระบบเติมน้ำเข้าถัง (Hysteresis Control)

โจทย์คือควบคุมปั๊มน้ำ (Fill Pump) โดยใช้ Hysteresis Logic (น้ำต่ำเริ่มเติม, น้ำเต็มหยุดเติม) เพื่อป้องกันปั๊มทำงานกระชาก (Chattering)

PROGRAM PLC_PRG
VAR
    rLevel      : REAL;         // ระดับน้ำปัจจุบัน (0-100%)
    xPumpStart  : BOOL;         // สั่งปั๊มทำงาน

    // Config Parameters (ควรประกาศเป็น Constant หรือ Retain Variable)
    c_rLowLevel : REAL := 10.0; // จุดเริ่มทำงาน
    c_rHighLevel: REAL := 90.0; // จุดหยุดทำงาน
END_VAR

// ---------------------------------------------------------
// Logic: Hysteresis Control
// ---------------------------------------------------------

IF rLevel < c_rLowLevel THEN
    // ถ้าน้ำต่ำกว่า 10% ให้เริ่มเดินปั๊ม (Set Active)
    xPumpStart := TRUE;

ELSIF rLevel > c_rHighLevel THEN
    // ถ้าน้ำสูงเกิน 90% ให้หยุดปั๊ม (Reset)
    xPumpStart := FALSE;

ELSE
    // ช่วงกลาง (10-90): ให้คงสถานะเดิมไว้ (Memory/Latch)
    // ไม่ต้องเขียน Code อะไร หรือเขียนย้ำว่า xPumpStart := xPumpStart;
    ;
END_IF;

💡 Architect Insight: สังเกตว่าผมไม่ได้เขียน ELSE เพื่อสั่ง FALSE ทันทีที่ระดับเกิน 10% แต่ปล่อยให้มันทำงานจนถึง 90% นี่คือเทคนิค Hysteresis ที่ C# Developer ต้องปรับจูน Logic ให้เข้ากับ Physics ของโลกจริงครับ

2. CASE…OF (The State/Mode Manager)

นี่คือ switch...case ของ C# ครับ เหมาะมากสำหรับการทำ State Machine หรือเลือก Operation Mode เพราะอ่านง่ายกว่า IF ซ้อนกันหลายชั้น

Scenario: เลือกโหมดการทำงานของเครื่องจักร (Machine Mode)

Step 1: สร้าง ENUM (Recommended) เพื่อให้ Code อ่านรู้เรื่อง (Self-documenting) ห้ามใช้ Magic Number (0, 1, 2) ลอยๆ ครับ

TYPE eMachineMode :
(
    STOPPED := 0,
    MANUAL  := 1,
    AUTO    := 2,
    ERROR   := 99
);
END_TYPE

Step 2: เขียน Logic ใน Program

PROGRAM PLC_MachineControl
VAR
    CurrentMode : eMachineMode;
    xMotorRun   : BOOL;
    xManualCmd  : BOOL;
    xAutoCmd    : BOOL;
    xErrorLamp  : BOOL;
END_VAR

// ---------------------------------------------------------
// Logic: Mode Selection
// ---------------------------------------------------------

CASE CurrentMode OF
    eMachineMode.STOPPED:
        // โหมดหยุด: ตัดการทำงานทุกอย่าง (Safety First)
        xMotorRun := FALSE;
        xErrorLamp := FALSE;

    eMachineMode.MANUAL:
        // โหมด Manual: ควบคุมตามปุ่มกด
        xMotorRun := xManualCmd;

    eMachineMode.AUTO:
        // โหมด Auto: ควบคุมตาม Sequence หรือ Sensor
        xMotorRun := xAutoCmd;

    eMachineMode.ERROR:
        // โหมด Error: หยุดเครื่องและโชว์ไฟ Alarm
        xMotorRun := FALSE;
        xErrorLamp := TRUE;

    ELSE
        // Defensive Programming: ถ้าค่าหลุดจากที่กำหนด (เช่น ค่าขยะ) ให้เข้า Safe State ทันที
        CurrentMode := eMachineMode.STOPPED;
        xMotorRun := FALSE;
END_CASE;

💡 Architect Insight: Safety Critical: ต้องมี ELSE เสมอใน CASE เพื่อดักจับค่าที่ไม่รู้จัก (Unknown State) แล้วสั่ง Shutdown ระบบทันที นี่คือกฎเหล็กครับ

3. ข้อควรระวังและ Best Practices (Architect’s Warning)

❌ สิ่งที่ควรเลี่ยง: Nested IF (นรกของความซับซ้อน)

การเขียน IF ซ้อนกันลึกๆ (Deep Nesting) ทำให้ Code อ่านยากและเสี่ยงต่อ Logic Error สูงมาก

// ❌ Bad Code (อ่านยาก บำรุงรักษายาก)
IF xSystemOn THEN
    IF NOT xError THEN
        IF rTemp > 80.0 THEN
            IF xSafetyDoorClosed THEN
                xFan := TRUE;
            END_IF
        END_IF
    END_IF
END_IF

✅ วิธีแก้: Flatten Logic (ทำให้แบนราบ)

ใช้ Boolean Algebra (AND, OR) รวมเงื่อนไข หรือใช้ CASE แทน

// ✅ Clean Code (รวมเงื่อนไขให้อ่านง่าย)
// พัดลมจะทำงานเมื่อ: ระบบเปิด AND ไม่เสีย AND ร้อน AND ประตูปิด
xFan := xSystemOn AND NOT xError AND (rTemp > 80.0) AND xSafetyDoorClosed;

✅ Best Practices เพิ่มเติม:

  • Indentation (ย่อหน้า): ใช้ Tab จัดย่อหน้าให้ตรงกันเสมอ CODESYS จะอ่านง่ายขึ้นมากถ้าจัด format ดีๆ
  • Assignment Operator: จำไว้เสมอว่า ST ใช้ := สำหรับกำหนดค่า และใช้ = สำหรับเปรียบเทียบ (ใน IF) อย่าสับสนกับ C#
  • Default ELSE: ในการเขียน IF...ELSIF ควรจบด้วย ELSE เสมอ เพื่อกำหนดพฤติกรรมในกรณีที่เงื่อนไขไม่ตรงกับอะไรเลย (Defensive Programming)

หวังว่าสรุปนี้จะช่วยให้คุณ Map Logic จาก C# มาสู่ CODESYS ได้อย่างมั่นใจนะครับ!

ติดตามต่อใน EP.3: เราจะมาดูเรื่อง Loops (FOR, WHILE) และการจัดการ Array กันครับ