利用TCP/IP 在Simulink和M文件进行实时的数据交换

前段时间在做实验的时候,需要在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);

你可能感兴趣的:(MATLAB)