前段时间在做实验的时候,需要在Simulink中读取M文件中的数据。一般来说Simulink中的数据,只有在程序运行完之后,才会把数据存入工作区间,这个时候,如果我们需要在程序运行的过程中和Simulink交换数据,就需要采取一些其他的方法了。
这个在normal模式下还是比较容易实现的, 利用下面这个语句还是很容易实现的,具体的可以参考问之前的文章,在MATLAB中采用M文件实现对Simulink中的S函数程序实现自动调参数
simOut = sim('model_name','StopTime', 'number', ... ');
variable= simOut.get('variable_name');
set_param('model_name', 'SimulationCommand', 'stop');
下面介绍一种在 External 模式下的Simulink和M文件进行数据交换的方法,因为我们利用第三方的设备,所以产商提供了相应 的通讯模块,就没有使用Simulink中的自带的TCP/IP Receive 和 TCP/IP Send, 但是两者应该是一样的。
1、两个M 文件进行交换数据
单次传输数据
server 端
clear;clc;close all;
% 构造服务器端tcpip对象
tcpipServer = tcpip('0.0.0.0',5001,'NetWorkRole','Server');
set(tcpipServer,'Timeout',10); %设置连接时间为1分钟
N = 1024;
t = [1:N]/N*4*pi;
signal = sin(t) ;
set(tcpipServer,'InputBufferSize',N*8);
set(tcpipServer,'OutputBufferSize',N);
%设置读写
%set(tcpipServer,'ByteOrder','littleEndian') %默认情况下应该采用的是大端模式
%告诉对方发送格式
% fprintf(t,'%s',['MMEMORY:DATA "sin.wfm",#42544MAGIC 1000' 13 10])
% fprintf(t,'%s','#42500')
%设置频率
% 打开连接对象
fopen(tcpipServer);
fprintf(tcpipServer,'%s',['CLOCK 5.0000000000e+002' 13 10 10]);
i=1;
recvR=zeros(300000,N);
nBytes_1=zeros(1,N);
sum=0;
%等待接收数据,用以判断是否有数据发送过来
while(1)
% 发送指令
fwrite(tcpipServer,i,'double');
while(1)
nBytes = get(tcpipServer,'BytesAvailable'); %这里得到的数据是接收到的所有缓存个数,比如说有N 个doubel 的数据,那么这个大小就是 8*N
if nBytes > 0
break;
end
end
%
nBytes_1(i)=nBytes;
% 接收数据
recvRaw= fread(tcpipServer,nBytes/8,'double');
n=size(recvRaw);
for j=1:1:n
recvR(sum+j,1)=recvRaw(j);
end
i=i+1;
sum=sum+n;
end
% 关闭和删除连接对象
fclose(tcpipServer);
delete(tcpipServer);
客户端
% 构造反馈数据
N = 1024;
t = [1:10*N]/N*4*pi;
signal = sin(t) ;
figure;
plot(t,signal);
grid on;
title('signal on the end of B.')
% 构造客户端tcpip对象
tcpipClient = tcpip('localhost',5001,...
'NetworkRole','Client');%设置对象属性,
set(tcpipClient,'OutputBufferSize',90*N); %设置缓存长度 经过验证一个double类型的数据数据栈据 8 个缓存位,这个是设置发送的数据缓存
%并且这个设置的长度必须大于你要发送的数据的长度
set(tcpipClient,'InputBufferSize',1024); %设置缓存长度 这个是设置接收的数据缓存
set(tcpipClient,'Timeout',60); %设置连接时间为1分钟
%打开连接对象
fopen(tcpipClient);
% 等待接收命令
while(1)
nBytes = get(tcpipClient,'BytesAvailable');
if nBytes>0
break;
end
end
% 接收命令
receivedInstruction = fread(tcpipClient,nBytes,'int8');
disp(strcat('received instruction is: ',char(receivedInstruction')));
% 反馈数据
fwrite(tcpipClient,signal,'double');
numSent = get(tcpipClient,'valuesSent');
disp(strcat('Bytes of instruction is :',num2str(numSent)));
% 关闭和删除连接对象
fclose(tcpipClient);
delete(tcpipClient);
循环传输数据
% 构造服务器端tcpip对象
tcpipServer = tcpip('0.0.0.0',5001,'NetWorkRole','Server');
set(tcpipServer,'Timeout',10); %设置连接时间为1分钟
N = 1024;
set(tcpipServer,'InputBufferSize',90*N);
set(tcpipServer,'OutputBufferSize',1024);
% 打开连接对象
fopen(tcpipServer);
i=1;
recvR=zeros(N,N);
nBytes_1=zeros(1,N);
%等待接收数据,用以判断是否有数据发送过来
while(1)
% 发送指令
instruction = 'Please send back a signal.';
fwrite(tcpipServer,instruction,'int8');
disp('Instruction sending succeeds.');
numSent = get(tcpipServer,'valuesSent');
disp(strcat('Bytes of instruction is :',num2str(numSent)));
while(1)
nBytes = get(tcpipServer,'BytesAvailable'); %这里得到的数据是接收到的所有缓存个数,比如说有N 个doubel 的数据,那么这个大小就是 8*N
if nBytes > 0
break;
end
end
nBytes_1(i)=nBytes;
% 接收数据
recvRaw= fread(tcpipServer,nBytes/8,'double');
n=size(recvRaw);
for j=1:1:n
recvR(i,j)=recvRaw(j);
end
i=i+1;
end
% 绘制接收数据图像
figure;
plot(recvR);grid on;
title('received signal from B');
% 关闭和删除连接对象
fclose(tcpipServer);
delete(tcpipServer);
客户端
% 构造反馈数据
N = 1024;
t = [1:6*N]/N*4*pi;
signal = sin(t) ;
figure;
plot(t,signal);
grid on;
title('signal on the end of B.')
% 构造客户端tcpip对象
tcpipClient = tcpip('localhost',5001,...
'NetworkRole','Client');%设置对象属性,A端的IP为192.168.123.30
set(tcpipClient,'OutputBufferSize',8*N); %设置缓存长度 经过验证一个double类型的数据数据栈据 8 个缓存位,这个是设置发送的数据缓存
%并且这个设置的长度必须大于你要发送的数据的长度
set(tcpipClient,'InputBufferSize',1024); %设置缓存长度 这个是设置接收的数据缓存
set(tcpipClient,'Timeout',10); %设置连接时间为1分钟
%打开连接对象
fopen(tcpipClient);
i=1;
% 等待接收命令,用以判断是否有数据发送过来
recvR=zeros(N,N);
nBytes_1=zeros(N);
while(1)
while(1)
nBytes = get(tcpipClient,'BytesAvailable'); %这里得到的数据是接收到的所有缓存个数,比如说有N 个字符 的数据,那么这个大小就是 N
if nBytes > 0
break;
end
end
nBytes_1(i)=nBytes;
disp(i)
% 接收命令
receivedInstruction = fread(tcpipClient,nBytes,'int8');
disp(strcat('received instruction is: ',char(receivedInstruction')));
% 反馈数据
fwrite(tcpipClient,signal(i),'double');
numSent = get(tcpipClient,'valuesSent');
disp(strcat('Bytes of instruction is :',num2str(numSent)));
i=i+1;
end
% 关闭和删除连接对象
fclose(tcpipClient);
delete(tcpipClient);