matlab与simulink实时交互可通过五种方法实现:一、全局变量+sim()传参;二、from/to workspace动态读写;三、runtimeobject事件监听实时绘图;四、set_param/get_param在线调参;五、app designer事件驱动架构协同。

如果您在MATLAB GUI或App Designer中启动Simulink模型,但无法实现实时数据更新与响应,则可能是由于回调函数未正确配置或数据访问路径不一致。以下是实现MATLAB与Simulink通过回调函数实时交互数据的具体方法:
一、利用全局变量与sim()命令触发仿真并传参
该方法适用于GUI中按钮点击后启动一次完整仿真,并将用户输入参数传递至Simulink模型。全局变量确保回调函数间共享模型名与参数值,sim()命令以指定时间与选项运行模型。
1、在GUI主界面的OpeningFcn或startupFcn中初始化全局变量:
global ModelName Kp Ki Kd
2、在按钮回调函数中获取用户输入并赋值:
Kp = str2num(get(handles.edit_Kp,'String'));
Ki = str2num(get(handles.edit_Ki,'String'));
Kd = str2num(get(handles.edit_Kd,'String'));
ModelName = 'my_controller';
3、调用sim命令执行仿真:
options = simset('SrcWorkspace','current');
sim(ModelName, [], options);
4、在Simulink模型中,PID控制器参数直接填写变量名Kp、Ki、Kd,而非数值。
二、使用From/To Workspace模块配合回调函数动态读写
该方法支持仿真运行过程中持续交换数据,To Workspace模块将信号实时写入MATLAB工作区,From Workspace模块则从工作区读取随时间变化的控制指令,适合闭环调节类应用。
1、在Simulink模型中添加To Workspace模块,连接待监测信号(如输出y):
设置Variable name为simout_y,Save format为Timeseries,Limit data points取消勾选。
2、添加From Workspace模块,用于接收GUI更新的参考信号r_ref:
Variable name设为r_ref,Data设为timeseries格式(需在GUI中预构造)。
3、在GUI按钮回调中构造参考信号timeseries:
t = (0:0.01:10)';
r = sin(t);
r_ref = timeseries(r, t);
4、启动仿真前刷新工作区:
assignin('base', 'r_ref', r_ref);
sim('my_controller');
5、仿真结束后读取结果:
y_data = simout_y.Time;
plot(y_data, simout_y.Data);
三、基于RuntimeObject与事件监听实现实时波形绘制
该方法绕过To Workspace模块的采样延迟,直接通过Simulink运行时对象(RuntimeObject)在每个仿真步长中提取端口数据,配合eventlistener实现毫秒级响应,适用于GUI中实时绘图场景。
1、在Simulink模型中,右键空白处→模型属性→Callbacks→StartFcn,填入:
add_exec_event_listener('my_model/Out1','PostOutputs',@PlotOnApp);
2、在MATLAB路径下新建PlotOnApp.m函数:
function PlotOnApp(block, ~)
rto = get_param([gcs '/Out1'],'RuntimeObject');
y = rto.InputPort(1).Data;
t = get_param(gcs,'SimulationTime');
app = guidata(0);
plot(app.UIAxes, t, y, '.','Color','b');
drawnow limitrate;
3、在GUI startupFcn中设置控件Tag:
app.Out1.Tag = 'Out1';
app.UIAxes.Tag = 'UIAxes';
4、确保GUI中坐标区UIAxes已存在且可见,且模型中Out1模块输出端口连接目标信号。
5、启动仿真后,PlotOnApp函数将在每个输出步长自动触发,无需手动轮询或定时器。
四、通过set_param/get_param动态修改运行中模型参数
该方法允许在仿真进行中修改模块参数(如Gain值、PID限幅),无需停止仿真,适用于参数在线整定或自适应控制验证。
1、在GUI中添加滑块或编辑框控件,绑定回调函数update_gain_callback。
2、在回调函数中获取当前值并写入模型:
gain_val = str2double(get(handles.gain_slider,'Value'));
set_param('my_model/Gain','Gain','num2str(gain_val)');
3、强制刷新模型结构以使参数生效:
refreshdata('my_model');
4、验证参数是否已更新:
current_gain = get_param('my_model/Gain','Gain');
disp(['Current Gain = ', current_gain]);
5、关键提示:必须确保模型处于仿真暂停或运行状态,且Gain模块名称与路径完全匹配。
五、采用App Designer与Simulink事件驱动架构协同
该方法依托App Designer的面向对象特性与Simulink事件机制,避免全局变量污染,提升代码可维护性,适用于中大型交互式应用开发。
1、在App Designer的Properties段定义私有属性:
properties (Access = private)
SimModelName = 'quadcopter';
SimRunning = false;
end
2、在RunButton回调中启动仿真:
if ~app.SimRunning
set_param(app.SimModelName, 'SimulationCommand', 'start');
app.SimRunning = true;
end
3、在StopButton回调中停止仿真:
if app.SimRunning
set_param(app.SimModelName, 'SimulationCommand', 'stop');
app.SimRunning = false;
end
4、在模型StartFcn中注册事件监听器:
add_exec_event_listener('quadcopter/ScopeData','PostOutputs',@(~,~)app.updatePlot());
5、在App Designer中定义updatePlot函数:
function updatePlot(app)
rto = get_param('quadcopter/ScopeData','RuntimeObject');
y = rto.InputPort(1).Data;
t = get_param('quadcopter','SimulationTime');
plot(app.UIAxes, t, y);
drawnow limitrate;
end











