ข้ามไปที่เนื้อหา

การเชื่อมต่อ Modbus / PLC

เกตเวย์นี้ติดตั้ง node-red-contrib-modbus มาพร้อมกับ Node-RED — ชุดโหนด สำหรับสื่อสารกับ PLC และอุปกรณ์อื่นผ่าน Modbus (serial หรือ TCP) กรอง palette ด้วยคำว่า "modbus" เพื่อดูชุดโหนดทั้งหมด:

โหนด Modbus ใน palette

โหนด หน้าที่
Modbus - Read อ่าน register/coil หนึ่งรายการขึ้นไปตามตารางเวลาหรือทริกเกอร์
Modbus - Write เขียนค่าไปยัง register/coil
Modbus - Getter อ่าน register/coil เมื่อได้รับข้อความเข้ามา
Modbus - Flex - Getter เหมือน Getter แต่กำหนดตำแหน่งได้ยืดหยุ่นกว่าในแต่ละข้อความ
Modbus - Flex - Write เหมือน Write แต่กำหนดตำแหน่งได้ยืดหยุ่นกว่าในแต่ละข้อความ
Modbus - Response จัดรูปแบบ/จัดการผลตอบกลับดิบจากการอ่าน
Modbus - Response - Filter กรองผลตอบกลับ เช่น ส่งต่อเฉพาะค่าที่เปลี่ยนแปลง
Modbus - Server ให้เกตเวย์นี้ทำหน้าที่เป็น Modbus server ให้อุปกรณ์อื่นสอบถามได้
Modbus - Queue - Info รายงานคิวคำขอภายในของการเชื่อมต่อ Modbus
Modbus - Flex - Connector ตัวเชื่อมต่อระดับต่ำที่ปรับแต่งได้ สำหรับรูปแบบการ polling แบบกำหนดเอง
Modbus - Flex - Sequencer เรียงลำดับการทำงาน Modbus หลายรายการ
Modbus - Flex - FC ส่ง Modbus function code ที่ระบุโดยตรง

รูปแบบการใช้งานทั่วไป

โฟลว์อ่านค่าจาก PLC พื้นฐานจะมีลักษณะดังนี้: โหนด inject (หรือ timestamp/timer) ทริกเกอร์ตามช่วงเวลา → โหนด Modbus - Read อ่านช่วง register จาก PLC → โหนด function หรือ change ปรับรูปแบบผลลัพธ์ → โหนดเอาต์พุต (http request, mqtt out หรือเขียนเข้า SCADash ผ่าน API ของมัน) ส่งค่าต่อไป

ดับเบิลคลิกโหนด Modbus เพื่อตั้งค่า:

  • Connection — ที่อยู่ของ PLC, พอร์ต (502 สำหรับ Modbus TCP) และ unit ID การเชื่อมต่อเป็น Configuration Node ที่ใช้ร่วมกันได้ — ตั้งค่าครั้งเดียวแล้วนำไปใช้ซ้ำกับโหนด Modbus หลายตัวได้
  • Register type and address — พื้นที่ข้อมูล Modbus ใด (coil, discrete input, holding register, input register) และตำแหน่งเริ่มต้นที่จะอ่านหรือ เขียน
  • Polling / trigger behavior — แตกต่างกันไปตามโหนด โดยทั่วไป Read node จะ poll ตามช่วงเวลา ส่วน Getter node จะตอบสนองต่อข้อความที่เข้ามา แทน

Note

ที่อยู่ที่แน่นอนและชนิด register ขึ้นอยู่กับ Modbus map ของ PLC ของคุณ เองทั้งหมด — ให้ดูเอกสารของ PLC ว่ามีอะไรอยู่ที่ตำแหน่งใด

การเชื่อมต่อกับอุปกรณ์ Modbus RTU

ฟิลด์ Server ของทุกโหนด Modbus จะชี้ไปยัง config node ของการเชื่อมต่อ ที่ใช้ร่วมกัน (modbus-client) คลิกไอคอนดินสอข้าง Server เพื่อแก้ไขตัวที่ มีอยู่ หรือ + เพื่อเพิ่มใหม่ แล้วตั้งค่า Type เป็น Serial หรือ Serial Expert:

modbus-client config node ตั้งค่า Type เป็น Serial Expert

ฟิลด์ หมายเหตุ
Serial port เส้นทางของ serial device บนเกตเวย์ เช่น /dev/ttyUSB0
Serial type RTU, RTU-BUFFERD, หรือ ASCII
Baud rate 115200 ลงไปถึง 75 — ต้องตรงกับอุปกรณ์
Data Bits 8, 7, 6, หรือ 5
Stop Bits 1, 1.5, หรือ 2
Parity None, Even, Mark, Odd, หรือ Space
Connection delay (ms) เฉพาะ Serial Expert — หน่วงเวลาหลังเปิดพอร์ตก่อนเริ่มสื่อสาร มีประโยชน์กับตัวแปลง RS-485 ที่ต้องใช้เวลาสลับทิศทาง
Unit-Id ที่อยู่ slave เริ่มต้นสำหรับโหนดที่ไม่ได้กำหนดค่าทับต่อข้อความ
Timeout (ms) ระยะเวลารอผลตอบกลับก่อนถือว่าล้มเหลว
Reconnect on timeout เปิดพอร์ตใหม่อัตโนมัติหลัง timeout

สำหรับอุปกรณ์ที่เชื่อมต่อผ่าน TCP (หรือเกตเวย์แปลง Modbus TCP-เป็น-RTU) ให้ใช้ Type: TCP แทน — กรอก Host, Port (ค่าเริ่มต้น 502) และตั้ง TCP Type เป็น RTU-BUFFERED หากอุปกรณ์นั้นเชื่อมต่อไปยังอุปกรณ์ RTU อีกฝั่งจริง ๆ:

modbus-client config node ตั้งค่า Type เป็น TCP

อุปกรณ์ RTU แบบ serial ทุกตัวที่ใช้พอร์ตเดียวกันต้องใช้ config node modbus-client ตัวเดียวกัน — นี่คือสิ่งที่ทำให้การเชื่อมต่อถูกใช้ร่วมกันและ เรียงลำดับการเข้าถึงบัสอย่างเป็นระเบียบ แทนที่จะให้สองโหนดแย่งใช้ serial port เดียวกัน

ตัวอย่าง: การอ่านและเขียนด้วย function code ผ่านโหนด Flex

โหนด Flex - Getter และ Flex - Write ไม่มีการตั้งค่า register/ function-code ตายตัวในกล่องแก้ไขเลย — แต่จะอ่าน Modbus function code, address และ quantity จาก msg.payload ทุกครั้งที่มีข้อความเข้ามาแทน ทำให้ เหมาะสำหรับกรณีที่ต้องการเลือก function code แบบไดนามิก (register ต่างกัน ในแต่ละรอบ polling, โฟลว์ "อ่านอะไรก็ได้" ทั่วไป ฯลฯ) แทนที่จะกำหนดการอ่าน ตายตัวไว้ในแต่ละโหนด

การอ่าน (Flex - Getter)

โหนด function สร้างคำขอ, โหนด Modbus - Flex - Getter อ่านค่า และ โหนด debug แสดงผลลัพธ์:

function → Modbus Flex Getter → debug เชื่อมต่อกัน

โค้ดของโหนด function:

msg.payload = {
    fc: 3,        // function code: 3 = Read Holding Registers
    unitid: 5,    // ที่อยู่ slave RTU ของอุปกรณ์บนบัส
    address: 0,   // ตำแหน่ง register เริ่มต้น
    quantity: 10  // จำนวน register ที่จะอ่าน
};
return msg;

function code ที่ Flex - Getter รองรับ (การอ่านทั้งหมด):

fc ความหมาย
1 Read Coil Status
2 Read Input Status
3 Read Holding Registers
4 Read Input Registers

ดับเบิลคลิกโหนด Flex - Getter เองแล้วตั้งค่า Server ให้ชี้ไปยังการ เชื่อมต่อ modbus-client ของอุปกรณ์ RTU ของคุณ (ดูด้านบน) — โหนดนี้ต้องการ แค่การเชื่อมต่อนั้นบวกกับสิ่งที่ส่งเข้ามาใน msg.payload

การเขียน (Flex - Write)

รูปแบบเดียวกัน แต่ใช้โหนด Modbus - Flex - Write แทน:

function → Modbus Flex Write → debug เชื่อมต่อกัน

// Single coil (FC5) — value ต้องเป็น true/false หรือ 1/0
msg.payload = { fc: 5, unitid: 5, address: 0, quantity: 1, value: true };

// Single register (FC6) — value เป็นตัวเลขเดียว 0-65535
// msg.payload = { fc: 6, unitid: 5, address: 0, quantity: 1, value: 1234 };

// Multiple registers (FC16) — value เป็น array ของตัวเลข 0-65535 แต่ละตัว
// msg.payload = { fc: 16, unitid: 5, address: 0, quantity: 3, value: [100, 200, 300] };

return msg;

function code ที่ Flex - Write รองรับ (การเขียนทั้งหมด):

fc ความหมาย value
5 Force Single Coil true/false หรือ 1/0
6 Preset Single Register ตัวเลขเดียว 0–65535
15 Force Multiple Coils array ของค่า boolean
16 Preset Multiple Registers array ของตัวเลข แต่ละตัว 0–65535

เช่นเดียวกับ Flex - Getter ให้ตั้งค่าฟิลด์ Server ของโหนดให้ชี้ไปยังการ เชื่อมต่อ modbus-client ของอุปกรณ์คุณ แล้วทริกเกอร์โหนด function (โหนด inject, ค่าที่ส่งเข้ามาจากที่อื่นในโฟลว์ ฯลฯ) ทุกครั้งที่ต้องการเขียนค่า

Note

unitid ในข้อความจะแทนที่ Unit-Id เริ่มต้นของการเชื่อมต่อ — มีประโยชน์ เมื่ออุปกรณ์ RTU หลายตัวใช้ serial port ร่วมกัน และคุณต้องเลือกว่าจะ คุยกับตัวไหนในแต่ละข้อความ