跳至主要内容

MC Protocol Communication Function

本文件整理自 KV-XCM02 User's Manual Chapter 6。 MC Protocol = MELSEC Communication Protocol,由 Mitsubishi Electric 制定的業界標準協定。 Keyence KV 系列 PLC 支援 QnA 相容 3E frame 與 4E frame,編碼可選 binary 或 ASCII。

協定特性

特性說明
編碼Binary(推薦)或 ASCII
傳輸TCP/IP port 5000(預設)/ UDP/IP 5000
Frame 結構QnA 相容 3E4E(4E 多 serial No. 用於 response 對應)
連線數15 sockets(TCP,與 Modbus / Host Link 共享)
Server / ClientKV PLC = server,PC = client
並發支援多 client 同時連線
Device 命名Mitsubishi 標準命名(M / D / X / Y / R 等,非 Keyence 原生)

為什麼選 MC Protocol

場景MC Protocol 適合度
與 Mitsubishi PLC 互相轉換⭐⭐⭐⭐⭐
用社群成熟 .NET / Python 函式庫⭐⭐⭐⭐⭐(McpX / MCProtocol-NET / HslCommunication 等)
高速大量 IO(>100 Hz)⭐⭐⭐⭐(binary 效率高)
自寫 framing⭐⭐⭐(比 Host Link 複雜,但有公開規格)
現場 debug(telnet)⭐⭐(binary 不易看,ASCII mode 較好但較少用)
程式碼 review / 客戶接手⭐⭐⭐(依靠成熟 lib,可讀性中等)

Frame 結構

整體結構

[Header] [Subheader] [Network No.] [PC No.] [Request dest I/O No.]
[Request dest station] [Request data length] [CPU monitor timer]
[Command] [Subcommand] [Request data]

3E vs 4E

FrameSubheader (request)Subheader (response)多餘欄位
3E0x50 0x00 (binary) / 5000 (ASCII)0xD0 0x00 / D000
4E0x54 0x00 / 54000xD4 0x00 / D400+ 2-byte Serial No.(用於 async response 對應)

固定欄位(傳給 KV-XCM02 時)

欄位
Network No.0x00
PC No.0xFF
Request destination unit I/O No.0x03FF
Request destination unit station No.0x00
CPU monitor timer任意(PLC 忽略此值,但必須填)

限制

  • 從 subheader 到 request data 的總長度 不可超過 8194 bytes

Communication Principle

TCP/IP Mode

3E Binary Request 範例(讀 D0 一個 word)

50 00              ← Subheader (3E request)
00 ← Network No.
FF ← PC No.
FF 03 ← Request dest I/O (LH)
00 ← Request dest station
0C 00 ← Request data length = 12 bytes (LH)
10 00 ← CPU monitor timer (4 sec, LH)
01 04 ← Command 0401 (Batch Read, LH)
00 00 ← Subcommand 0000 (word) (LH)
00 00 00 ← Device address D0 (3 bytes, LH)
A8 ← Device code D = 0xA8
01 00 ← Number of devices = 1 word (LH)

3E Binary Response 範例

D0 00              ← Subheader (3E response)
00 ← Network No.
FF ← PC No.
FF 03 ← Request dest I/O
00 ← Request dest station
04 00 ← Response data length = 4 bytes (LH)
00 00 ← End code = 0x0000 (success) (LH)
39 30 ← D0 value = 0x3039 = 12345 (LH)

完整指令清單

功能CommandSubcommandData Unit
Batch read04010001bit
Batch read04010000word
Batch write14010001bit
Batch write14010000word
Random read04030000word
Random write14020001bit
Random write14020000word
Register monitor08010000
Read monitor08020000
Batch read multiple blocks04060000word
Batch write multiple blocks14060000word
Read buffer memory06130000word
Write buffer memory16130000word
Read intelligent unit buffer06010000byte
Write intelligent unit buffer16010000byte
Remote RUN10010000
Remote STOP10020000
Read CPU model01010000
Loopback test06190000

機型查詢回應(0101 指令)

Read CPU Model 回應:

KV 機型Model ASCIIModel Code (binary)
KV-X550VX5503FH
KV-X530VX5303DH
KV-X520VX5203CH
KV-X500VX5003EH
KV-X310VX3103BH
KV-8000V800039H
KV-8000AV8000A3AH
KV-7500V750037H
KV-7300V730036H

Model 字串不足 16 byte 時,後面補 0x20(space)至 16 byte。

Device Code 對照(KV ↔ MC Protocol)

KV NativeMC Protocol DeviceASCIIBinary範圍
R (Relay)X(Y)0000-X(Y)7CFFX* / Y*9C / 9D0-199915 (KV-7/8000)
B (Link relay)B0000-B7FFFB*A00-7FFF (hex)
MR (Internal aux)M00000-M63999M*900-63999
LR (Latch relay)L00000-L15999L*920-15999
CR (Control relay)SM0000-SM1279SM910-1279
CM (Control memory)SD0000-SD7599SDA90-7599 (KV-8000)
DM (Data memory)D00000-D65534D*A80-65534
EM (Extended DM)D100000-D165534D*A80-65534
FM (File register)R00000-R32767R*AF0-32767
ZF (File register ext)ZR00000-ZR7FFFFZRB00-524287 (hex)
W (Link register)W0000-W7FFFW*B40-7FFF (hex)
T Timer currentTN0000-TN3999TNC20-3999
T Timer contactTS0000-TS3999TSC10-3999
C Counter currentCN0000-CN3999CNC50-3999
C Counter contactCS0000-CS3999CSC40-3999

Device No. 在 MC Protocol 中為 hexadecimal(其他 device 為 decimal)。 ASCII 命名中的 * 為對齊用的 0x2A(asterisk),實際格式:M* = 0x4D 0x2A

重要實作細節

Bit-by-bit 表達(讀寫位元,5 個 M-relay 從 M10 開始)

ASCII:

M*00010 0005 1 0 1 1 0
↑ ↑ ↑ ↑ ↑ ↑
Lead M14 M13 M12 M11 M10 (注意順序:上位 → 下位)
device ON OFF ON ON OFF

Binary:

00 00 0A    ← Leading device M10 (3 bytes LH)
90 ← Device code (M)
05 00 ← Number of devices = 5 (LH)
10 11 10 ← Data (4-bit pack, even number 補 0)

Word 表達(讀寫 word,2 個 D-register 從 D350)

D*00350 0002 56AB 170F
↑ ↑ ↑
Lead D350 D351
=22187 =5903 (decimal)

Bit-by-word 表達(讀位元但用 16-bit 為單位)

當需要批次讀大量 bit 時,可用 word 為單位,每 16 個 bit 打包成 1 個 hex word。位元順序為 H → L

例:M16 起 32 個 bit 讀回 = AB12 34CD

M16 = bit 0 of (AB12 → bit15...bit0 = 1010101100010010)
所以 M16=0, M17=1, M18=0, ..., M31=1
M32 = bit 0 of 34CD

32-bit data atomicity

寫 32-bit 資料(Random Write 0x1402)時,只在 device No. 為偶數時保證上下 16-bit 同時更新

錯誤碼

End Code = 0x0000 表示成功;非 0 為錯誤。

Code說明
0xC050ASCII / binary 通訊不一致
0xC051-0xC054Frame 解析錯誤
0xC056Subcommand 錯
0xC059Command / subcommand 不支援
0xC05BDevice 範圍錯
0xC05C通訊資料長度超限
0xC05DCPU 監視 timer 錯
0xC05F此 PLC 不支援該 command
0xC0B5不可寫入(保護中)

完整列表見 KV-XCM02 User's Manual Appendix。

.NET 實作建議

直接 binary frame(自寫)

private static byte[] BuildBatchReadCommand(byte deviceCode, ushort address, ushort count)
{
var frame = new byte[21];
frame[0] = 0x50; frame[1] = 0x00; // Subheader 3E
frame[2] = 0x00; // Network No.
frame[3] = 0xFF; // PC No.
frame[4] = 0xFF; frame[5] = 0x03; // Dest I/O (LH)
frame[6] = 0x00; // Dest station
frame[7] = 0x0C; frame[8] = 0x00; // Data length = 12
frame[9] = 0x10; frame[10] = 0x00; // CPU timer
frame[11] = 0x01; frame[12] = 0x04; // Command 0401
frame[13] = 0x00; frame[14] = 0x00; // Subcommand 0000 (word)
frame[15] = (byte)(address & 0xFF);
frame[16] = (byte)((address >> 8) & 0xFF);
frame[17] = 0x00; // Address bit 16-23 (always 0 for KV)
frame[18] = deviceCode; // 0xA8 for D
frame[19] = (byte)(count & 0xFF);
frame[20] = (byte)((count >> 8) & 0xFF);
return frame;
}

用 McpX (NuGet)

using McpXLib;

using var mcpx = new McpX("192.168.0.10", 5000);

// 讀 D0..D9
short[] words = mcpx.BatchRead<short>(Prefix.D, "0", 10);

// 寫 M10 = ON
mcpx.BatchWrite<bool>(Prefix.M, "10", new bool[] { true });

// 讀 32-bit unsigned
uint dword = mcpx.Read<uint>(Prefix.D, "100");

Prefix.M 對應 KV MRPrefix.D 對應 KV DM。詳見 Device Codes 對照表

Telnet debug(不容易但可行)

3E binary frame 用 telnet 不可讀。改用 ASCII frame:

5000 00FF03FF000018  0010  0401 0000  D*0000000  0001
↑ ↑ ↑ ↑ ↑ ↑
3E PC... Len Cmd Device Count

或用 PowerShell 寫 binary:

$client = New-Object System.Net.Sockets.TcpClient("192.168.0.10", 5000)
$stream = $client.GetStream()
$frame = [byte[]]@(0x50,0x00,0x00,0xFF,0xFF,0x03,0x00,0x0C,0x00,0x10,0x00,
0x01,0x04,0x00,0x00,0x00,0x00,0x00,0xA8,0x01,0x00)
$stream.Write($frame, 0, $frame.Length)

$buf = New-Object byte[] 256
$len = $stream.Read($buf, 0, $buf.Length)
[BitConverter]::ToString($buf[0..($len-1)])

參考