7

我目前正在尝试在 Matlab 应用程序设计器应用程序中显示通过串行端口接收的数据。我正在遭受线性仪表(~1 Hz)的糟糕刷新率。

仪表的值由设置为 30Hz 的固定速率计时器更新。计时器回调中的时间戳打印显示它以正确的频率调用。我的电脑很强大,任务管理器没有显示任何高负载的迹象——事实上,MATLAB 应用程序几乎不消耗 CPU 时间。它实际上不仅仅是仪表,而是所有的 UI 元素。

所以我的猜测——或者更好:我的希望——是刷新率必须有一些硬性上限。不过,官方文档没有给出任何关于如何改变这一点的提示。

我的 MATLAB 版本是 R2016b。

所以我的问题:

  • R2017a 解决了这个问题吗?

  • 如果没有:我可以做点什么,即摆弄 MATLAB 内置文件吗?

这是一个演示该问题的 MCV 示例:

classdef testapp < matlab.apps.AppBase

% Properties that correspond to app components
properties (Access = public)
    UIFigure                  matlab.ui.Figure
    andwatchhowthisstartstospinsmoothlyGaugeLabel  matlab.ui.control.Label
    andwatchhowthisstartstospinsmoothlyGauge  matlab.ui.control.SemicircularGauge
    KeepturninghereKnobLabel  matlab.ui.control.Label
    KeepturninghereKnob       matlab.ui.control.Knob
end


properties (Access = private)
    tim_the_timer
    i = 0;
end

methods (Access = private)
    function app = refreshMeter(app, ~,~)
        % display timestamp
        datestr(now,'HH:MM:SS.FFF')

        % update the gauge
        app.andwatchhowthisstartstospinsmoothlyGauge.Value = app.i;
        app.i = app.i + 1;
        if app.i > 100
           app.i = 0;
        end
    end
end


methods (Access = private)

    % Code that executes after component creation
    function startupFcn(app)
       t = timer;
       t.TimerFcn = @app.refreshMeter;
       t.Period = 0.02;
       t.BusyMode = 'drop';
       t.ExecutionMode = 'fixedRate';
       start(t);
       app.tim_the_timer = t;
    end

    % Close request function: UIFigure
    function UIFigureCloseRequest(app, event)
        stop(app.tim_the_timer);
        delete(app.tim_the_timer);
        delete(app);
    end
end

% App initialization and construction
methods (Access = private)

    % Create UIFigure and components
    function createComponents(app)

        % Create UIFigure
        app.UIFigure = uifigure;
        app.UIFigure.Position = [100 100 640 480];
        app.UIFigure.Name = 'UI Figure';
        app.UIFigure.CloseRequestFcn = createCallbackFcn(app, @UIFigureCloseRequest, true);
        setAutoResize(app, app.UIFigure, true)

        % Create andwatchhowthisstartstospinsmoothlyGaugeLabel
        app.andwatchhowthisstartstospinsmoothlyGaugeLabel = uilabel(app.UIFigure);
        app.andwatchhowthisstartstospinsmoothlyGaugeLabel.HorizontalAlignment = 'center';
        app.andwatchhowthisstartstospinsmoothlyGaugeLabel.Position = [275 138 246 15];
        app.andwatchhowthisstartstospinsmoothlyGaugeLabel.Text = '... and watch how this starts to spin smoothly';

        % Create andwatchhowthisstartstospinsmoothlyGauge
        app.andwatchhowthisstartstospinsmoothlyGauge = uigauge(app.UIFigure, 'semicircular');
        app.andwatchhowthisstartstospinsmoothlyGauge.Position = [338 168 120 65];

        % Create KeepturninghereKnobLabel
        app.KeepturninghereKnobLabel = uilabel(app.UIFigure);
        app.KeepturninghereKnobLabel.HorizontalAlignment = 'center';
        app.KeepturninghereKnobLabel.Position = [119 265 112 15];
        app.KeepturninghereKnobLabel.Text = 'Keep turning here...';

        % Create KeepturninghereKnob
        app.KeepturninghereKnob = uiknob(app.UIFigure, 'continuous');
        app.KeepturninghereKnob.Position = [145 314 60 60];
    end
end

methods (Access = public)

    % Construct app
    function app = testapp()

        % Create and configure components
        createComponents(app)

        % Register the app with App Designer
        registerApp(app, app.UIFigure)

        % Execute the startup function
        runStartupFcn(app, @startupFcn)

        if nargout == 0
            clear app
        end
    end

    % Code that executes before app deletion
    function delete(app)

        % Delete UIFigure when app is deleted
        delete(app.UIFigure)
    end
end
end

编辑:我注意到,当我转动旋钮、滑块等时,仪表会立即更新。因此,以某种方式肯定存在更高刷新率的能力......但是如何在无需触摸控件的情况下启用它?相应地更新了 MCV。

4

4 回答 4

2

我会建议以下事项来帮助您解决问题:

  1. 按照这个非常有用的链接,它为低级图形问题提供数学解决方案。这可能与您的显卡有关。

  2. 遵循@MrAzzamans 的建议,drawowrefreshdata可以帮助解决您的问题(请记住,它们有不同的召唤选项)。

  3. 如果您使用的是 GUIDE,请尝试更改为 App Designer 并查看它是否可以解决您的问题。

我在 GUIDE 中构建“视频播放器”时遇到了类似的问题,第一个建议为我修复了它。

于 2017-07-12T14:36:15.853 回答
2

您应该能够通过在回调中调用该drawnow函数来强制刷新。refreshMeter

于 2017-07-10T05:30:21.660 回答
0

我找到了一种方法来强制触发小部件更新的事件,对于该小部件,drawow 无法操作:尝试带有回车的 sendkeys:

h = actxserver('WScript.shell'); h.SendKeys(换行);

于 2018-12-04T00:14:15.550 回答
0

所以我就这个问题联系了 MathWorks 支持。不幸的是,这似乎是 R2016b 和 2017a 中普遍存在的已知问题,可能会在未来的版本中修复。支持也无法为我提供解决方法,所以暂时我只是将测量数据打印到 matlab 命令行。

于 2017-07-16T08:23:44.270 回答