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 相容 3E 或 4E(4E 多 serial No. 用於 response 對應) |
| 連線數 | 15 sockets(TCP,與 Modbus / Host Link 共享) |
| Server / Client | KV 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
| Frame | Subheader (request) | Subheader (response) | 多餘欄位 |
|---|---|---|---|
| 3E | 0x50 0x00 (binary) / 5000 (ASCII) | 0xD0 0x00 / D000 | — |
| 4E | 0x54 0x00 / 5400 | 0xD4 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)
完整指令清單
| 功能 | Command | Subcommand | Data Unit |
|---|---|---|---|
| Batch read | 0401 | 0001 | bit |
| Batch read | 0401 | 0000 | word |
| Batch write | 1401 | 0001 | bit |
| Batch write | 1401 | 0000 | word |
| Random read | 0403 | 0000 | word |
| Random write | 1402 | 0001 | bit |
| Random write | 1402 | 0000 | word |
| Register monitor | 0801 | 0000 | — |
| Read monitor | 0802 | 0000 | — |
| Batch read multiple blocks | 0406 | 0000 | word |
| Batch write multiple blocks | 1406 | 0000 | word |
| Read buffer memory | 0613 | 0000 | word |
| Write buffer memory | 1613 | 0000 | word |
| Read intelligent unit buffer | 0601 | 0000 | byte |
| Write intelligent unit buffer | 1601 | 0000 | byte |
| Remote RUN | 1001 | 0000 | — |
| Remote STOP | 1002 | 0000 | — |
| Read CPU model | 0101 | 0000 | — |
| Loopback test | 0619 | 0000 | — |
機型查詢回應(0101 指令)
Read CPU Model 回應:
| KV 機型 | Model ASCII | Model Code (binary) |
|---|---|---|
| KV-X550 | VX550 | 3FH |
| KV-X530 | VX530 | 3DH |
| KV-X520 | VX520 | 3CH |
| KV-X500 | VX500 | 3EH |
| KV-X310 | VX310 | 3BH |
| KV-8000 | V8000 | 39H |
| KV-8000A | V8000A | 3AH |
| KV-7500 | V7500 | 37H |
| KV-7300 | V7300 | 36H |
Model 字串不足 16 byte 時,後面補
0x20(space)至 16 byte。
Device Code 對照(KV ↔ MC Protocol)
| KV Native | MC Protocol Device | ASCII | Binary | 範圍 |
|---|---|---|---|---|
R (Relay) | X(Y)0000-X(Y)7CFF | X* / Y* | 9C / 9D | 0-199915 (KV-7/8000) |
B (Link relay) | B0000-B7FFF | B* | A0 | 0-7FFF (hex) |
MR (Internal aux) | M00000-M63999 | M* | 90 | 0-63999 |
LR (Latch relay) | L00000-L15999 | L* | 92 | 0-15999 |
CR (Control relay) | SM0000-SM1279 | SM | 91 | 0-1279 |
CM (Control memory) | SD0000-SD7599 | SD | A9 | 0-7599 (KV-8000) |
DM (Data memory) | D00000-D65534 | D* | A8 | 0-65534 |
EM (Extended DM) | D100000-D165534 | D* | A8 | 0-65534 |
FM (File register) | R00000-R32767 | R* | AF | 0-32767 |
ZF (File register ext) | ZR00000-ZR7FFFF | ZR | B0 | 0-524287 (hex) |
W (Link register) | W0000-W7FFF | W* | B4 | 0-7FFF (hex) |
T Timer current | TN0000-TN3999 | TN | C2 | 0-3999 |
T Timer contact | TS0000-TS3999 | TS | C1 | 0-3999 |
C Counter current | CN0000-CN3999 | CN | C5 | 0-3999 |
C Counter contact | CS0000-CS3999 | CS | C4 | 0-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 | 說明 |
|---|---|
0xC050 | ASCII / binary 通訊不一致 |
0xC051-0xC054 | Frame 解析錯誤 |
0xC056 | Subcommand 錯 |
0xC059 | Command / subcommand 不支援 |
0xC05B | Device 範圍錯 |
0xC05C | 通訊資料長度超限 |
0xC05D | CPU 監視 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 MR,Prefix.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)])
參考
- KV-XCM02 User's Manual Chapter 6(O24GB 版,2024-10)
- Mitsubishi SLMP Reference Manual(公開)
- 相關文件: