สอนการเขียน PID Control ใน PLC พร้อมตัวอย่าง PWM และทฤษฎี
PID Control ตั้งแต่ศูนย์ด้วยตัวอย่างต้มน้ำให้ได้ 50 องศา เขียน PWM, On-Off และสูตร PID แบบ Discrete เองใน SamSoar2022 บน 2-in-1 GT-043-16MT + F-4PT แล้วใช้คำสั่ง EPID ให้ Self Tune หาค่า KP, TI, TD เอง
PID คำนวณ Output จาก Error = SV − PV ผ่าน 3 เทอม คือ P (Kp × Error) I (สะสม Error แก้ Steady State Error) และ D (อัตราการเปลี่ยนของ Error ลด Overshoot) คลิปนี้ต้มน้ำให้ได้ 50 องศา เขียน PWM และสูตร PID แบบ Discrete เองใน SamSoar2022 แล้วปิดท้ายด้วยคำสั่ง EPID ที่ Self Tune หาค่า KP, TI, TD ให้เอง
อัพเดทล่าสุด: 11 พฤศจิกายน 2569
โจทย์ในคลิป: ต้มน้ำให้ได้ 50 องศา
คลิปนี้สอน PID Control ทั้งทฤษฎีและปฏิบัติ โดยใช้โจทย์ที่ลองทำเองที่บ้านได้ คือต้มน้ำให้ได้น้ำอุ่นที่ 50 องศา (หรืออุณหภูมิอื่นก็ได้) ครึ่งแรกเป็นทฤษฎีและการเขียนสูตร PID เองใน PLC ครึ่งหลังเป็นการใช้คำสั่งสำเร็จ EPID
ระบบต้มน้ำแบ่งเป็น 3 ส่วน
- Controller คือ PLC รับค่า Set Value (SV) แล้วออก Output ไปคุม Process
- Process คือฮีตเตอร์ต้มน้ำ
- Sensor อ่านค่า Process Variable (PV) หรืออุณหภูมิปัจจุบันกลับเข้า Controller ให้ครบ Feedback Loop
ในระบบจริงยังมี Disturbance หรือสิ่งรบกวนจากภายนอก เช่น แอร์หรือพัดลมที่ทำให้อุณหภูมิน้ำเปลี่ยน
อุปกรณ์และการ Wiring
ใช้ได้ 2 แบบ
| แบบ | PLC | โมดูลอ่าน PT100 |
|---|---|---|
| Standalone | PLC รุ่น FAs รุ่นใดก็ได้ | S-E4PT4T |
| 2-in-1 (ที่ใช้ในคลิป) | GT-043-16MT (2-in-1 HMI + PLC จอ 4.3 นิ้ว รุ่น 7 นิ้วก็ใช้ได้เหมือนกัน) | F-4PT |
- Sensor เป็น PT100 แบบ 3 สาย ต่อเข้าโมดูล แล้ว PLC อ่านค่ากลับเข้ามา
- Output ใช้ทรานซิสเตอร์ของ PLC ที่ Y0 ขับ Solid State Relay (SSR) ในรูปต่อ COM0 กับ 0V ของแหล่งจ่าย 24V ส่วน Y0 และ +24V ต่อเข้าขาอินพุตของ SSR
- ฝั่งไฟ AC ให้ L ผ่าน SSR ไปที่เต้ารับ ส่วน N ต่อตรงเข้าเต้ารับ แล้วเสียบปลั๊กฮีตเตอร์ที่เต้ารับนั้น
อ่านอุณหภูมิเข้า PLC
สร้างโปรเจครุ่น GT ใน SamSoar2022 แล้วเพิ่มโมดูล F-4PT ในหน้า Plugins เปิดใช้ Channel AI100 เป็นโหมด PT100 จากนั้นใน Main ใช้ M102 สั่ง MOV ค่า AI100 ไปเก็บที่ D12 ซึ่งเป็น PV
ค่าที่ใช้เป็นค่าดิบไม่มีจุดทศนิยม เช่น 500 คือ 50 องศา
PWM: ออก Output ระหว่าง 0–100% จากขาเดียว
ปกติ Output มีแค่ 1 กับ 0 แต่ถ้าแบ่งเวลาเป็นช่วงเท่าๆ กันที่เรียกว่า Period แล้วกำหนดเวลาที่ออก 1 ในแต่ละช่วงที่เรียกว่า Duty Cycle ค่าเฉลี่ยของ Output จะอยู่ระหว่าง 0 ถึง 1 ได้ เช่น Period 2 วินาที เปิด 1 วินาที คือ Duty Cycle 50% ค่าเฉลี่ย 0.5 ถ้า Duty Cycle เป็น 75% ค่าเฉลี่ยก็สูงขึ้น
กับฮีตเตอร์ PWM ทำให้คุมความร้อนเฉลี่ยได้ ใช้กันแพร่หลายตราบใดที่ความถี่ในการสวิตช์ SSR ไม่สูงเกินไป
ในคลิปวาด T0 (NC) ไว้ตัวเดียวแล้วแตกไปที่ TON ทั้งสองตัว ส่วนข้างบนนี้เขียน T0 ซ้ำในแต่ละกิ่ง ผลการทำงานเหมือนกัน
ที่ใส่ Duty ได้ 0–2000 เพราะ TV250 เป็น timer 1 ms จึงใส่เป็นมิลลิวินาทีได้ตรงๆ ผลที่ทดลองบนเครื่องจริง (Period 2,000 ms)
| D14 | Duty Cycle | Y0 |
|---|---|---|
| 0 | 0% | ดับตลอด |
| 500 | 25% | ติด 0.5 วินาทีต่อคาบ |
| 1000 | 50% | ติด 1 วินาที ดับ 1 วินาที |
| 2000 | 100% | ติดตลอด ฮีตเตอร์อุ่นน้ำตลอด |
On-Off Control และปัญหา Overshoot
ถ้าไม่รู้จัก PID วิธีที่คิดได้จากพื้นฐาน PLC คือ PV ต่ำกว่า SV ก็เปิดเต็ม PV สูงกว่า SV ก็ปิด
D14 คือ Output Duty Cycle ที่ส่งต่อให้ PWM ข้างบน ใช้ MOVD เพราะเป็นค่า Double Word
ผลที่เก็บข้อมูลจากหน้าจอทุก 1 วินาที (ดึงออกผ่าน USB Thumb Drive หรือส่งผ่าน MQTT ไปที่ Google Sheet ก็ได้) ตั้ง SV = 500 (50 องศา) PV พุ่งเกินขึ้นไปสูงสุดราวๆ 52 องศา แล้วค่อยๆ เย็นลง พอต่ำกว่า SV ฮีตเตอร์ก็เปิดเต็มอีก วนแบบนี้ไปเรื่อยๆ
สาเหตุคือ Duty Cycle เป็น 100% ทุกครั้ง และน้ำมีความจุความร้อนจำเพาะ (Specific Heat Capacity) สูง ต้องใช้พลังงานมากกว่าจะร้อนและต้องคายพลังงานมากกว่าจะเย็น แม้ปิดฮีตเตอร์ทันทีที่เกิน SV อุณหภูมิก็ยังพุ่งต่อ
เมื่อเทียบกับกราฟที่ใช้ EPID แบบ Auto Tune (ไม่นับ 2 ไซเคิลแรกที่ระบบกำลังจูนหาค่าสัมประสิทธิ์) PV จะอยู่ใกล้ SV และนิ่งกว่าแบบ On-Off
ทฤษฎี PID
PID ย่อมาจาก Proportional, Integral, Derivative หรือสัดส่วน ปริพันธ์ (ผลรวม) และอนุพันธ์ (อัตราการเปลี่ยนแปลง)
Error
สิ่งแรกที่ต้องคำนวณคือ Error หรือความต่างระหว่างค่าที่ต้องการ (SV) กับค่าปัจจุบัน (PV)
Error = SV − PV
เช่น 500 − 450 = 50
Error เป็นบวกหรือลบก็ได้ เอา Error เข้าสูตรแล้วจะได้ Output ที่พา PV เข้าใกล้ SV สูตรแบ่งเป็น 3 ส่วนตามชื่อ
u(t) = Kp·e(t) + Ki·∫e(τ)dτ + Kd·de(t)/dt
= Kp·[ e(t) + (1/Ti)·∫e(τ)dτ + Td·de(t)/dt ]
Ki = Kp / Ti Kd = Kp · Td
P (Proportional)
P คือเอาสัมประสิทธิ์ Kp คูณกับ Error ปัจจุบัน
ในคลิปลองปรับค่าใน PID Simulator ของ luisllamas.es แทนการต้มน้ำจริงเพราะใช้เวลานาน เมื่อเพิ่ม Kp จาก 0 เป็น 1 กราฟ Current Value ยกขึ้น แต่ปรับ Kp เท่าไรก็ไม่ถึง Set Point สักที เหลือ Error ค้างไว้ เรียกว่า Steady State Error และถ้า Kp มากเกินไปกราฟจะแกว่ง ใช้ P อย่างเดียวจึงไม่พอ
I (Integral)
I คือ Ki คูณกับ Error ที่ถูกอินทิเกรต มองง่ายๆ ว่าเป็นพื้นที่ใต้กราฟระหว่าง Set Point กับ Current Value ยิ่ง Error สะสมมาก Output ก็ยิ่งเพิ่ม เมื่อใส่ Ki เพิ่มเข้าไป Steady State Error ค่อยๆ หายไปและ PV เข้าใกล้ SV
ตอนใช้งานจริงจะไม่ใช้ Ki ตรงๆ แต่ดึง Kp ออกมาคูณทั้งก้อน แล้วใช้ Ti (Integral Time) แทน (Ki = Kp / Ti) เวลาจูนจะตรึง Kp ไว้แล้วเปลี่ยนแค่ Ti
PLC อินทิเกรตไม่ได้ ต้องแปลงเป็นแบบ Discrete คือมองอินทิเกรตเป็นผลรวมของ Error คูณเวลา Sampling (Ts) ในคลิปให้ Ts = 1 วินาที สูตรจึงง่ายลง
I[k] = I[k−1] + Kp · (Ts / Ti) · e[k]
Ts = 1 → I[k] = I[k−1] + Kp · (1 / Ti) · e[k]
D (Derivative)
P กับ I ยังมีปัญหา Overshoot คือค่าพุ่งเลย Set Point ขึ้นไป เมื่อลองเพิ่ม Kd ใน Simulator Overshoot ลดลง เพราะ Output ของ D ขึ้นกับอัตราการเปลี่ยนแปลงของ Error เหมือนขับรถแล้วเห็นรถคันหน้า ก็แตะเบรกเมื่อเข้าใกล้เร็วเกินไป
เปลี่ยน Kd เป็น Td (Derivative Time) แบบเดียวกับฝั่ง I แต่เป็นการคูณ (Kd = Kp × Td) แล้วแปลงเป็น Discrete โดยหาความชันของ Error ระหว่างรอบนี้กับรอบที่แล้ว
D[k] = Kp · (Td / Ts) · (e[k] − e[k−1])
Ts = 1 → D[k] = Kp · Td · (e[k] − e[k−1])
สูตรรวม (Ts = 1)
u[k] = Kp·e[k] + I[k−1] + Kp·(1/Ti)·e[k] + Kp·Td·(e[k] − e[k−1])
เขียน PID เองใน PLC
PID ที่เขียนเองมีไว้เพื่อเข้าใจสูตรระดับโค้ด ใช้ตัวเลข Float คำนวณ แล้วส่งผลลัพธ์เป็น Duty Cycle เข้า D14 ให้ PWM
Main: เรียก Sub Program SelfPID
Sub Program SelfPID
Rung ชุดนี้อยู่ใน Sub Program ชื่อ SelfPID (ไม่ใช่ใน Main)
Register ที่ใช้
| Address | ชนิด | หน้าที่ |
|---|---|---|
| D10 | DWORD | SV (500 = 50 องศา) |
| D12 | DWORD | PV |
| D14 | DWORD | Output Value (Duty) 0–2000 |
| D20 / D22 | DWORD / Float | Error ปัจจุบัน |
| D24 | Float | P Term |
| D26 / D28 | Float | I Term / I รอบที่แล้ว |
| D30 | Float | PID Output ก่อนตัดทศนิยม |
| D32 | Float | Error รอบที่แล้ว |
| D34 | Float | D Term |
| D6000 | — | Calculation Cycle (ค่าตั้งของ TV10 ซึ่งเป็น timer 100 ms) |
| D6002 | Float | Kp |
| D6004 | Float | Ti (Integral Time) |
| D6006 | Float | Td (Derivative Time) |
| M5 | Bit | First Calculation |
| M6 | Bit | สั่งคำนวณ PID 1 รอบ |
| M7501 / M7502 | Bit | ติด = หยุดคำนวณ I / D |
ตั้ง D6000 = 10 (TV10 เป็น timer 100 ms × 10 = 1 วินาที) ให้ตรงกับสมมติฐาน Ts = 1 ในสูตร ถ้าใส่ 1000 ตามที่พูดในคลิป รอบคำนวณจะกลายเป็น 100 วินาที
หน้าจอ HMI (2-in-1)
ค่าที่อ่านจาก PLC มาจาก COM2 ซึ่งเป็น Internal Controller ของรุ่น 2-in-1
- SV = D10 กรอกค่าได้ (ค่าดิบ 500 = 50 องศา) PV = D12 Out = D14 ทั้งหมดเป็นข้อมูล 32 บิต และมีไฟแสดงสถานะ Y0 ว่า SSR กำลังทำงานหรือไม่
- ปุ่ม On Off, Self PID, EPID เปิด Window ของแต่ละโหมด ในนั้นมีปุ่มเปิด PWM (M10) และปุ่มเริ่มของโหมดนั้น เช่น On-Off Control ที่ M1
- Window Self PID มีปุ่ม PWM, Self PID Control, Integral (M7501), Derivative (M7502) และช่องกรอก Calculation Cycle (D6000), K_p (D6002), T_i (D6004), T_d (D6006)
Trend Chart
| ช่อง | ค่า |
|---|---|
| Data type | 32-Bit Unsigned Int |
| Read Trigger bit | LB0 (กด Start ให้กราฟวิ่ง ถ้าไม่กดกราฟจะหยุด) |
| Read Address | D10 |
| Clear Trigger bit | LB100 (Automatic Reset) |
| Curve number | 3 (D10 SV, D12 PV, D14 Output — ข้อมูล 32 บิตจึงกระโดดทีละ 2 Address) |
| Sampling time | 1 × 1s |
| Number of Data Points | 60 |
ปุ่มช่วยอื่นๆ
| ปุ่ม | Address | หน้าที่ |
|---|---|---|
| MOV Data | M102 | ย้ายค่าอุณหภูมิจาก Analog Input เข้า PV |
| Start Trend | LB0 | เริ่มวาด Trend |
| Clear Trend | LB100 | ล้าง Trend |
| Clear | LB60120 | ล้างข้อมูลใน Historical Data ก่อนดาวน์โหลด |
| ไฟ USB | LB60114 | ติดเป็นสีเขียวเมื่อเสียบ USB Thumb Drive (ฟอร์แมต FAT32) |
| Export | LB60128 | Export ไฟล์ CSV จาก Historical Data ลง USB |
ปุ่มสุดท้ายเป็น Network Setting สำหรับต่อ WiFi หรือตั้ง IP เพื่อส่งข้อมูลออกไปวิเคราะห์ ซึ่งคลิปนี้ไม่ได้ลงรายละเอียด
ใช้คำสั่ง EPID (PID สำเร็จรูปพร้อม Self Tune)
ใช้งานจริงไม่ต้องเขียนสูตรเอง ใช้คำสั่ง EPID ของ PLC ได้เลย ตัว E มาจากการที่ปรับปรุงจากคำสั่ง PID เดิมให้มี Auto Tune คือให้ Controller วิเคราะห์หาค่า KP, TI และ TD ออกมาให้เอง
เขียนคำสั่ง EPID
คำสั่งขอ 5 พารามิเตอร์
EPID K0 D6100 D10 D12 D14
│ │ │ │ └─ Output (D14 Duty)
│ │ │ └────── Measure (PV)
│ │ └─────────── Target (SV)
│ └────────────────── Address เริ่มต้นของชุดพารามิเตอร์ (จอง 50 ตัว D6100–D6149)
└────────────────────── PID Loop K0–K7 (สูงสุด 8 Loop)
- Loop คือการคำนวณ PID 1 ชุด เช่นระบบต้มน้ำนี้ 1 ระบบ เขียนใหม่ให้เริ่มที่ K0
- Address ถ้ามีหลาย Loop ต้องเว้นแต่ละชุดไว้ 50 ตัว
- Output เป็น Bit (Y หรือ M) ก็ได้ EPID จะออกเป็น Duty Cycle เอง หรือเป็น D แบบ Analog ก็ได้ ในคลิปใช้ D14 ส่งให้ PWM ที่เขียนไว้
ตั้งค่าใน EPID Wizard
ดับเบิลคลิกคำว่า <More...> ในบล็อก EPID เพื่อเปิดหน้าต่าง EPID Extension PID control ใช้อ่านและเขียนพารามิเตอร์ได้ง่ายกว่าแก้ใน Address ทีละตัว
- Loop เลือกจำนวน Loop ที่ใช้ ในคลิปใช้ LOOP 0 อันเดียว
- LOOP 0 (Base setting) ตั้ง Loop index = 0, Target value = D10, Measure value = D12, Output mode = Amulate volume (D) คือแบบ Analog, Output address = D14 ถ้าจะออกตรงที่ขา Y0 ไปที่ SSR ก็เลือก Output mode เป็น Y ได้
- Argument ตั้งพารามิเตอร์
| พารามิเตอร์ | ค่าในคลิป | ความหมาย |
|---|---|---|
| Sample period | 1000 ms | รอบการคำนวณ ระบบต้มน้ำไม่ต้องเร็ว ถ้าเป็นงานที่ต้องปรับบ่อยๆ เช่นโดรนหรืองานเคลื่อนที่ให้ใส่ค่าน้อยลง |
| Benifit | 0 (ให้ Self Tune หา) | Kp |
| Integral time | 0 ms (ให้ Self Tune หา) | Ti |
| Differential time | 0 ms (ให้ Self Tune หา) | Td |
| Deadzone | 0 | ถ้า Error น้อยกว่าค่านี้ PID จะหยุด ใส่ 0 คือทำงานตลอดตราบที่มี Error |
| Output minimum / maximum | 0 / 2000 | ตรงกับช่วง Duty ของ PWM |
| Output direction | Negative | Negative = PV ลด Output เพิ่ม (งานให้ความร้อนแบบนี้ ระบบส่วนใหญ่ใช้แบบนี้) Positive = PV ลด Output ลด |
| PID calculate range | 65535 (ค่าเริ่มต้นใน Wizard ส่วน Network EPID Initialization เขียน 10000) | Error น้อยกว่าค่านี้ PID จึงทำงาน เป็น Double Word ใส่ค่ามากได้ ใส่ไว้มากคือ PID ทำงานต่อเนื่อง |
| Control mode | PID | เลือก PID, PI หรือ P ก็ได้ P อย่างเดียวมี Steady State Error บางระบบ PI ก็พอ แต่ในคลิปใส่ D ด้วยเพราะห่วงเรื่อง Overshoot |
| PID mode | PID custom control | คำนวณ Output ตามสูตรจาก Kp, Ti, Td เหมาะกับระบบที่พฤติกรรมคงที่อย่างการต้มน้ำ |
PID mode มีอีก 2 แบบ คือ Handle mode ปรับ Output เองด้วยมือ และ Self-Adaption fuzzy PID control สำหรับระบบที่คาดเดาพฤติกรรมไม่ได้หรือเปลี่ยนตลอดเวลา ถ้าใช้ PID custom control ข้ามแท็บ Obscure PID ไปได้
ถ้าจะจูนเองให้แก้ค่าในหน้านี้แล้วกด Write to PLC ถ้าใช้ Auto Tune ให้จูนเสร็จก่อนแล้วค่อยอ่านค่ากลับมา
- Self-Adaption ติ๊ก Enable self-adjustment แล้วเขียนลง PLC เพื่อสั่งให้ PLC รันไซเคิลปกติ 2 ไซเคิลแล้วหาค่า KP, TI, TD ที่เหมาะสม การ Enable นี้เขียนลง Address ลำดับที่ 34 ของชุดพารามิเตอร์ (ในคลิปคือ D6134) ตั้ง Self-Adaption timeout ให้นานพอให้ระบบจูนเสร็จ ในคลิปใส่ 80 นาที
- Memory distribute ดูว่า D แต่ละตัวทำหน้าที่อะไร (เริ่มที่ D6100 ใช้ 50 words)
| Address | ชนิด | หน้าที่ |
|---|---|---|
| D6100 | DWORD | Sample period (ms) |
| D6102 | FLOAT | Benefit (Kp) |
| D6104 | FLOAT | Integral Time (ms) |
| D6106 | FLOAT | Integral Coefficient |
| D6108 | FLOAT | Differential Time (ms) |
| D6110 | FLOAT | Differential Coefficient |
| D6112 | WORD | Deadzone |
| D6114 | FLOAT | Output Upper Limit |
| D6116 | FLOAT | Output Lower Limit |
| D6118 | HEX | PID Config |
| D6120 | DWORD | PID Calculation Volume |
| D6122 | FLOAT | PID Calculation Range |
| D6124 | HEX | Error Code |
| D6125 | WORD | PID Mode |
| D6134 | WORD | Self-tune Status |
| D6136 | WORD | Self-tune Timeout |
| D6140 / D6141 / D6142 | WORD | P / I / D Term |
D6134 (Self-tune Status) สำคัญที่สุด ระหว่างจูนจะเป็น 1 พอรันครบ 2 ไซเคิลและจูนเสร็จจะเปลี่ยนเป็น 0 แปลว่าได้ค่าสัมประสิทธิ์แล้ว
ผล Self Tune บนเครื่องจริง
บนหน้าจอ กดปุ่ม EPID เปิด Window แล้วเปิด PWM ก่อน ตามด้วย EPID Control (M0) แล้วกด Self Tune (M3 ซึ่งเขียน D6134 = 1) PV ต่ำกว่า SV ระบบก็เริ่มทำงาน รอ 2 ไซเคิลก็ได้ค่าสัมประสิทธิ์ที่เหมาะกับระบบ
ในช่วง 2 ไซเคิลแรก Output จะเปิดเต็มปิดสุดเหมือน On-Off (กราฟมี Overshoot) เพื่อเก็บข้อมูล พอได้ค่าแล้วจึงเริ่มใช้สูตร PID Output หลังจากนั้นจึงขึ้นลงตลอด
ค่าที่ระบบต้มน้ำในคลิปได้จาก Self Tune (ดูใน Monitor)
| Address | ค่า |
|---|---|
| D6102 (Kp) | 52.685822 |
| D6104 (Ti) | 378500 ms |
| D6108 (Td) | 90840 ms |
ดับเบิลคลิก <More...> อีกครั้ง ในหน้า Argument กด Read from PLC เพื่อดึงค่าที่ Self Tune ได้เข้ามาใน Wizard แล้วปรับจูนเองต่อได้ภายหลัง
สรุป
การเขียนสูตร PID เองทีละเทอมช่วยให้เข้าใจว่าเบื้องหลัง PLC คำนวณ PID อย่างไร ส่วนงานจริงใช้คำสั่ง EPID ที่มี Self Tune ได้เลย PID ไม่ได้ใช้แค่ต้มน้ำ ยังใช้คุมตำแหน่ง พัดลม งานแช่แข็ง และอื่นๆ ลองนำโครงสร้างโค้ดนี้ไปปรับใช้กับระบบของตัวเอง
บทถัดไป
การใช้งาน PID Control ใน PLC พร้อมเทคนิค Auto Tuning
มีคำถาม? ติดต่อทีมงาน

