Skip to content

mc_server — 三菱 MC 协议从站服务器 ​

模块名:mc_server

让本机变成一台三菱 MC 协议从站(FX3U-ENET-ADP 兼容,1E 帧 / 格式 1),触摸屏(GT Designer)、组态软件或其它 MC 主机可以通过网络直接读写本机 PLC 软元件。协议解析和软元件映射固件已做好,脚本只要 start 一下,不用注册回调。

既能当主站,也能当从站

函数总览 ​

库级函数 ​

函数作用
mc_server.start([port, max_sockets, buffer_size])启动服务器

对象上只有 __gc,没有其它方法。被回收时自动停止服务。


mc_server.start ​

lua
mc_server.start([port, max_sockets, buffer_size]) --> server

启动 MC 协议从站并立即监听。

参数

#参数类型必填默认值说明
1portinteger否5000监听端口
2max_socketsinteger否1最大并发客户端数
3buffer_sizeinteger否1024每连接的收发缓冲区字节数

返回值

类型说明
userdata服务器对象。必须用全局变量接住,被 GC 回收会立刻停止服务

示例

lua
-- 5000 端口,允许 2 个客户端同时连
server = mc_server.start(5000, 2)

说明

  • 没有停止方法。要停就让持有它的变量置 nil 并等 GC,或重启脚本。
  • 没有任何身份认证,也不校验 PC 站号(报文里 PC 号必须是 0xFF,其它值会返回错误)。任何能连到端口的客户端都能读写本机 PLC。不要暴露在公网,放内网或用防火墙限制。
  • 同时支持 BIN 和 ASCII 两种帧格式,服务端按首字节自动识别,触摸屏侧选哪种都行。

实用例程 ​

lua
--开启mc协议服务器,端口为5000
mcs=mc_server.start(5000,4,1024)
--读取电表
state=data.creat(0)
dlt=com_dlt645.creat('<设备ID或凭据>',state)--建立电表驱动参数为表号12位表号2007广播表号
kwh=data.creat(0)
kw=data.creat(0)
dlt:add_channel(com_dlt645.KW_2007,kw);--读取功率
dlt:add_channel(com_dlt645.KWH_2007,kwh);--读取正向有功总电量到D0
com1=com.setup(1,2400,com.EVEN,8,1)--打开串口父设备2007表默认2400BPS
com1:add_device(dlt)--在串口父设备中加入电表子设备
com1:start()--启动串口父设备
local 倍率=1

  dssc=timer.start(5000,function()--启动定时器 5 秒发布一个数据
 local kwhreal=kwh:get_num()*倍率
 --local kwhreal = string.format("%.2f",kwh:get_num()*倍率)		
  local jsontable =
{
	name="<名称>",
	kw=kw:get_num()*倍率,
	kwh = kwhreal,
}
plc.df(200,kwhreal)--把电能浮点值保存到D200
local jsonstring = json.encode(jsontable)
--print(jsonstring)
print("<名称>",plc.df(200),"<名称>",plc.dd(204))	
end
)

把上面的地址、主题、引脚替换成你项目里的即可。

mc_server.creat / mc_server.set / mc_server.get_bool / mc_server.get_num / mc_server.get_string —— 本模块没有这些函数 ​

有些流传的 API 清单会把这五个名字挂在 mc_server 名下——那不可信。mc_server 模块从注册到运行只有 start 一个入口,对象上也只有回收用的 __gc。对服务器对象调用任何别的方法都会直接报错:

lua
server = mc_server.start(5000)
server:set(...)       --> 报错:attempt to call method 'set' (a nil value)

参数

这五个名字实际是 data 模块(共享变量对象)的库函数与对象方法,与 mc_server 无关:

  • creat —— 实际入口是 data.creat([初值]),创建一个值容器
  • set —— 实际入口是 d:set(值),往容器写值(只能用冒号写法)
  • get_num —— 实际入口是 d:get_num(),按数字读出
  • get_bool —— 实际入口是 d:get_bool(),按布尔读出
  • get_string —— 实际入口是 d:get_string(),按原始字节串读出

返回值

以 mc_server.* 形式调用一律报错、没有返回值;按 data.* 形式调用时的返回值见 data 模块文档。

示例

lua
-- 正确:这五个函数在 data 模块里,用法与 mc_server 无关
value = data.creat(0)
value:set(1)
print(value:get_num(), value:get_bool())      -- 1    true

支持的命令 ​

命令码作用一次上限
00成批读位(BR)256 点
01成批读字(WR)32 个字
02成批写位(BW)160 点
03成批写字(WW)10 个字
04随机写位(BT)80 点
05随机写字(WT)10 个字
0x13远程读(RR)—
0x14远程运行/停止(RS)—
0x15读 PLC 型号(PC)—
0x16回环测试(TT)—

其它命令返回格式错误(0x11)。

可访问的软元件 ​

位软元件(BR / BW / BT)

MC 软元件说明
X输入
Y输出
M辅助继电器
S状态
TS定时器触点
CS计数器触点

字软元件(WR / WW / WT)

MC 软元件说明
D数据寄存器
TN定时器当前值
CN计数器当前值(C0–C199 为 16 位,C200–C255 为 32 位,占 2 个字)

说明

  • 软元件名是 2 字符 MC 编码(如 X、Y、M、D、TN、CN),触摸屏组态里按三菱 FX 地址直接填写即可。
  • CN 的 C200–C255 是 32 位计数器,一个点占 2 个字,读写时长度要算对。

常见用法 ​

给触摸屏开一个 MC 口

lua
server = mc_server.start(5000)

触摸屏(GT Designer 等)侧配置:

  • 通信协议:三菱 FX 系列 MC(FX3U-ENET-ADP,1E 帧)
  • IP:本机 IP,端口:5000
  • 直接用 D100、M10、Y0 等地址读写

换非标端口

lua
server = mc_server.start(6000, 4)

注意事项 ​

  • 必须用全局变量持有返回值,local 出作用域后服务会停。
  • 无认证、无加密,只在可信网络里开放。
  • PC 站号必须是 0xFF,触摸屏侧按 FX3U-ENET-ADP 默认配置即可。
  • 想同时以主站身份采集三菱 PLC,用 pipe.setup("mc", ...)(仅上位机 / Linux 版本),两者不冲突。

例程 ​

本模块从注册到运行只有 start 一个入口,没有回调、没有 set/creat/get_* 等方法。脚本只要 start 并全局持有返回对象即可。统一模板「场景 / 完整代码 / 要点 / 验证方法 / 注意事项」。

例程 1:给触摸屏开一个 MC 口 ​

适用:LP3201 / LP3202 / LP3203 / LP3222 / LP3232 / LP3288 / 软PLC模拟器 / 上位机 | 依赖模块:mc_server | 难度:★☆☆

场景:现场一台三菱系触摸屏(GT Designer),希望直接读写本机 PLC 的 D/M/Y,无需任何 Lua 逻辑。

完整代码(可直接下载运行):

lua
server = mc_server.start(5000)   -- 默认端口 5000,必须用全局变量持有

要点:

  • 只有 start 一个入口,无需注册回调;协议解析和软元件映射固件已完成。
  • 返回对象必须用全局变量接住,被 GC 回收后服务立即停止。

验证方法:

  1. 触摸屏侧配:三菱 FX 系列 MC(FX3U-ENET-ADP,1E 帧),IP 填本机、端口 5000。
  2. 直接用 D100、M10、Y0 等地址读写,应实时生效。

注意事项:

  • 无任何身份认证,谁连上就能读写本机 PLC——只放内网,公网务必用防火墙限制。
  • 触摸屏侧 PC 站号必须填 0xFF(FX3U-ENET-ADP 默认),填别的会被拒。
  • local server = ... 在脚本主体里出作用域后服务会停,用全局变量。

例程 2:换非标端口 / 允许多个客户端 ​

适用:同上 | 依赖模块:mc_server | 难度:★☆☆

场景:502/5000 被占用,或要同时接多台上位机。

完整代码(可直接下载运行):

lua
server = mc_server.start(6000, 4)   -- 端口 6000,最多 4 个客户端同时连

要点:

  • 第 2 参 max_sockets 默认 1;第 3 参 buffer_size 默认 1024。
  • 同时支持 BIN 和 ASCII 两种帧格式,服务端按首字节自动识别。

验证方法:多台触摸屏/组态连 6000 端口均可用。

注意事项:默认 max_sockets=1,第二台连不上要显式调大;返回对象仍须全局持有。


例程 3:注意事项——误以为 mc_server 有 creat/set 等方法 ​

适用:同上 | 依赖模块:mc_server data | 难度:★☆☆

场景:某些自动生成的 API 清单会把 creat/set/get_num/get_bool/get_string 挂在 mc_server 名下——那是错的。这五个名字实际属于 data 模块。

完整代码(可直接下载运行):

lua
-- ❌ 错误:mc_server 对象上调这些方法会直接报错
server = mc_server.start(5000)
server:set(...)              --> attempt to call method 'set' (a nil value)

-- ✅ 正确:这些函数在 data 模块里
value = data.creat(0)
value:set(1)
print(value:get_num(), value:get_bool())      -- 1    true

要点:

  • mc_server 从注册到运行只有 start;对象上也只有回收用的 __gc,没有别的实例方法。
  • creat / set / get_num / get_bool / get_string 都是 data 模块的库函数/对象方法,与 mc_server 无关。

验证方法:正确写法不报错并打印 1 true;错误写法直接抛 nil method 异常。

注意事项:想临时存个值、改 mc_server 对象——做不到,用 data.creat 建独立共享对象。

LPPLC 工业物联网云平台 · 软硬件与云平台全栈自研