MATLAB APP 设计实践(一)UART通信(下篇)

该文详细介绍了如何使用MATLABAppDesigner开发一个基于UART通信的应用,该应用能发送图片的RGB像素数据。内容包括设计思路、界面布局、功能需求、组件选择、内部数据处理及发送过程,并提供了源代码和演示视频。
摘要由CSDN通过智能技术生成

引言

上篇介绍了 MATLAB App 的基本内容,本篇就结合UART发送数据的具体案例介绍开发过程。文末给出设计源文件、设计的可执行文件的下载链接,以及App的实际使用视频(与FPGA开发板进行调试验证)。

前文链接:

MATLAB APP 设计实践(一)UART通信(上篇)

在看本篇文章之前,最好看一下上篇文章,做好前期准备工作。

MATLAB 版本:R2022a


最终界面展示

在开始讲解之前,先展示一下,最终的应用界面:

设计APP之前要想清楚的几个问题

APP页面总体布局

在设计之前要考虑清楚,设计的App要用到哪些组件,这些组件如何放置,如何布局,尽可能做到简洁美观。

App覆盖什么功能

要考虑清楚App的功能需求以及用什么方法来满足这种需求。

App有哪些内部共享数据

这个问题是更深层次的考虑,根据功能需求分析该App内需要有哪些共享数据在不同的函数之间传递。

App需要哪些回调

这个回调函数可以近似理解为中断处理程序,每当相应的事件发生,就会调用该函数一次。如按键每按下一次就产生一次亮灯;每选择一次下拉菜单就更新某个数据等。

App需要哪些内部处理函数

如做一个信号处理或者数字图像处理的App,就需要考虑设计一个函数来实现信号处理或者图像处理算法。

UART通信App设计

功能需求(发送图片像素RGB数据)

界面需求:
1、可以选择要发送的图片并显示图片内容;
2、可以设置UART发送的波特率:9600bps、57600bps、115200bps;
3、可以选择COM口;
4、可以设置数据发送间隔(单位:秒);
5、具有发送开关;
6、实时显示当前发送的数据所在的行列索引号;
7、图片导入时显示显示图片规格,格式为 :长度 X 高度;
8、图片发送时首先发送16位帧头:0x5A4B;
9、可以读取设备写回的帧头并显示在界面;
10、数据发送时按像素数据的R、G、B分量依次发送;
11、界面显示一个指示灯,指示发送状态:
灰色:待机/停止发送
绿色:正在发送
蓝色:发送完成
12、只发送真彩图,如果发现图片是灰度图,则需要弹出错误警示。

设计思路

界面规划

由于此App的功能需求不是很复杂,所以整体的规划是用一栏的界面完成。

组件需求

  1. 开关组件,实现发送/暂停的控制;

  1. 指示灯组件,显示发送状态;

  1. 按键组件,点击时选择将要发送的图片;

  1. 文本/数值显示组件,显示帧头信息、图片规格信息、像素数据索引号信息以及接收发送间隔等;

  1. 图片组件,显示博客昵称;

  1. 超链接组件,点击后跳转至本人博客主页;

  1. 下拉栏组件,供选择波特率以及COM口;

App内部共享数据

通过下面的方式添加App的属性,以在App内共享数据:

我所添加的属性:

    properties (Access = private)
        IMAGE_DATA   % 图像数据
        IMAGE_DATA_R % 图形数据行数
        IMAGE_DATA_C % 图像数据列数
        COM_NAME     % 串口号名称
        BAUD_RATE    % 通信波特率 bps
    end

App启动设置

此App在启动时,我想让其自动加载一些默认配置,比如波特率,指示灯颜色,端口号等。

创建startupFcn回调的方法:

在此回调内,配置加载默认信息:

我的回调:

% Code that executes after component creation
        function startupFcn(app)
            % Configure image axes
            app.ImageAxes.Visible = 'off';
%             app.ImageAxes.Colormap = gray(256);
            axis(app.ImageAxes, 'image');

            app.Lamp.Color = [0.65 0.65 0.65];

            app.EditField.Value = 0;
            app.EditField_2.Value = 0;
            app.EditField_3.Value = '';
            app.EditField_4.Value = 0;
            app.XEditField.Value = 0;
            app.bpsDropDown.Value = '115200';
            app.COMDropDown.Value = 'COM5';
            app.bpsDropDownValueChanged;
            app.COMDropDownValueChanged;
        end

设计过程

图片选择

此功能的实现过程如下:

1、用户点击按钮后;
2、APP 弹出文件管理器;
3、用户选择将要发送的图片;
4、APP 获取图片的路径字符串;
5、APP 使用 imread 函数读取图片数据,获取其图片尺寸规格,并在图片显示区域显示图片内容;
6、APP 判别图片是否为真彩图,即是否同时具有 R G B 3种分量;
7、如果是真彩图,则准备发送,否则弹窗报错;

此处的图片选择借鉴官方例程:

创建使用多个坐标区来显示图像分析结果的 App

可以在MATLAB命令行输入如下命令打开例程:

openExample('matlab/AppdImageHistogramsExample')

此处需要添加一个按钮的回调,当用户按下此按钮时,需要将文件管理器弹开,让用户选择将要发送的图片。

点击按钮,右键,添加回调。

另外,案件的其他设置可以在右侧的侧边栏完成设置:

我的回调函数:

        % Button pushed function: Button
        function ButtonPushed(app, event)
            % Display uigetfile dialog
            filterspec = {'*.jpg;*.png;*.gif','All Image Files'};
            [f, p] = uigetfile(filterspec);
            
            % Make sure user didn't cancel uigetfile dialog
            if (ischar(p))
               fname = [p f];
               app.Lamp.Color = [0.65 0.65 0.65];
               app.EditField.Value = 0;
               app.EditField_2.Value = 0;
               app.EditField_3.Value = '';
               DATA = imread(fname);
               app.EditField_4.Value = (size(DATA,2));
               app.XEditField.Value = (size(DATA,1));
               FUNC_DISP_IMAGE(app,fname);
            end
        end

图片显示

此功能通过函数实现,添加App内部私有函数:

函数内容:

  % 图片显示函数
        function FUNC_DISP_IMAGE(app,IMAGE_NAME)
            try
                app.IMAGE_DATA = imread(IMAGE_NAME);
                app.IMAGE_DATA_R = size(app.IMAGE_DATA,1);
                app.IMAGE_DATA_C = size(app.IMAGE_DATA,2);
            catch ME
                % If problem reading image, display error message
                uialert(app.UIFigure, ME.message, '图片读取失败!');
                return;
            end
            if(size(app.IMAGE_DATA,3)==3)
                imagesc(app.ImageAxes,app.IMAGE_DATA);
            else
                msgbox('输入图像不是真彩图,请重新选择图片!','运行错误提示','error');
                return;
            end
        end

UART发送像素数据

同样的方式,添加私有函数,通过函数发送:

        % UART 发送像素数据
        function FUNC_UART_SEND_RGB_DATA(app)
            
            if(strcmp(app.Switch.Value,'On'))
                % 创建串口连接
                SERIAL_OBJ = serialport(app.COM_NAME,app.BAUD_RATE);
                SERIAL_OBJ.Parity = "none";
                SERIAL_OBJ.DataBits = 8;
                SERIAL_OBJ.StopBits = 1;
                SERIAL_OBJ.ByteOrder = "little-endian";
                SERIAL_OBJ.Timeout = 30;
                % 清除缓存
                flush(SERIAL_OBJ);
                % 指示灯变绿
                app.Lamp.Color = [0 1 0];
                % 发送帧头
                write(SERIAL_OBJ,hex2dec('5A'),'uint8');
                write(SERIAL_OBJ,hex2dec('4B'),'uint8');
                READ_DATA = read(SERIAL_OBJ,2,'uint8');
                app.EditField_3.Value = reshape(dec2hex(READ_DATA).',1,[]);
                pause(2);
                % 数据发送
                for i = 1:app.IMAGE_DATA_R
                    app.EditField.Value = i;
                    app.EditField_2.Value = 0;
                    for j = 1:app.IMAGE_DATA_C
                        if(strcmp(app.Switch.Value,'On'))
                            app.EditField_2.Value = j;
                            write(SERIAL_OBJ,app.IMAGE_DATA(i,j,1),'uint8');
                            write(SERIAL_OBJ,app.IMAGE_DATA(i,j,2),'uint8');
                            write(SERIAL_OBJ,app.IMAGE_DATA(i,j,3),'uint8');
                            pause(app.sEditField.Value)
                        else
                            app.Lamp.Color = [0.65 0.65 0.65];
                            flush(SERIAL_OBJ);
                            delete(SERIAL_OBJ);
                            return;
                        end
                    end
                end
                % 清除缓存
                flush(SERIAL_OBJ);
                % 关闭串口
                delete(SERIAL_OBJ);
                % 指示灯变蓝
                app.Lamp.Color = [0 0 1];
                app.Switch.Value = 'Off';
            else
                app.Lamp.Color = [0.65 0.65 0.65];
                return;
            end
        end

编程说明

App Designer 类似于C++ 的面向对象编程,数据的索引需要用 app.对象名 的形式;例如访问/取用APP内的私有数据需要用app.变量名 的形式。知道了这一点 App的开发就很简单了。

App设计源码分享

此App的设计源文件(.mlapp)以及可执行文件(.exe)放在这里,如果需要可以下载:

提取码:XYB1

App演示视频

UART发送像素数据——MATLAB APP设计 演示视频


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在路上-正出发

哈哈,多少是个心意

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值