Matlab GUI因項目需求,不得不學的又雜又淺,趁着還沒徹底忘記,寫下來一些關鍵注意點。
命令行窗口輸入guide→Blank GUI→確定
根據自己的需求,拖動選擇對應的工具,如下圖所示
雙擊每一個對象,就可以彈出其檢查器,修改其屬性,字體大小、粗細、位置等,其中最關鍵的是兩個,一是String,二是Tag,String是用來修改對象中的文字,Tag是所調用的代碼名,這個要好的代碼習慣,儘量所見即所得,比如串口按鍵就用portbutton等。彈出式菜單的String,根據需要輸入多行。一般來說,習慣用面板將某一個模塊的各個功能圈起來,如上圖的控制區、發送區、接收區等
界面的拖動相對比較簡單,接下來就需要實現具體的功能,右鍵對象→查看回調→callback,即可調到代碼區。
我實現的功能及代碼主要包括以下部分
1.串口打開與關閉
1.1右鍵“端口號com1”的按鈕,打開callback。因爲在打開串口之前需要選擇對應的端口號。
function ppPort_Callback(hObject, eventdata, handles)
% hObject handle to ppPort (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: contents = cellstr(get(hObject,'String')) returns ppPort contents as cell array
% contents{get(hObject,'Value')} returns selected item from ppPort
global port
scoms = instrfind; %讀取所有存在的端口
if ~isempty(scoms)
stopasync(scoms); fclose(scoms); delete(scoms);%停止並且刪除串口對象
end
vall=get(handles.ppPort,'Value');
switch vall
case 1
port='com1';
case 2
port='com2';
case 3
port='com3';
case 4
port='com4';
case 5
port='com5';
end
這裏handles.xxx是抓取所點擊的項, handles.後面的爲所抓取函數的函數名,上述代碼抓取端口號com1~com5中的一個,也就是tag爲ppPort的對象的值。
在彈出式菜單的String裏每一行對應於case的1~5,點這些選項對應執行‘port=xxx’
1.2右鍵“打開串口”的按鈕,打開其callback函數
function pbOpenSerial_Callback(hObject, eventdata, handles)
% hObject handle to pbOpenSerial (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global port;
display(port)
Conm_num_str = port;
global Scom;
Scom=serial(Conm_num_str);
Scom.InputBufferSize=2000; %設置好buf的空間,足夠最多一次指令返回數據的存儲
Scom.timeout=3;
Scom.BaudRate=115200;
Scom.DataBits=8;
Scom.Parity='none';
Scom.StopBits=1;
Scom.ByteOrder='bigEndian';
fopen(Scom); %打開串口設備對象
fprintf("open serial success");
set(handles.pbOpenSerial,'enable','off');%打開串口的按鈕變成灰色,不再可用
這裏需要注意的是如果想在不同的函數下用同一個變量,需要用global定義全局變量,並且在每一個要用到這個這個變量的函數中都用global 定義一下。在打開串口的函數中,串口號port調用於串口選擇函數,串口配置Scom將會在關閉串口的函數中用到。
1.3右鍵“關閉串口”,選擇callback。
function pbCloseSerial_Callback(hObject, eventdata, handles)
% hObject handle to pbCloseSerial (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
set(handles.pbOpenSerial,'enable','on');%打開串口的按鈕重新可用
global Scom;%全局變量Scom
display(Scom)
fclose(Scom);
delete(Scom);
2.串口收發
在打開串口之後,開始執行數據的收發,並在發送區和接收區顯示
2.1串口通過發送區文本框以及“發送數據按”鈕實現串口發送
function pbSend_Callback(hObject, eventdata, handles)
% hObject handle to pbSend (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global d
global Scom
global tmp_hex
d=get(handles.editS,'String');%editS爲發送數據的文本編輯框,抓取裏面的字符串
if(iscell(d))%這句是debug出了問題之後的修正,有時候輸入的字符串會抓取爲元胞數組,需要提取其字符串,如果抓取的值直接是字符串那就處理字符串,如果抓取的是元胞數組,就提取其字符串並處理
m=d{1};
else
m=d
end
display(d)
switch m
case {'PRESS','press'}
a=['01';'03';'xx';'xx';'xx';'xx';'xx';'xx'];%本代碼採用modbus協議
data=hex2dec(a);%將16進制數字轉換爲10進制
fwrite(Scom,data);%將數據發送至串口
tmp_hex = fread(Scom,8)%接收單片機數據,並存入tmp_hex數組
tmp_int=tmp_hex(4)*256+tmp_hex(5);
tmp_dec=tmp_hex(6)*256+tmp_hex(7);
tmp_press=(tmp_int*1000+tmp_dec)/1000.0%保留三位有效數字
set(handles.editR,'string',['壓力: ',num2str(tmp_press),'mN']);%將數組的值轉換爲字符串並在接收區顯示editR爲接收數據的文本編輯框
press=[ press,tmp_press];%將數據存入press數組中,以便在座標系中繪製曲線
case ...
end
目前演示結果如下:
2.2發送區和接收區數據清空
function pbClearT_Callback(hObject, eventdata, handles)
% hObject handle to pbClearT (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
set(handles.editS,'String','');
% --- Executes on button press in pbClearR.
function pbClearR_Callback(hObject, eventdata, handles)
% hObject handle to pbClearR (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
set(handles.editR,'string','');
3 座標系顯示曲線
由於項目有多種待測量需要分時顯示,故採用一個彈出式菜單來控制曲線繪製。
function ppCurveDisplay_Callback(hObject, eventdata, handles)
% hObject handle to ppCurveDisplay (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: contents = cellstr(get(hObject,'String')) returns ppCurveDisplay contents as cell array
% contents{get(hObject,'Value')} returns selected item from ppCurveDisplay
global ch
global press;%串口收發生成press數組
vall=get(handles.ppCurveDisplay,'Value');
switch vall
case 1
ch='xxx',axes(handles.axes1),plot(R2T,'g'),hold on,plot(R3T,'b'),plot(R4T,'r')...;
case 2
ch='側向壓力',cla,axes(handles.axes1),plot(press,'b'), grid on ,xlabel('SampleNum'),ylabel('Press/mN'),title(ch);%cla用於清空曲線,否則會出現曲線的疊加,座標系的函數名爲axes1,抓取該座標系並對其進行操作
case 3
...
end
顯示結果如下,當然由於未連接設備,採集到的數據均爲0,故爲一條press=0mN的直線。
Matlab GUI實現簡單的很容易,但是在操作過程中會有各種各樣的bug,需要慢慢探索研究……