基于Matlab的UDP通信(浪高仪)实录

由于最近需要使用一个利用UDP网口进行传输数据的浪高仪,且它需要基于Matlab平台与程序进行数据融合,这里同时接触到一些新的数据编译工作。在这里简单记录一下开发该程序的全过程。


目录

一、UDP协议介绍

二、通讯代码

三、数据编译代码

四、采用网络调试助手辅助验证算法

五、源代码


一、UDP协议介绍

UDP类似于我上文提到的串口RS485的Modbus协议,不像TCP是两者固定的连接,而是使用广播的方式进行通信。

二、通讯代码

fclose(instrfindall);   %先关闭之前可能存在的UDP
ipA = '192.168.0.2';    %这个根据说明书所设定的本地IP地址
portA = 10000;          %这个是所设定的本地主机端口
ipB = '192.168.0.21';   %这个是仪器的远程ip地址(前面三段数字相同,网络即处于同一网段)
portB = 10000;          %这个是所设定的远程主机端口
handles.udpA = udp(ipB,'RemotePort',portB,'LocalPort',portA); %新建一个udp对象
udpA.OutputBufferSize=8192;   %根据传输的数据长度来定
udpA.TimeOut=10;    %超时时间为10ms
udpA.BytesAvailableFcnCount  = 'byte';
udpA.BytesAvailableFcnCount  = 1024;  %触发中断的数据数量
fopen(udpA);   %设备之间网络连接


for i=1:1:10
    fwrite(udpA,(hex2dec(['DA'; '05'; '01'; '02'; '00'; 'E2'])));  %发送指令
    pause(1); %一定的延时(需要把控精确的计算时间的可以采用下面注释的代码)
    if(c.BytesAvailable)    %若满足传输的字节为9个字节
       data1= fread(udpA,9);  %读取9个字节
    end   
end
fclose(udpA);
delete(udpA);

注意:

1.电脑主机IP的更改在网络设置里面更改Internet协议版本4(TCP/IPv4) 属性。

2.这里端口需要统一, 才可以连接

3.写数据和读取数据的方式跟串口通讯是一模一样的。

三、数据编译代码

根据说明书中的指令,经过NetAssist V5.0.3的试验,其发送指令和相应的响应指令如下:

T:DA 05 01 02 00 E2

R:DC 00 FF 00 81 17 BA 8C 43

由于浪高仪发送回来的是浮点数,且遵循低位在前,高位在后的原则,这里需要这样进行编译。

4个字节的16进制字符可以转换为32bit浮点数。

b = 'BA8C8117';
c = typecast(uint32(hex2dec(b)),'single');

 运行程序可以看到,c=-0.0011

四、采用网络调试助手辅助验证算法

提前先采用网络调试助手来与matlab进行连接,是因为这样可以看到发送和接受的信息,若直接和设备相连无法看到发送过去的是什么内容。同样的,这里由于测试是在一个机器上进行通讯,因此改为只有一个本地的ip地址(即127.0.0.1)。另外这里通讯的时候,两个端口是相反的(且由于在同一个地址内,端口不能相同),这个应该好理解。代码如下:

clc
clear
delete(instrfindall);  %先关闭之前可能存在的UDP
udpA = udp('127.0.0.1','RemotePort',8080,'LocalPort',8086); %这里'127.0.0.1'指的是本地
udpA.OutputBufferSize=8192;   %根据传输的数据长度来定
udpA.TimeOut=10;    %超时时间为10ms
udpA.BytesAvailableFcnMode =  'byte';
udpA.BytesAvailableFcnCount  = 9;  %触发中断的数据数量
fopen(udpA);   %设备之间网络连接


for i=1:1:10
    fwrite(udpA,(hex2dec(['DA'; '05'; '01'; '02'; '00'; 'E2'])));  %发送指令
    pause(1); %一定的延时(需要把控精确的计算时间的可以采用下面注释的代码)
%%              tic  
%%                 for t = 0.001:0.001:0.2  
%%                    while toc < t
%%                     end
%%                 end

    if(udpA.BytesAvailable)    %若满足传输的字节为9个字节
       data1= fread(udpA,9);  %读取9个字节
    end   
end
fclose(udpA);
delete(udpA);

这代表在正式的仪器连接中,仪器是能够接受到正确的指令。(如果这里只发送前面指令,而不发送附加位,这里可以勾选checksum8)


可以看到,matlab也成功接受了由网络调试助手发送的DC 00 FF 00 81 17 BA 8C 43指令,并将其解析为实际的数据。即由于matlab中是不显示16进制的,只会以10进制显示所收到的数据。因此这里需要将返回来的数据先变为第三节代码所需要的数据形式,即一个一维的字符串。方法有点笨拙,有改进的请在评论区发给我吧。

H=dec2hex(data1(5:8));    %将十进制的double型数据变为十六进制的二维字符串
H1=H(1,:);
H2=H(2,:);
H3=H(3,:);
H4=H(4,:);
data2=[H3,H4,H1,H2];      %拼接成一维的字符串,且低位在前,高位在后 

五、源代码

clc
clear
delete(instrfindall);  %先关闭之前可能存在的UDP
udpA = udp('127.0.0.1','RemotePort',8080,'LocalPort',8086); %这里'127.0.0.1'指的是本地
udpA.OutputBufferSize=8192;   %根据传输的数据长度来定
udpA.TimeOut=10;    %超时时间为10ms
udpA.BytesAvailableFcnMode =  'byte';
udpA.BytesAvailableFcnCount  = 9;  %触发中断的数据数量
fopen(udpA);   %设备之间网络连接
pause(5)

for i=1:1:10
    fwrite(udpA,(hex2dec(['DA'; '05'; '01'; '02'; '00'; 'E2'])));  %发送指令
    pause(1); %一定的延时(需要把控精确的计算时间的可以采用下面注释的代码)
    if(udpA.BytesAvailable)    %若满足传输的字节为9个字节
       data1= fread(udpA,9);  %读取9个字节
    end   
    H=dec2hex(data1(5:8));    %将十进制的double型数据变为十六进制的二维字符串
    H1=H(1,:);
    H2=H(2,:);
    H3=H(3,:);
    H4=H(4,:);
    data2=[H3,H4,H1,H2];      %拼接成一维的字符串   
    data3 = typecast(uint32(hex2dec(data2)),'single');
end
fclose(udpA);
delete(udpA);

猜你喜欢

转载自blog.csdn.net/m0_56146217/article/details/127863496