C Scripting ใน HMI
พื้นฐานภาษา C สำหรับเขียน Script ใน HMI Samkoon ด้วย SKTool ตั้งแต่ Script Editor, Comment, ค่าคงที่ฐาน 10 และฐาน 16, Overflow, การประกาศตัวแปร short/int/float, Variable settings, Array ไปจนถึงสั่ง Y0 ของ PLC จาก Script
Script ของ HMI ซีรีส์ SK เขียนด้วยภาษา C ใน Script Editor ของ SKTool — EP นี้สอน 4 เรื่องแรกคือค่าคงที่ การประกาศตัวแปร ตัวแปรพิเศษที่ผูกกับ Address ของ HMI หรือ PLC ผ่าน Variable settings และ Array พร้อมทดสอบด้วย Init Script จนสั่ง Y0 ของ PLC ให้ติดได้
อัพเดทล่าสุด: 26 ตุลาคม 2569
ทำไมต้องเขียน Script
ถ้าอยากทำระบบที่ซับซ้อนขึ้น เช่น LINE Notification เก็บข้อมูลลง Google Sheets ใช้ HTTP Protocol หรือ MQTT Protocol หรือสร้าง SCADA เองจากหน้าจอ มักต้องกำหนดเงื่อนไขการทำงานของหน้าจอเอง เช่น มีคนกดปุ่มแล้วให้ไป Run Function ส่งข้อมูลไปที่ Server หรือส่งการแจ้งเตือน ซึ่งต้องทำผ่าน Script
Script ของ HMI ซีรีส์ SK ใช้ ภาษา C เป็นหลัก ไม่ต้องเป็น Programmer ก็เรียนได้ แค่เข้าใจคอนเซ็ปต์ที่เกี่ยวข้อง
พื้นฐานภาษา C ที่ควรมีในการใช้ HMI
- ค่าคงที่
- การประกาศตัวแปร
- การสร้างตัวแปรพิเศษ (ค่าจาก PLC หรือ Sensor)
- การสร้างและใช้งาน Array
- การทำงานตามเงื่อนไข
- การวนลูป
- การใช้งานตัวอักษรและ String
- การสร้างฟังก์ชันเพื่อใช้ซ้ำ
EP นี้โฟกัสเฉพาะ 4 ข้อแรก
เตรียมหน้าจอและ Script Editor
- Copy หน้าจอเดิม (เช่นหน้า Settings) แล้ว Paste เป็นหน้าใหม่ เปลี่ยน Screen Name เป็น
C-Languageและ ID เป็น 20 แล้วสร้างปุ่มเข้าหน้านี้ - ที่เมนูทางซ้ายหา Script Editor แล้วดับเบิลคลิกเปิดขึ้นมา
- กดปุ่ม New (รูปไฟล์) ที่มุมซ้ายบนเพื่อสร้าง Script ใหม่ — มองว่า Script คือไฟล์ที่กำหนดให้หน้าจอ Run ได้
- ตั้งชื่อ Script เช่น
CBasic
โปรแกรมสร้างโค้ดตั้งต้นให้ (Macro_main และ MarcoInit) โค้ดที่เราเขียนเพิ่มให้เขียนไว้ใต้ Comment //ToDo
Comment
Comment คือส่วนที่ Compiler ไม่สนใจเวลา Compile ใช้จดว่าโค้ดนี้ทำอะไร ไม่เกี่ยวกับ Logic การทำงานใดๆ
#include "MacroInit.h"
//#include "subFun1.c" //Example
void Macro_main(IN *p)
{
MarcoInit
//ToDo
// This is a comment
/*
This is a multi-line
comment
*/
}//— Comment บรรทัดเดียว/*...*/— Comment หลายบรรทัด
ค่าคงที่และการกำหนดค่าให้ Local Word
#include "MacroInit.h"
//#include "subFun1.c" //Example
void Macro_main(IN *p)
{
MarcoInit
LocalWord[0] = 15;
LocalWord[1] = 0xF;
LocalWord[2] = -15;
LocalWord[3] = 65535;
LocalWord[4] = 65551; // Binary: 1_0000000000001111 (overflow)
}- ทุกคำสั่งต้องปิดด้วย Semicolon (
;) — ถ้าลืมแล้วกด Compile จะขึ้น Error สีแดง 0xF— ขึ้นต้นด้วย0xคือเลขฐาน 16 (F = 15) จึงได้ค่า 15 เท่ากับเขียน15แบบฐาน 10
ทดสอบด้วย Init Script
- ปิด Script Editor แล้วสร้าง Numeric Display ที่ Local Word 0 (ไปที่ View → Display Control Address เพื่อให้หน้าจอแสดง Address สีแดงบน Control ที่วางไว้)
- เลือกวิธีเรียก Script — มี 3 แบบ
| แบบ | ทำงานเมื่อ |
|---|---|
| Global Script | เรียกตลอดเวลาขณะ HMI ทำงาน เช่นส่งข้อมูลจาก HMI ไป PLC ทุกๆ 10 วินาที |
| Init Script | Run ครั้งเดียวเมื่อเปิด HMI ขึ้นมา |
| Trigger Script | Run เมื่อ Bit บางตัวเปลี่ยนสถานะ เช่นมีคนกดปุ่มที่ PLC |
- EP นี้ใช้ Init Script เพราะเรียกแค่ครั้งเดียวก็พอ — กด New เลือก Script
CBasicแล้วกด OK - กด Offline Simulate แล้วไปที่หน้า C-Language จะเห็น Local Word 0 = 15
ค่าติดลบ
LocalWord[2] = -15; แต่ Numeric Display ยังไม่แสดง -15 เพราะยังไม่ได้กำหนดให้แสดงค่าติดลบ — แก้ Data Type จาก 16-bit Unsigned Int เป็น 16-bit Signed Int แล้วจะได้ -15
Overflow
ค่าสูงสุดของข้อมูล 16 bit คือ 65535 ซึ่งใส่ได้ไม่มีปัญหา แต่ถ้าใส่ 65551 ลง Local Word 4 การ Compile ยังผ่าน (ขึ้นแค่ Warning) ภาษา C ไม่ห้ามให้ ต้องระวังเอง
ผลคือหน้าจอแสดง 15 เพราะ 65551 ในเลขฐาน 2 คือ 1_0000000000001111 ยาวเกิน 16 bit ตัว 1 ข้างหน้าจึงถูกตัดทิ้ง เหลือ 0000000000001111 = 15 เหตุการณ์นี้เรียกว่า Overflow ต้องระวังเวลาตัวเลขนับเพิ่มจนเกินขอบเขต
การประกาศตัวแปร
ตัวแปรในภาษา C ต้องกำหนดชนิดข้อมูลตอนประกาศ
| ชนิด | ขนาด | หมายเหตุ |
|---|---|---|
short | 16 bit | เท่ากับขนาดของ Local Word หนึ่งช่อง |
int | 32 bit | ย่อมาจาก Integer ใช้เมื่อต้องการค่าที่ใหญ่กว่า 16 bit |
float | 32 bit | มีจุดทศนิยมได้ |
#include "MacroInit.h"
//#include "subFun1.c" //Example
void Macro_main(IN *p)
{
MarcoInit
short a; // 16-bit
a = 15;
short aa = 15;
int b; // 32-bit
b = 100000;
float c; // 32-bit
c = 3.1415;
}ต้องประกาศตัวแปรก่อนแล้วจึง Assign ค่า จะเขียน a = 15; ก่อนบรรทัด short a; ไม่ได้ หรือจะประกาศพร้อม Assign ค่าในบรรทัดเดียวแบบ short aa = 15; ก็ได้
ตัวแปรพิเศษ — Variable settings
จะแสดงค่าตัวแปรบนหน้าจอ ทำได้ทั้งเอาไปใส่ Local Word แต่ละตำแหน่ง หรือสร้าง ตัวแปรพิเศษ ที่ผูกกับ Address ในแท็บ Variable settings ด้านล่างของ Script Editor
- ในแท็บ Variable settings ดับเบิลคลิกแถว New
- สร้างตัวแปรชื่อ
LW5Data type 32-Bit Unsigned Int (เพราะbเป็น int) Address LW5 แล้วกด OK - สร้างตัวแปรชื่อ
LW7Data type 32-Bit Float Address LW7 — ข้าม LW6 เพราะข้อมูล 32 bit ที่ LW5 กินที่ LW6 ไปด้วย - เขียนโค้ดส่งค่าเข้าตัวแปร
#include "MacroInit.h"
//#include "subFun1.c" //Example
void Macro_main(IN *p)
{
MarcoInit
LW5 = b;
LW7 = c;
}ถ้ายังไม่ได้สร้างตัวแปรใน Variable settings แล้วเขียนแบบนี้ (เช่นลอง LW6 = c;) จะ Compile ไม่ผ่าน
ตอนแสดงผลอย่าลืมตั้ง Numeric Display ให้ตรงชนิดข้อมูล — LW5 เลือก Data Type แบบ 32 bit ส่วน LW7 เลือก 32 bit Floating Point และกำหนดจำนวนตำแหน่งทศนิยม (ในคลิปใช้ 5 ตำแหน่ง) และเพิ่มจำนวนหลักให้พอสำหรับเลขยาว ผล Offline Simulate ได้ 100000 และ 3.14150
Array
Local Word ก็คือ Array แบบหนึ่ง เราเข้าถึงแต่ละตำแหน่งได้ด้วย Index (LocalWord[0], LocalWord[1], …) และสร้าง Array ของเราเองได้
#include "MacroInit.h"
//#include "subFun1.c" //Example
void Macro_main(IN *p)
{
MarcoInit
short myArray[] = { 42, 420, 4200 };
LocalWord[9] = myArray[0]; // 42
LocalWord[10] = myArray[1];
myArray[2] = 4242;
LocalWord[11] = myArray[2];
}- ประกาศชนิดข้อมูล ตั้งชื่อ ต่อด้วย
[]แล้วกำหนดค่าเริ่มต้นในปีกกา คั่นด้วยคอมมา — ตัวอย่างนี้คือ Array 3 ช่อง - เข้าถึงข้อมูลด้วย
myArray[index]โดย Index เริ่มจาก 0 —myArray[0]คือ 42 - แก้ค่าใน Array ได้ เช่น
myArray[2] = 4242;แล้ว Local Word 11 จะได้ 4242 ที่ถูกแก้แล้ว
ผล Offline Simulate: Local Word 9, 10, 11 = 42, 420, 4242
สั่ง PLC จาก Script
เรื่องสุดท้ายคือเปลี่ยนค่าของอุปกรณ์ภายนอก HMI ในคลิปต่อหลอดไฟไว้ที่ Y0 ของ PLC และอยากให้ไฟติดเมื่อ Script ทำงาน
- ใน Variable settings กด New สร้างตัวแปรชื่อ
Y0 - Data type เป็น bool เพราะเป็น Bit ของฝั่ง PLC
- Address เลือกจาก Link ที่ต่อกับ PLC (ในคลิปคือ COM2, FGs Series) ตำแหน่ง Y0 แล้วกด OK
- เขียนโค้ด
#include "MacroInit.h"
//#include "subFun1.c" //Example
void Macro_main(IN *p)
{
MarcoInit
Y0 = 1;
}ข้อมูลแบบ Boolean มีได้แค่ True หรือ False (1 หรือ 0) จึงเขียน Y0 = true; แทนก็ได้
- Compile แล้วต่อสาย USB-C Download ลงหน้าจอจริง — พอหน้าจอเปิดขึ้นมา Init Script ทำงานและหลอดไฟที่ Y0 ติดทันที
สรุป
- Script ของ HMI ซีรีส์ SK เขียนด้วยภาษา C ใน Script Editor เขียนโค้ดใต้
//ToDoและปิดทุกคำสั่งด้วย Semicolon - เลือกวิธี Run ได้ 3 แบบ: Global, Init และ Trigger Script
- ระวังชนิดข้อมูลและ Overflow — ค่าที่เกิน 16 bit จะถูกตัด
- ตัวแปรที่ผูกกับ Address ของ HMI หรือ PLC ต้องสร้างใน Variable settings ก่อนใช้
- Array เข้าถึงด้วย Index ที่เริ่มจาก 0
ตอนต่อไปจะพูดถึง If-Else การวนลูป ข้อมูลตัวอักษร และการสร้างฟังก์ชันเพื่อใช้ซ้ำ
ตอนถัดไป
13. if, else, loop และ String
มีคำถาม? ติดต่อทีมงาน
