8

仮想 COMM ポートを使用してリアルタイムでデータを読み込む Matlab スクリプトを作成しました。mfile でかなりの量の信号処理を行いました。

次に、情報をまとめて表示するコンパクトな GUI の必要性を感じました。

最近、Matlab の組み込み GUI ツールである GUIDE を掘り下げて読み始めました。いくつかのチュートリアルに従って、ボタンを押した後にグラフを GUI に表示することに成功しました。

ただし、GUI をリアルタイムで更新する必要があります。私のデータ ベクトルは常に更新されています (COMM ポートからデータを読み込みます)。更新のためにボタンを押すことに頼るのではなく、GUI が新しいデータでグラフを更新し続けることを望みます。誰かがバックグラウンド更新の正しい方向に私を向けることができますか?

現在 GUI に関連するコードは次のとおりです。

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global data
global time

% Time domain plot
axes(handles.timeDomainPlot);
cla;
plot (time, data);

EDIT 変更されたコード:

% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%Setting it to display something when it ends
% t = timer('TimerFcn', 'timerOn=false; disp(''Updating GUI!'')',... 
t = timer(... 
            'TasksToExecute', 10, ... % Number of times to run the timer object
            'Period', 3, ...                
            'TimerFcn', GUIUpdate()); 

%Starting the timer
start(t)

function GUIUpdate()
global data
global time
%Parameters below axes
    global min
    global max 
      % Time domain plot
    axes(handles.timeDomainPlot);
    cla;
    plot (time, data);
    %Other parameters:
    set(handles.mean, 'String', mean);
    set(handles.max, 'String', max);

私が得るエラーは次のとおりです。

??? Error using ==> GUI_Learning>GUIUpdate
Too many output arguments.

Error in ==>
@(hObject,eventdata)GUI_Learning('pushbutton1_Callback',hObject,eventdata,guidata(hObject))


??? Error while evaluating uicontrol Callback
4

4 に答える 4

10

timerFcn コールバックでタイマーを使用する例を次に示します。1軸1ボタンのシンプルなGUIを作りました。

オープニング関数では、プロットを初期化し、タイマーを作成します。開始ボタンのコールバックで、タイマーを開始し、データの操作を開始します。タイマー関数のコールバックは、ハンドルを介してラインの y データを更新するだけです。以下は、GUI の M ファイルからの関連関数です (init セクションと出力 fcn.

function testTimer_OpeningFcn(hObject, eventdata, handles, varargin)
global y x
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);
handles.plot = plot(handles.axes1,x,y);
handles.timer = timer('ExecutionMode','fixedRate',...
                    'Period', 0.5,...
                    'TimerFcn', {@GUIUpdate,handles});
handles.output = hObject;
guidata(hObject, handles);

% --- Executes on button press in startButton.
function startButton_Callback(hObject, eventdata, handles)
global y x
start(handles.timer)
for i =1:30
   y = sin(x+i/10); 
   pause(1) 
end

function GUIUpdate(obj,event,handles)
global y 
set(handles.plot,'ydata',y);

GUI の構造やデータの更新方法によっては、停止ボタンでタイマーを停止したい場合があります。

編集: Basic は情報を処理します。これのいくつかはかなり基本的なものであり、すでに知っているかもしれません:

オブジェクトへの個々のハンドルには、get() 関数で読み取ったり、set() 関数で設定したりできる一連のプロパティが含まれています。たとえば、GUI で何らかの理由で startButton のテキストを変更したい場合があります。

set(handles.startButton,'String','Something Other Than Start');

コードのどこかにブレークポイントを設定して (ボタンを押したときなど)、handles 構造体をいじりたいだけかもしれません。get()さまざまなオブジェクトに対してコマンドを実行して、それらのプロパティを学習します。

これで、handles 構造には、すべての ... うーん... GUI のオブジェクトへのハンドルと、そこに保存するのに便利なカスタム項目が含まれています。ほとんどの GUI コールバックは自動的に handles 構造体に渡されるため、GUI のすべての部分に簡単にアクセスできます。

元。「startButton」コールバックは自動的に渡されhandlesました。そのため、 を介してタイマー オブジェクトに簡単にアクセスできましたhandles.timer

これにより、カスタムのものを に貼り付けることができhandlesます。handles.timerオープニング関数で、handles 構造に新しい項目を追加しました。これはhandles.plot、他のコールバック (ボタンの押下や timerFcn コールバックなど) でそれらが役立つことがわかっていたためです。

ただし、これらのものを永続的に保存するには、'guidata' 関数を使用する必要があります。この関数は基本的に、呼び出し方handlesに応じて、変更された構造体を格納するか、コピーを取得します。handlesしたがって、開始関数の次の行は、変更されたハンドル構造 (.timer と .plot を追加) をメイン GUI に格納しています。

guidata(hObject,handles);

基本的に、何かを追加するときはいつでもhandles、変更を永続的にするためにその行が必要です。

それを呼び出す他の方法は次のとおりです。

handles = guidata(hObject); %hObject can be any handle who is a child of the main GUI.

これにより、GUI のハンドル構造が取得されます。

最後handles.output = hObjectは、GUI を起動したときのデフォルトの出力です。このようにMatlabのコマンドラインからGUIを呼び出すとh = myGUI; 、ハンドルがGUIに返されます。

于 2012-01-08T19:32:38.230 に答える
1

タイマー オブジェクトを使用する必要があります。プロットを更新する関数になるようにコールバックを設定します。

于 2012-01-06T00:01:14.743 に答える
1

データリンク とlinkdataコマンドでグラフをレスポンシブにするをご覧ください。

同じ変数が複数の図のプロットに表示される場合、任意のプロットを変数にリンクできます。リンクされたプロットは、Data Brushing を使用したグラフのマークアップと連携して使用できますが、単独でも使用できます。プロットをリンクすると、

  • ベース ワークスペースまたは関数内の変数の変更にグラフが応答するようにする
  • 変数エディターとコマンド ラインで変数を変更したときにグラフが応答するようにする
  • 一度に変数のさまざまなグラフィック表現に影響を与えるデータ ブラッシングを介して変数を変更します。
  • デバッグ用のグラフィカルな「ウォッチ ウィンドウ」を作成する

ウォッチ ウィンドウは、MATLAB 言語でプログラミングする場合に便利です。たとえば、データ処理アルゴリズムを調整してコードをステップ実行すると、関数がステートメントを実行するときに、変数の変化にグラフが反応することがわかります。

以下に示す簡単で汚いテストを作成しましたが、これがGUIと関数でどのように機能するかはわかりませんが、うまくいくかもしれません。

注 1:yプロットの自動更新を実際に確認するには、グローバルを変更するサブルーチンにブレーク ポイントを追加する必要がありました。データが急速に変更されている場合は、 drawow、pause、またはタイマーの組み合わせが必要になる場合があります。

function testLinking()
global x y
%Links failed if the global did not also exist in the base workspace
evalin('base','global x y');
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);

h = plot(x,y,'ydatasource','y','xdatasource','x');
linkdata on
testSub

function testSub()
%Test to see if a sub can make a linked global refresh
global x y
for i = 1:10
    %This should automatically update the plot.
    y = sin(x+i/10); 
end

編集:関数の構造によっては、グローバルの使用を回避する方法があるかもしれません...しかし、私はそれをあまり掘り下げる時間がありません.

于 2012-01-06T15:37:29.617 に答える
0

プロット関数を実行するシリアル オブジェクトにコールバックを追加できます。オブジェクトの 'BytesAvailableFcn' イベントにコールバックをアタッチする必要があります ( com オブジェクトのプロパティの詳細については、こちらを参照してください)

基本的に、com ポートで利用可能なバイトがある場合、特定の関数を実行するように matlab に指示します。あなたの場合、それはGUIを更新する機能になります。着信データを最初に処理する必要がある場合、コールバック関数は最初に信号処理を行い、次にプロット コマンドを行います。

于 2012-01-06T16:57:30.670 に答える