如何通过MATLAB脚本触发PLC上外部模式的Simulink被控对象模型?
事件触发式HiL仿真实现方案(PLC+MATLAB MPC)
一、PLC端Simulink被控对象模型配置
- 切换为单步触发模式:
- 打开模型后按
Ctrl+E进入配置参数,在Solver标签页设置:- Type:
Fixed-step - Solver:
discrete (no continuous states) - 取消固定采样周期的强制绑定(或暂设一个占位值,后续由外部触发覆盖)
- Type:
- 启用外部模式单步执行:在External Mode标签页勾选
Enable single-step execution - 添加通信模块:根据PLC支持的协议(UDP/TCP/IP/OPC UA),插入对应
Send/Receive模块,用于接收PC端的控制输出和触发指令,同时发送被控对象的输出回PC。
- 打开模型后按
二、PC端MATLAB MPC控制器脚本逻辑
核心逻辑为「计算输出→发送→触发仿真→接收反馈→循环」,以下是UDP通信的示例代码(可根据实际协议调整):
% 初始化通信 plcIp = '192.168.1.100'; % 替换为你的PLC IP sendPort = 1234; recvPort = 1235; udpSend = udp(plcIp, sendPort); udpRecv = udp(plcIp, recvPort); set(udpRecv, 'Timeout', 10); % 设置接收超时,避免卡住 fopen(udpSend); fopen(udpRecv); % 初始化MPC控制器 plant = % 你的被控对象模型(需提前定义) mpcObj = mpc(plant); % 无需设置固定采样周期,采用事件触发 % 配置MPC约束、权重等(与原固定周期设置一致) % 初始状态 x0 = [0; 0]; % 被控对象初始状态向量 yPrev = 0; while true % 1. 计算MPC控制输出 u = mpcmove(mpcObj, x0, yPrev); % 2. 发送控制输出到PLC fwrite(udpSend, u, 'double'); % 3. 发送单步触发指令 fwrite(udpSend, 'TRIG_STEP', 'char'); % 4. 接收PLC返回的被控对象输出 yCurrent = fread(udpRecv, 1, 'double'); % 5. 更新状态,用于下一轮计算 x0 = predict(plant, x0, u); % 若PLC返回状态,可直接替换为返回值 yPrev = yCurrent; % 按ESC键退出循环 if ~isempty(get(gcf,'CurrentCharacter')) && get(gcf,'CurrentCharacter') == char(27) break; end end % 清理资源 fclose(udpSend); fclose(udpRecv); delete(udpSend); delete(udpRecv);
三、PLC端模型触发逻辑实现
- 添加触发子系统:
- 拖拽
Triggered Subsystem模块到模型,将被控对象的核心仿真逻辑(状态更新、输出计算)移入子系统 - 触发信号处理:用
Compare To Constant模块判断接收的指令是否为TRIG_STEP,输出布尔信号作为子系统的上升沿触发源 - 子系统执行完成后,立即通过通信模块将输出值发送回PC端
- 拖拽
四、关键注意事项
- 通信协议选型:实时性要求高的场景优先用TCP/IP或OPC UA,UDP适合对丢包不敏感的测试场景
- 数据格式统一:PC与PLC端发送/接收的数据类型(如double、int32)必须完全一致,避免解析错误
- 外部模式调试:保持Simulink与PLC的外部模式连接,可实时监控模型状态,快速排查触发或通信故障
- 异常处理:在MATLAB脚本中添加超时、重发逻辑,避免因PLC异常导致脚本挂起
内容的提问来源于stack exchange,提问作者Kamal
相关产品推荐
相关产品推荐

