พื้นฐานการเขียนโปรแกรม PLC ด้วยภาษา Structure Text

พื้นฐานการเขียนโปรแกรม PLC ด้วยภาษา Structure Text

พื้นฐานการเขียนโปรแกรม PLC ด้วยภาษา Structure Text

ภาษา Structure Text หรือตัวย่อสั้นๆอาจจะเรียกว่า “ST” เป็นหนึ่งในภาษาที่อยู่ใน Standard IEC61131-3 ว่าด้วยเรื่องของมาตรฐานการเขียนโปรแกรมบน Programable Logic Controller (PLC) เป็นภาษาที่มีจุดเด่นในด้านความง่ายในการโปรแกรมที่มีการคำนวนที่ซับซ้อน มีการบวก ลบ คูณ หาร หรือการ mapping ข้อมูลจำนวนมาก ซึ่งถ้าใช้ Ladder Diagram อาจจะใช้จำนวนบล็อกที่มากกว่าในการทำงานอย่างเดียวกัน งานที่มีลักษณะการทำงานเป็นเงื่อนไข (IF ELSE) ก็สามารถจัดการได้ง่ายกว่า หรือแม้กระทั่งคำสั่งวนลูปต่างๆเพื่อนำไปใช้จัดการกับ Array ของข้อมูลจำนวนมาก ก็เหมาะอย่างยิ่งกับการเขียนด้วย Structure Text

ในบทความนี้ ผู้เขียนจะอ้างอิงโดยใช้ PLC ตระกูล Logix ของยี่ห้อ Allen-Bradley ซึ่งใน PLC แต่ละยี่ห้ออาจจะมีไวยากรณ์ที่ต่างกันบ้างเล็กน้อย แต่โดยรวมแล้วจะมีหลักการเขียนที่เหมือนกัน โดยผู้เขียนขอแบ่งหัวข้อออกเป็น 4 หัวข้อ ได้แก่

  1. Assignments การกำหนดค่าให้กับตัวแปร
  2. Expressions การคำนวนต่างๆ
  3. Instructions คำสั่งเฉพาะ
  4. Constructions การจัดการกับโปรแกรม

หัวข้อที่ 1 Assignments

เกี่ยวกับการกำหนดค่าให้ตัวแปรของเรา โดยจะใช้ไวยากรณ์ดังนี้

Tag := expression;

โดยที่

Tag คือ ตัวแปรที่สร้างไว้และกำลังจะรับค่าจากจาก expression

:= คือ เครื่องหมายสำหรับ assign ค่า

Expression คือ การคำนวนซึ่งได้มาซึ่งค่าๆหนึ่งซึ่งต้องการจะ assign ให้กับ Tag

; คือ เครื่องหมายจบ assignment

ตัวอย่าง

Tag1:=Tag2+Tag3;         หมายถึง Tag1 จะมีค่าเท่ากับผลรวมของ Tag2 กับ Tag3

 

หัวข้อที่ 2 Expressions

คือ การคำนวนใดๆซึ่งได้ค่าผลลัพธ์ออกมา ไม่ว่าจะเป็นการกระทำการทางคณิตศาสตร์ การเปรียบเทียบค่า (Comparison) หรือคำนวนโดยใช้ฟังก์ชันต่างๆ

เครื่องหมายทางคณิตศาสตร์ที่ใช้ได้มีดังนี้

ฟังก์ชันที่ช่วยในการคำนวน

การเปรียบเทียบค่า (compare function) จะให้ผลลัพธ์เป็น BOOL คือมีค่าเป็น เท็จ (0) หรือจริง (1) เท่านั้น

Pic3

การใช้ logical operator

ใช้เมื่อต้องการตรวจสอบเงื่อนไขที่มากกว่าหนึ่งเงื่อนไขว่าเป็นจริงหรือเท็จ โดยจะให้ผลลัพธ์เป็น BOOL คือมีค่าเป็น เท็จ (0) หรือจริง (1) เท่านั้น

Pic4

**ใน PLC รุ่น CompactLogix และ ControlLogix สามารถใช้ Logical Operator กับ Tag ชนิด DINT ได้ โดยจะเป็นการเปรียบเทียบในระดับบิทแทน

การตีความผลลัพธ์ของ Expression จะทำจากซ้ายไปขวา โดยเรียงลำดับความสำคัญตามตารางดังนี้

Pic5

ดังนั้น เพื่อให้เข้าใจง่ายและไม่มีความผิดพลาด แนะนำให้ใช้วงเล็บช่วยในการจัดกลุ่มเครื่องหมาย เมื่อมีการใช้หลายๆตัวแปรในการคำนวน expression

 

หัวข้อที่ 3 Instruction

Instruction คือ คำสั่งต่างๆที่ใช้ใน PLC จะมีคำสั่งอะไรบ้างนั้นขึ้นอยู่กับ PLC แต่ละรุ่นและยี่ห้อ เช่น คำสั่ง Motion, คำสั่งที่ใช้จัดการกับ ASCII และ STRING, Timer และ Counter และอื่นๆอีกมากมาย ซึ่งจะไม่ได้กล่าวถึงเนื้อหาในบทนี้

หัวข้อที่ 4 Construction

เป็นตัวควบคุมการ Execution ของโปรแกรม เนื่องจากถ้าไม่มีการควบคุม โปรแกรมจะ Execute จากบรรทัดบนสุดไปล่างสุด และวนกลับไปที่บรรทัดบนสุดและไปล่างสุดเสมอ ในบางครั้ง จำเป็นต้องมีการวางเงื่อนไขเพื่อให้การคำนวนเป็นไปตามต้องการ คำสั่งต่างๆที่เกี่ยวข้องได้แก่

1. IF…THEN

       IF bool_expression THEN

 <statement>;

       END_IF;

ทำ <statement> เมื่อเงื่อนไข bool_expression เป็นจริง และข้ามในส่วนนี้ไปเลย ถ้า bool_expression เป็นเท็จเช่น

Pic7

2. IF…THEN…ELSE

     IF bool_expression THEN

 <statement1>;

     ELSE

 <statement2>;

    END_IF;

ทำ <statement1> เมื่อเงื่อนไข bool_expression เป็นจริง และทำ <statement2> เมื่อ bool_expression เป็นเท็จ เช่น

Pic9

ใส่ [:=] เพื่อให้เคลียร์ค่า Tag นี้เป็น 0 เมื่อเริ่มรันโปรแกรม หรือปิดเปิดไฟใหม่

3. IF…THEN…ELSEIF

       IF bool_expression1 THEN

 <statement1>;

       ELSEIF bool_expression2 THEN

 <statement2>;

       END_IF;

ทำ <statement1> เมื่อเงื่อนไข bool_expression1 เป็นจริง และทำ <statement2> เมื่อ bool_expression1 เป็นเท็จและ bool_expression2 เป็นจริง เช่น

Pic11

4. CASE_OF

     CASE numeric_expression OF

 selector1: <statement>;

 selectorN: <statement>;

     ELSE

 <statement>;

     END_CASE;

ใช้ CASE เมื่อต้องการเขียนเงื่อนไขแบบตัวเลือกโดยใช้เงื่อนไขเดียวในการตรวจสอบ เช่น

Pic13

5.  FOR_DO

ใช้เพื่อวนลูปจนกว่า initial_value จะเกิน final_value ที่กำหนดโดนกำหนดให้เพิ่มค่าทีละ Increment_value โดยที่ ถ้าไม่ได้กำหนด increment_value จะทำการเพิ่มค่าทีละ 1

FOR count:=initial_value

        TO final_value

        BY increment_value (Optional)

DO

 <statement>;

END_FOR;

การใช้งานคำสั่งวนลูปมักจะใช้ร่วมกับ Array เพื่อทำการคำนวนค่าในทุกๆช่องของ Array ได้อย่างรวดเร็ว เช่น

คำสั่งนี้เป็นการกำหนดให้ Array[0] – Array[31] มีค่าเป็น 0 ทั้งหมด

6. WHILE_DO

ให้วนลูปไปเรื่อยๆตราบที่ condition ที่ตรวจสอบยังเป็นจริงอยู่

      WHILE bool_expression DO

 <statement>;

      END_WHILE;

ข้อควรระวังในการใช้ WHILE_DO คือ ถ้าเงื่อนไข bool_expression เป็นจริงตลอด โปรแกรมจะติดอยู่ใน loop และไม่ scan บรรทัดถัดไป จนทำให้ Controller Fault ได้ ดังนั้น จึงควรเขียนเงื่อนไขในการออกจาก Loop โดยใช้ IF_THEN ไว้ด้วย

ตัวอย่างการใช้ WHILE

ทำการค้นหา array ช่องแรกที่มีค่าเท่ากับ targetvalue โดยการตรวจสอบทีละช่องตั้งแต่ structarray[0] เมื่อเจอช่องที่มีค่าเท่ากับ targetvalue จะออกจาก Loop WHILE และได้ค่า Pos ของ array เพื่อใช้คำนวนอย่างอื่นต่อไป

7. REPEAT_UNTIL

ให้วนลูปไปเรื่อยๆจนกว่า เงื่อนไขจะเป็นจริง มีลักษณะคล้ายกับ While แต่ต่างกันตรงที่ While จะต้องมีเงื่อนไขเป็นจริงก่อนจึงจะเริ่มทำ statement แต่ REPEAT จะทำ statement ก่อนแล้วค่อยเช็คเงื่อนไข

REPEAT

<statement>;

UNTIL bool_expression

END_REPEAT;

Pic19

ข้อควรระวังในการใช้ REPEAT_UNTIL คือ ถ้าเงื่อนไข bool_expression ไม่เป็นจริงเป็นเวลานาน โปรแกรมจะติดอยู่ใน loop และไม่ scan บรรทัดถัดไป จนทำให้ Controller Fault ได้ ดังนั้น จึงควรเขียนเงื่อนไขในการออกจาก Loop โดยใช้ IF_THEN ไว้ด้วย

Pic20

ตัวอย่างการใช้งาน REPEAT

Pic21

ทำการค้นหา array ช่องแรกที่มีค่าเท่ากับ targetvalue โดยการตรวจสอบทีละช่องตั้งแต่ structarray[0] เมื่อเจอช่องที่มีค่าเท่ากับ targetvalue จะออกจาก Loop REPEAT และได้ค่า Pos ของ array เพื่อใช้คำนวนอย่างอื่นต่อไป

 

เอกสารอ้างอิง
https://literature.rockwellautomation.com/idc/groups/literature/documents/pm/1756-pm007_-en-p.pdf