MATLAB Appdesigner实用技巧(二):MATLAB App建立TCP服务端和下位机通信

1. MATLAB App建立TCP服务端和下位机通信

在数据传输上方式上,笔者选择了使用ESP8266进行通信。ESP8266模块作为AP,TCP客户端模式;电脑作为TCP服务端。在MATLAB中,“tcpserver”函数可以建立一个TCP服务端。查询”tcpserver“函数的基础使用用法为:

ts = tcpserver(address,port);

其中,“address”为TC服务器的地址,“port”为端口号。使用上述基础语法,我们就可以在电脑上创建一个TCP服务器和下位机通信了。接下来,我将详细介绍如何在App中使用TCPserver和下位机进行通信。

1.1 查看电脑端IP地址

1.按照下图所示的点击顺序,点击模块热点的“属性”。

在这里插入图片描述

2.弹出如下窗口:

在这里插入图片描述

找到属性中的“IPv4地址”,这个就是模块分配给电脑的IP地址了。在我的组网中,我的电脑被分配的地址为192.168.4.2。

1.2 在MATLAB中创建TCPserver变量

1.在MATLAB脚本中输入如下代码:

address = '192.168.4.2';
port = 8080;
ts = tcpserver(address,port);

注意,“address”为字符串变量,而“port”为double类型变量。

P.S.关于对应的下位机代码部分,笔者将会在硬件相关的章节(待更新)详细介绍。在这里,我做一个简要的解释:在驱动ESP8266的代码中,我将该模块设置为向远端IP地址为“192.168.4.2”,端口号为“8080”的TCP服务器发起连接。相关代码如下:

uint8_t AT_START[] = "AT+CIPSTART=\"TCP\",\"192.168.4.2\",8080\r\n";//建立TCP连接

#define ATSTART HAL_UART_Transmit(&huart3, (uint8_t *)AT_START, sizeof(AT_START), 0xFFFF) //发送建立TCP连接命令

回到MATLAB脚本中来。运行建立TCP服务端的代码,我们就可以创建一个TCPserver变量。在工作区双击打开“ts”变量:

在这里插入图片描述

可以看到TCPserver变量所具有的属性。当有TCPClient接入时,”Connected“属性会显示为接入的Client的数量,未有Client接入则为零。

2.注意上图中的“NumBytesAvailable”属性,这一属性代表当前通信状态下的数据字节数。在下一小节中,该属性将作为标准判断是否可以读取数据。

1.3 配置数据读取模式并编写回调函数

1.在下位机的代码中,我将数据发送的格式设置为每包数据末尾添加“\r\n”字符。那么在MATLAB上位机端,我们就需要设置TCPserver在遇到这两个字符后开始读取并处理数据。在创建好了TCP服务端后,添加如下代码:

configureTerminator(ts,"CR/LF");

这段代码的作用是将回调函数触发条件设置为“Terminator”,通俗来说就是读到特定字符时触发回调函数。另外还有一种方式,是在串口中数据量到达固定字节后触发串口回调函数。在这里,我们只详细介绍“Terminator”方式。

2.设置好后,我们就需要编写相应的回调函数了。在上面的代码下面添加如下代码:

configureCallback(ts,"terminator",Receive_Callback);

这段代码的作用是,当读到terminator设置的字符后,程序进入回调函数。所以在这时,我们还需要添加相应的回调函数:

function Receive_Callback(ts,~)
    TCPBytesAvailable = get(ts,'NumBytesAvailable');
    if TCPBytesAvailable % 判断是否有数据可读,如果可读则进行下一步读出的操作
        data = read(src,SerialBytesAvailable,"char");
        disp(data); % 将读出的数据在命令行显示出来
    end
end

完整的代码如下:

clc; clear; close all

%% 打开串口
address = '192.168.4.2'; % 这里读者需要改成自己相应的IP地址
port = 8080; % 同样,读者需要改为自己在下位机设置的端口号
ts = tcpserver(address,port);

%% 清空数据并打开回调函数
flush(ts);

configureTerminator(ts,"CR/LF");
configureCallback(ts,"terminator",@Receive_Callback);

% 这里pause的效果是,按下键盘上任意键,代码从这一行继续运行。
% 如果不加这一行,则程序将直接运行到configureCallback(ts,"off");即关闭回调函数
% 回调函数将不会运行
pause;

configureCallback(ts,"off");

function Receive_Callback(ts,~)
    TCPBytesAvailable = get(ts,'NumBytesAvailable');
    if TCPBytesAvailable % 判断是否有数据可读,如果可读则进行下一步读出的操作
        data = read(ts,TCPBytesAvailable,"char"); % 读出的数据类型为char
        disp(data); % 将读出的数据在命令行显示出来
    end
end

运行上述代码,结果如下:

在这里插入图片描述

可以看到,下位机发送上来的数据显示在了命令行窗口中。

1.4 在App中实现上述功能

1.在MATLAB脚本中做好调试后,我们就需要将该功能移植到App当中。我们需要一个“编辑字段(文本)”控件、一个“编辑字段(数值)”控件、两个按钮控件,分别用于IP地址的输入、端口号输入、建立TCP服务端和关闭TCP服务端。我们将控件变量分别命名为:

  • IPEditField
  • PortEditField
  • OpenTCPButton
  • CloseTCPButton

创建好的控件如下图所示:
在这里插入图片描述
2.创建好控件后,我们需要给这些控件添加功能代码。分为如下几个部分:

  • “建立TCP服务端”按钮和“关闭TCP服务端”按钮的回调函数
  • 在公共方法中添加TCPserver的回调函数
  • 在公共属性中添加要创建的TCPserver变量。命名为“ts”;添加TCP读出的数据变量,命名为“TCPData”。

如何添加回调函数和公共属性,请参考MATLAB Appdesigner开发独立桌面App全流程(一):以打开串口功能为例介绍Appdesigner的基本使用第8节。在这里,笔者只给出代码。这三部分的代码如下:

properties (Access = public)
    ser; % Serial
    serialname;
    model; % To store the model data
    modelvisual; % Store the patch handle
    baud = 115200; % baud rate
    datetimer; % To show time
    SerialData;
    %% 以下为本节新添加的变量
    ts;
    TCPData;
end

methods (Access = public)

    function TCPReceive_Callback(app, src,~)
        TCPBytesAvailable = get(src,'NumBytesAvailable');
        if TCPBytesAvailable % 判断是否有数据可读,如果可读则进行下一步读出的操作
            app.TCPData = read(src,TCPBytesAvailable,"char");
            % SerialTextArea是在6.9.2节创建的文本区控件。这里方便起见,就直接调用了该控件来显示数据
            set(app.SerialTextArea,"Value",app.TCPData); 
        end
    end

end

% Button pushed function: OpenTCPButton
function OpenTCPButtonPushed(app, event)
    try
        address = app.IPEditField.Value;
        port = app.PortEditField.Value;
        app.ts = tcpserver(address,port);
        flush(app.ts);
        configureTerminator(app.ts,"CR/LF");
        configureCallback(app.ts,"terminator",@app.TCPReceive_Callback);
    catch ME
        report = getReport(ME);
        uialert(app.UIFigure,report,'Error Message','Interpreter','html');
    end
end

% Button pushed function: CloseTCPButton
function CloseTCPButtonPushed(app, event)
    try
        configureCallback(app.ts,"off");
        delete(app.ts);
    catch ME
        report = getReport(ME);
        uialert(app.UIFigure,report,'Error Message','Interpreter','html');
    end
end

运行App,效果如下:

在这里插入图片描述
可以看到,下位机的数据显示在了文本区域当中。这样,我们就使用TCPserver建立了与下位机的通信。在下次更新中,我将介绍如何利用这些数据在App的坐标区中显示实时波形——也就是示波器的效果。

  • 6
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值