主题
pipe "mc" — 三菱 MC 协议
协议名:"mc"
三菱 Q / L 系列 PLC 的 MC 协议(以太网)。管道对象的读写方法、返回值约定和错误码都和 7.1 Pipe 通信概述 一致,本页只讲 MC 协议特有的创建方式和地址格式。
平台限制
本协议只在上位机版本和 Linux 网关版本里提供,ESP32 机型不支持,在 ESP32 上 pipe.setup("mc", ...) 会返回 nil。
ESP32 上访问三菱 PLC 请用 "fx"(FX 编程口协议)。
创建管道
lua
pipe.setup("mc", "ip[:port]") --> pipe | nil第二个参数是字符串,不是 table。
| 形式 | 说明 |
|---|---|
"192.168.1.100:502" | 指定 IP 和端口 |
"192.168.1.100" | 用默认端口 502 |
lua
mc = pipe.setup("mc", "192.168.1.100:502")
if not mc then print("创建失败") end说明
- 默认端口是
502。三菱 MC 协议实际端口取决于 PLC 侧以太网模块配置(常见 5000 / 6000),按 PLC 参数填写。 - 网络号、站号、请求目标模块 I/O 号在代码里固定,不能从 Lua 侧配置。
地址格式
前缀 + 十进制编号,没有位小数点形式。
| 前缀 | 软元件 | 类型 |
|---|---|---|
M | 辅助继电器 | 位 |
X | 输入 | 位 |
Y | 输出 | 位 |
S | 状态 | 位 |
D | 数据寄存器 | 字 |
W | 链接寄存器 | 字 |
T | 定时器 | 字 |
C | 计数器 | 字 |
lua
mc:read_u16("D100") -- 读 D100
mc:read_u16("D100", 10) -- 读 D100 起 10 个字
mc:read_bite("M100") -- 读 M100
mc:write_bite("M100", true)
mc:write_u16("D100", 1234)说明
- 编号是十进制。X / Y 在三菱编程软件里习惯用十六进制编号,这里一律写十进制点号。
- 位地址不用小数点:读 M100 就写
"M100",不是"M100.0"。 - 代码里不做地址范围检查,超范围时错误由 PLC 应答报出(
errno为8109)。 read_string的第 2 个参数是字符数,默认10,内部换算成(长度+1)/2个字。
可用方法
16 个类型化读写方法全部可用,用法见 7.1 的对象方法:
read_bite write_bite read_s16 write_s16 read_u16 write_u16 read_s32 write_s32 read_u32 write_u32 read_float write_float read_double write_double read_string write_string
不可用:p:read() 和 p:write()(管道自身参数存取)在 MC 协议里没有实现,不要调用。
常见用法
lua
mc = pipe.setup("mc", "192.168.1.100:502")
function poll()
local ret = mc:read_u16("D100", 10)
if ret.errno == 0 then
for i = 1, 10 do plc.d(i, ret.data[i]) end
end
local bits = mc:read_bite("M0", 16)
if bits.errno == 0 and bits.data[1] == 1 then
print("M0 已置位")
end
end
t = timer.start(500, poll)相关协议:"mitsubishi_a"(A 系列串口)
三菱 A1S / A2S / A3A / A4A 系列走串口计算机链接(ASCII 帧)。同样只在上位机版本和 Linux 网关版本里提供。
lua
a = pipe.setup("mitsubishi_a", "COM1:9600")
a = pipe.setup("mitsubishi_a", "COM1") -- 默认 9600串口帧格式固定 7 数据位 + 偶校验 + 1 停止位,站号固定 0,都不可配。
地址:X / Y 为八进制(X 只读),M / S / D 为十进制,T / C 映射到 TN / CN 当前值。
只实现了 read_bite / write_bite、read_u16 / write_u16、read_s16 / write_s16。32 位、浮点、双精度、字符串方法全是空实现(读返回 nil,写返回失败)。p:read() / p:write() 未实现。
注意事项
- ESP32 固件不支持本协议,
pipe.setup直接返回nil。 - 管道对象要用全局变量长期持有,被 GC 回收会断连。
- 32 位和浮点的字序由 MC 协议规范固定,没有
format参数可调。 - 写方法返回整数错误码,读方法返回
{errno, data},两者不要混用。
例程
每个例程都是可直接下载运行的完整脚本(仅上位机 / Linux 网关版本,ESP32 上
pipe.setup("mc", ...)返回nil)。通用读写接口见 8.1 概述。统一模板「场景 / 完整代码 / 要点 / 验证方法 / 注意事项」。
例程 1:轮询三菱 Q/L 的 D 区和 M 位
适用:LP3232 / LP3288 / 软PLC模拟器 / 上位机(不含 ESP32)| 依赖模块:pipe timer plc | 难度:★☆☆
场景:三菱 Q/L 系列 PLC,每 500ms 把 D100 起 10 个字读到本机 D 区,并监控 M0 是否置位。
完整代码(可直接下载运行):
lua
mc = pipe.setup("mc", "192.168.1.100:502") -- 第二参是字符串 ip:port
if not mc then
print("创建失败(ESP32 不支持 mc 协议,请用 'fx')")
return
end
function poll()
local ret = mc:read_u16("D100", 10)
if ret.errno == 0 then
for i = 1, 10 do plc.d(i, ret.data[i]) end
end
local bits = mc:read_bite("M0", 16)
if bits.errno == 0 and bits.data[1] == 1 then
print("M0 已置位")
end
end
t = timer.start(500, poll)要点:
pipe.setup("mc", "192.168.1.100:502")—— 第二个参数是字符串(IP 或IP:端口),不是 table。- 地址用前缀 + 十进制编号,位地址没有小数点:
"M100"不是"M100.0"。 - ESP32 上
setup返回nil,必须判空再往下走。
验证方法:
- 在上位机 / Linux 网关版本运行,本机 D100~D109 出现三菱侧 D100~D109 的值。
- 三菱侧 M0 置位,日志打印"M0 已置位"。
注意事项:
- 第二参写成 table(
{ ip = ... })会被当成不支持,直接返回nil。 - ESP32 机型用
mc一定失败;要在 ESP32 上访问三菱 PLC 请用"fx"(FX 编程口协议)。 - X/Y 在三菱软件里习惯十六进制编号,这里一律写十进制点号(如
X10表示第 16 点)。
例程 2:把数据写回三菱 PLC(写方法返回整数错误码)
适用:同上 | 依赖模块:pipe | 难度:★☆☆
场景:把本机的计算结果写到三菱 D200,并置位 M50。
完整代码(可直接下载运行):
lua
local mc = pipe.setup("mc", "192.168.1.100:502")
if not mc then return end
local err = mc:write_u16("D200", 1234)
if err == 0 then print("写 D200 成功") end
local e2 = mc:write_bite("M50", true)
print("写 M50:", e2 == 0 and "成功" or "失败")要点:
- 写方法返回整数错误码,
0成功;value可单个或数组一次写多个。 - 读方法才返回
{ errno, data }——两者结构不同,别混用。
验证方法:三菱侧监视 D200 = 1234、M50 = 1。
注意事项:把写结果当 table 去查 result.errno,整数没有 errno 字段,判断永远为真;务必 err == 0。
例程 3:注意事项——在 ESP32 上用 mc / 第二参写成 table
适用:同上 | 依赖模块:pipe | 难度:★☆☆
场景:最常见的两种误用:在 ESP32 上调用 mc,以及把第二参写成 table。
完整代码(可直接下载运行):
lua
-- ❌ 错误:第二参是 table,且 ESP32 根本不支持 mc → 创建失败返回 nil
local mc = pipe.setup("mc", { ip = "192.168.1.100" })
if not mc then print("mc 创建失败") end
-- ✅ 正确:上位机 / Linux 网关上,第二参用字符串
local mc = pipe.setup("mc", "192.168.1.100:502")
if not mc then
print("mc 创建失败(请确认平台支持,或改用 'fx')")
return
end要点:
mc协议只在上位机版本和 Linux 网关版本里提供,ESP32 不支持。- 第二参数类型是字符串(
"IP"或"IP:端口"),不是 table。
验证方法:正确写法在支持平台拿到对象;错误写法立即返回 nil,必须判空。
注意事项:ESP32 误用 mc 会得到 nil;想读三菱请用 "fx"(FX 编程口,串口或以太网均可)。mc 协议没有 p:read() / p:write() 管道参数方法,不要调用。