สื่อสารผ่าน Modbus TCP/IP

การสื่อสารผ่าน Modbus TCP/IP

 การสื่อสารผ่าน Modbus TCP/IP

โปรโตคอลยอดนิยมที่ใช้กันอย่างกว้างขวางในวงการอุตสาหกรรมคงหนีไม่พ้น Modbus ซึ่งมีทั้ง Modbus RTU และ Modbus TCP ถึงแม้ว่าในปัจจุบันจะมีโปรโตคอลอื่นๆที่มีสมถรรนะที่ดีกว่า Modbus มากมาย  แต่ Modbus ก็ยังเป็นโปรโตคอลคลาสสิคและได้รับความนิยมจนถึงทุกวันนี้  ซึ่งโปรโตคอล Modbus ได้รับการพัฒนาขึ้นตั้งแต่ปี พ.ศ. 2522 โดย Modicon Incorporated เพื่อใช้กับระบบควบคุมอัตโนมัติสำหรับอุตสาหกรรมและคอนโทรลเลอร์    และมันได้กลายเป็นวิธีการมาตรฐานในอุตสาหกรรมสำหรับการถ่ายโอนข้อมูลแบบ on/off และแบบอนาลอกตั้งแต่นั้นเป็นต้นมา

อุปกรณ์ที่สื่อสารด้วย Modbus โดยใช้วิธีการ Master-Slave (หรือ Client-Server) จะมีอุปกรณ์เพียงตัวเดียวซึ่งคือ Master (หรือ Client) สามารถเริ่มต้นการสื่อสารได้เท่านั้น (queries)  ส่วนอุปกรณ์ตัวอื่น ๆ จะทำหน้าที่เป็น Slaves (หรือ servers) จะตอบสนองต่อการสื่อสารนั้น โดย Slave จะส่งข้อมูลที่ร้องขอกลับไปยัง Master หรือโดยการดำเนินการบางอย่างตามที่ Master ร้องขอ

Slave อาจเป็นอุปกรณ์ต่อพ่วงใด ๆ (I/O transducer, วาล์ว, Inverter (VFD)หรืออุปกรณ์เครื่องมือวัดอื่นๆ)  ซึ่งประมวลผลและส่งข้อมูลไปยัง Master   รูปข้างล่างนี้แสดงการสื่อสารระหว่าง Master กับ Slave

รูปที่ 1

Master สามารถติดต่อกับ Slave แต่ละตัวได้ หรือสามารถส่งเป็น Message ถึง Slave ทุกตัวได้ในลักษณะของการ Broadcast และ Slave จะตอบสนองสิ่งที่ Master ต้องการเท่านั้น    สิ่งที่ Master ส่งให้จะประกอบด้วย Slave address, function code (คำสั่งหรือสิ่งที่ต้องการให้ทำ), Data และ Checksum   ส่วนข้อมูลที่ Slave ส่งกลับมาจะประกอบด้วยคำสั่งที่สั่งให้กระทำ  ข้อมูลต่างๆ และ Checksum

Modbus TCP/IP คือ อะไร

Modbus TCP/IP (Modbus-TCP) คือ โปรโตคอล Modbus RTU ที่เชื่อมต่อด้วย TCP โดยทำงานบนสถาปัตยกรรมของ Ethernet   โครงสร้าง Message ของ Modbus คือ application protocol ที่จะถูกส่งผ่านไปพร้อมกับ TCP/IP (TCP/IP คือ Transmission Control Protocol และ Internet Protocol ซึ่งเป็นตัวกลางที่ใช้ในการส่ง Message ของ Modbus TCP/IP)

ตารางข้างบนนี้แสดงชนิดของ Data และ Address ที่ใช้กับ Modbus RTU ซึ่งถูกใช้งานเช่นเดียวกันใน Modbus TCP/IP

ส่วนตารางข้างล่างนี้แสดงชนิด Function และ Function code ของ Modbus RTU ที่ใช้สำหรับอ่านและเขียนข้อมูลซึ่งเราต้องใส่ไว้ใน Modbus RTU data frame

ในทางปฏิบัติ Modbus TCP จะฝัง Modbus RTU data frame ร่วมไปกับ TCP frame โดยไม่ต้องใช้ Modbus checksum แต่จะใช้ Checksum ของ TCP แทนดังแสดงในรูปที่ 2

รูปที่ 2

จากรูปที่ 2 Modbus Application Protocol (MBAP) จะประกอบด้วยข้อมูล 7 bytes ซึ่งจะวางหน้า Modbus RTU message โดยมีรายละเอียดดังนี้

  • Transaction/invocation Identifier (2 Bytes): ใช้จับคู่การแลกเปลี่ยนข้อมูลเมื่อมี Message หลายๆ ชุด ถูกส่งออกมาด้วย TCP เดียวกัน ด้วย Client ตัวใดตัวหนึ่ง โดยไม่ต้องรอลำดับการ Response
  • Protocol Identifier (2 bytes): ในส่วนจะมีค่าเป็น 0 เสมอ
  • Length (2 bytes): เป็นการระบุจำนวน Byte ที่รวมจำนวน Byte ของ unit identifier, function code, และ data fields
  • Unit Identifier (1 byte): เป็นการระบุ ID ของ server ที่อยู่ในระบบสื่อสาร อาจตั้งเป็น 00 ถึง FF ก็ได้

ตัวอย่าง Modbus TCP message

เราลองมาดูตัวอย่างโปรโตคอล Modbus RTU สำหรับอ่านค่าอนาลอกเอาท์พุตของ Holding register แอดเดรส 40108 ถึง 40110 จาก Slave หมายเลข 17

11 03 006B 0003 7687
11: SlaveID Address (17 = 11 hex)
03: Function Code (read Analog Output Holding Registers)
006B: Data Address ของ register ตัวแรก (40108-40001 = 107 =6B hex)
0003: จำนวน registers ที่ต้องการอ่าน (อ่าน 3 ตัว 40108 ถึง 40110)
7687: เป็น CRC (cyclic redundancy check) สำหรับเช็คความผิดพลาด

เมื่อนำไปรวมกับ MBAP จะได้รายละเอียดโปรโตคอล Modbus TCP ดังนี้ ซึ่ง Frame checksum (CRC) จะถูกตัดออกไป

0001 0000 0006 11 03 006B 0003

0001: Transaction Identifier
0000: Protocol Identifier
0006: Message Length (6 bytes ที่อยู่ตำแหน่งถัดไปจาก Byte นี้)
11:     Unit Identifier  (17 = 11 hex)
03:     Function Code (อ่านค่า Analog Output Holding Registers)
006B: Data Address ของ register ตัวแรก (40108-40001 = 107 =6B hex)
0003: จำนวน registers ที่ต้องการอ่าน (อ่าน 3 ตัว 40108 ถึง 40110)

สมมุติว่าคุณต้องการเขียนโปรแกรม VB เพื่ออ่านข้อมูล Holding register จาก Slave หมายเลข 1 โดย Function code เพื่ออ่านค่าข้อมูลจาก Holding register ซึ่งก็คือ 3 นั้นเอง สามารถดูตัวอย่างการเขียนโปรแกรมได้ดังตัวอย่างข้างล่างนี้  การส่ง Message ผ่าน TCP/IP จะใช้ winsock ของ VB โดยค่า Remote port ที่ตั้งจะเป็น 502 ซึ่งเป็นค่าปกติของ Modbus TCP/IP

รูปที่ 3

ข้างล่างนี้คือตัวอย่างโค้ด Visual Basic สำหรับการสื่อสารในรูปแบบ Modbus TCP

Private Sub ReadLW_Click()

‘Byte 0   : transaction identifier (upper byte) – copied by server – usually 0
‘Byte 1   : transaction identifier (lower byte) – copied by server – usually 0
‘Byte 2   : protocol identifier (upper byte) = 0
‘Byte 3   : protocol identifier (lower byte) = 0
‘Byte 4   : length field (upper byte)
‘Byte 5   : length field (lower byte) = number of bytes following
‘Byte 6   : unit identifier (slave address)
‘Byte 7   : MODBUS function code
‘Byte 8   : address of register (upper byte)
‘Byte 9   : address of register (lower byte)
‘Byte 10 : number of register as need (upper byte)
‘Byte 11 : number of register as need (lower byte)

‘The Mod operator returns the remainder of a division. For example, the expression 14 Mod 4 evaluates to 2
‘The \ Operator returns the integer quotient of a division. For example, the expression 14 \ 4 evaluates to 3
‘The Val function returns number of a string (convert string to number)

Dim StartLow As Byte
Dim StartHigh As Byte
Dim LengthLow As Byte
Dim LengthHigh As Byte
If (Winsock1.State = 7) Then
StartLow = Val(AdssLW.Text) Mod 256
StartHigh = Val(AdssLW.Text) \ 256
LengthLow = Val(NoOfWord.Text) Mod 256
LengthHigh = Val(NoOfWord.Text) \ 256
MbusQuery(0) = 0
MbusQuery(1) = 0
MbusQuery(2) = 0
MbusQuery(3) = 0
MbusQuery(4) = 0
MbusQuery(5) = 6    ‘6 Hex :Length field, there are 6 byte count from Unit ID to the last byte
MbusQuery(6) = 1    ‘1 Hex :Unit ID (Slave address)
MbusQuery(7) = 3    ‘3 Hex :Function code READ multiple holding register
MbusQuery(8) = StartHigh
MbusQuery(9) = StartLow
MbusQuery(10) = LengthHigh
MbusQuery(11) = LengthLow
MbusRead = True
MbusWrite = False

Winsock1.SendData MbusQuery

ModbusWait = True
ModbusTimeOut = 0
Timer1.Enabled = True
MbusReadByteOrBit = True

Else

MsgBox (“Device not connected via TCP/IP”)

End If

End

จากตัวอย่างโค้ด VB ข้างบนเมื่อเรา Compile แล้ว โปรแกรมที่ได้จะทำงานบนคอมพิวเตอร์ซึ่งจะทำหน้าที่เป็น Master และสามารถใช้โปรแกรมนี้เพื่อเชื่อมต่อกับ Slave ที่รองรับโปรโตคอล Modbus TCP ได้  นอกจากนั้นเราสามารถใช้หลักการเดียวกันนี้เพื่อนำไปประยุกต์ใช้กับการเขียนโปรแกรม PLC เพื่อเชื่อมต่อกับอุปกรณ์ที่รองรับ Modbus TCP ได้