MATLAB 串口讀取姿態(tài)數(shù)據(jù)及GUI實(shí)時(shí)動(dòng)態(tài)顯示設(shè)計(jì)

上一篇實(shí)現(xiàn)了Matlab 對(duì)串口數(shù)據(jù)的讀取,數(shù)據(jù)可以讀取并且保存到本地。本文主要設(shè)計(jì)GUI并且動(dòng)態(tài)的顯示曲線。可以更直觀的觀察實(shí)時(shí)的姿態(tài)數(shù)據(jù)和傳感器數(shù)據(jù)。

GUI設(shè)計(jì)效果:

姿態(tài)GUi.png

分別設(shè)置三個(gè)區(qū)域,分別為數(shù)據(jù)接收顯示區(qū)域,串口設(shè)置區(qū)域和區(qū)域顯示區(qū)域。
串口參數(shù)設(shè)置與上一篇基本一直,只是將串口號(hào)和波特率設(shè)置為全局變量。matlab GUI 編程可以看其他教程,主要調(diào)用函數(shù)參數(shù)與hObject,eventdata,handles。
hObject 和handles 都可以設(shè)置相應(yīng)的空間的性能,但是區(qū)別在于hObject只是一個(gè)局部變量,而handles 相當(dāng)于一個(gè)全局變量。當(dāng)要在函數(shù)中設(shè)置另外控件的性能,只能調(diào)用handles。

參數(shù)設(shè)置區(qū)域

參數(shù)設(shè)置區(qū)域主要實(shí)現(xiàn)的是串口的選擇和波特率的設(shè)置。GUI上通過下拉菜單選擇。在相應(yīng)空間的callback 函數(shù)中添加初始化代碼:

  • COM callback 函數(shù)設(shè)置
% --- Executes on selection change in ppcom.
function ppcom_Callback(hObject, eventdata, handles)
% hObject    handle to ppcom (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 ppcom contents as cell array
%        contents{get(hObject,'Value')} returns selected item from ppcom
global COM;
val=get(hObject,'value');
switch val
    case 1
        COM='COM1';
        fprintf('ceshi_COM=1\n');
    case 2
        COM='COM2';
    case 3
        COM='COM3';
    case 4
        COM='COM4';
    case 5
        COM='COM5';
    case 6
        COM='COM6';
    case 7
        COM='COM7';
    case 8
        COM='COM8';
    case 9
        COM='COM9';
end

波特率callback 函數(shù)設(shè)置

function ppbandrate_Callback(hObject, eventdata, handles)
% hObject    handle to ppbandrate (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 ppbandrate contents as cell array
%        contents{get(hObject,'Value')} returns selected item from ppbandrate
global rate;
val=get(hObject,'value');
switch val
    case 1
        rate=9600;
    case 2
        rate=19200;
    case 3
        rate=38400;
    case 4
        rate=115200;
end

打開串口:

function activityReco_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to activityReco (see VARARGIN)

global COM;
global rate;
global act a;
global count;
global act_data t;
global p x;
count=1;x=-15;
act=zeros(12,1);
t=0;
p = plot(t,act,...
   'EraseMode','background','MarkerSize',5);
% axis([x x+20 -200 200]);
% grid(handles.axplotact,'on');
set(handles.axplotact,'XLim',[x x+20],'YLim',[-200 200]);
set(handles.axplotact,'XTickLabel',[]);
legendaxes=legend(handles.axplotact,{'Yaw','Pitch','Roll','Accx','Accy','Accz','GYROx','GYROy','GYROz','Magx','Magy','Magz'},1);
set(legendaxes,'Location','northeastoutside');
act_data=[]; a=[];
COM='COM5'
rate = 115200;
set(handles.ppcom,'value', 5);
set(handles.ppbandrate,'value',4);
set(handles.pbcloseserial,'Enable','off');
% Choose default command line output for activityReco
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);

關(guān)閉串口:

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)
global s;
fclose(s);
delete(s);
set(handles.pbcloseserial,'Enable','on');
set(handles.pbopenserial,'Enable','off');
fprintf('close com');

串口參數(shù)設(shè)置部分基本與上一篇博客一致,有問題可以對(duì)照理解。

姿態(tài)數(shù)據(jù)動(dòng)態(tài)顯示

姿態(tài)和傳感器數(shù)據(jù)總共12位。具有不同的單位,為了顯示效果,特地將各個(gè)數(shù)據(jù)歸一在[-200,200]的范圍顯示,整體實(shí)現(xiàn)單線程串行顯示。這里實(shí)現(xiàn)動(dòng)態(tài)顯示的方法是背景擦除方法。


姿態(tài)gui2.png

matlab單線程動(dòng)態(tài)曲線繪制有幾種方法,參見博客(http://www.cnblogs.com/duanp/archive/2008/12/02/Matlab-Plot-Animation.html)

【源方法】

t=[0]
m=[sin(t);cos(t)]
p = plot(t,m,...
   'EraseMode','background','MarkerSize',5);%%定義數(shù)據(jù)種類,因此t和m不能為空
x=-1.5*pi;           %坐標(biāo)初始設(shè)置小于數(shù)據(jù)起始位置,任意設(shè)置
axis([x x+2*pi -1.5 1.5]); %繪圖坐標(biāo)設(shè)置,橫坐標(biāo)設(shè)置為x的參數(shù)
grid on;


for i=1:1000
    t=[t 0.1*i];                   %Matrix 1*(i+1)
    m=[m [sin(0.1*i);cos(0.1*i)]]; %Matrix 2*(i+1)
    set(p(1),'XData',t,'YData',m(1,:))
    set(p(2),'XData',t,'YData',m(2,:))    
    drawnow
    x=x+0.1;    
    axis([x x+2*pi -1.5 1.5]);
    pause(0.5);
end

這里我用的是采用背景擦除的方法,顯示動(dòng)態(tài)的曲線,并且動(dòng)態(tài)改變坐標(biāo)系。整體思路是顯示的橫坐標(biāo)t和縱坐標(biāo)act_data只存儲(chǔ)400個(gè)數(shù)據(jù),當(dāng)大于400 ,則刪除前端數(shù)據(jù)保持整體為400個(gè)。然后每次解算則顯示一次。

function ReceiveCallback( obj,event,handles)     %創(chuàng)建中斷響應(yīng)函數(shù)  
   global s a fid;
   global count;
   global  act;
   global act_data;
   global t x p;
   str = fread(s,100,'uint8');%讀取數(shù)據(jù)
   hex=dec2hex(str);
  IMU_data = [];Motion_data=[];
  sign_head1=hex2dec('A5');sign_head2 = hex2dec('5A');
  sign_finish=hex2dec('AA');sign_IMU=hex2dec('A1');sign_Motion=hex2dec('A2');

  a= [a;str];
  j=1;
  while (~isempty(a))
        if j>size(a,1)
           break;
        end
        if a(j)==sign_head1 && a(j+1) == sign_head2 
            if (j+a(j+2)+1) > size(a,1) 
                break;
            end
            index_start = j+2;
            index_finish= index_start + a(j+2)-1;
            pack = a(index_start:index_finish);
            if ~isempty(pack) &&pack(pack(1))== sign_finish
                  if pack(2) == sign_IMU
                        IMU_data(1,:) = Get_IMU(pack);
                        j = index_finish;
                        continue;
                  end
                   if pack(2) ==sign_Motion
                          Motion_data(1,:) = Get_Motion(pack);
                          j = index_finish;
                   end
                   if ~isempty(IMU_data) && ~isempty(Motion_data)
                        count=count+1;
                        act_data = [IMU_data,Motion_data]';
%                         fprintf(fid,'%8.1f%8.1f%8.1f%8.1f%8.1f%8.1f%8d%8d%8d%8d%8d%8d%8d%8d%8d\n',act_data);
                        t=[t 0.1*count]; 
                        act=[act,[act_data(1:3);act_data(7:9)*100/16384;act_data(10:12)*pi/180;act_data(13:15)]];%%繪圖數(shù)據(jù)歸一化-200-200
                        set(handles.edshowdata,'string',num2str(act_data));
             
                        axis(handles.axplotact);
                        if ~get(handles.rbpause,'Value')
                            if get(handles.rbshowangles,'Value')
                                    set(p(1),'XData',t,'YData',act(1,:));
                                    set(p(2),'XData',t,'YData',act(2,:));
                                    set(p(3),'XData',t,'YData',act(3,:));
                            end
                            if get(handles.rbshowacc,'Value')
                                    set(p(4),'XData',t,'YData',act(4,:));
                                    set(p(5),'XData',t,'YData',act(5,:));
                                    set(p(6),'XData',t,'YData',act(6,:));
                            end
                            if  get(handles.rbshowgyro,'Value')
                                    set(p(7),'XData',t,'YData',act(7,:));
                                    set(p(8),'XData',t,'YData',act(8,:));
                                    set(p(9),'XData',t,'YData',act(9,:));
                            end
                            if get(handles.rbshowmag,'Value')
                                    set(p(10),'XData',t,'YData',act(10,:));
                                    set(p(11),'XData',t,'YData',act(11,:));
                                    set(p(12),'XData',t,'YData',act(12,:));
                            end
                             drawnow
                              x=x+0.1;
                             set(handles.axplotact,'ytick',-200:50:200);
                             axis(handles.axplotact,[x x+20 -200 200]);
%                            set(handles.axplotact,'xtick',x:x+20);
                             if size(t,2) >400
                                 t(1)=[];
                                act(:,1)=[];
                              end
                        end 
                   end
%                   set(handles.edshowdata,'String',num2str(act));
                    Motion_data=[];IMU_data=[];
                    a(1:index_finish)=[];
                    j=1;
%                   pause(0.005);
            end
         else
                j=j+1;
        end
  end

需要注意axes 和axis的區(qū)別,axes 是GUI控件名,axis用來設(shè)置figure的坐標(biāo)。這里

axis(handles.axplotact);

是用來鎖定后面操作的對(duì)象,即后面幾個(gè)set函數(shù)都是對(duì)handles.axplotact進(jìn)行設(shè)置,就不必要每個(gè)set前面都添加handles.axplotact了。drawnow用來繪制,使整個(gè)過程更流暢。下面留了兩個(gè)axes控件,用來實(shí)現(xiàn)三維傳感器空間位置顯示和相對(duì)坐標(biāo)系解算的顯示。
【源代碼】上傳到github

總結(jié)

整體來說MATLAB GUI設(shè)計(jì)還是挺好入手,了解一點(diǎn)callback就能入手了。基本需要注意的函數(shù)為hObject 和handles,get和set(屬性獲取和設(shè)置)。暫時(shí)只是顯示數(shù)據(jù),但是存在一點(diǎn)延時(shí),還不確定是中斷和fread的問題還是單線程串行顯示的問題。后面打算實(shí)現(xiàn)三維空間顯示和地球三維坐標(biāo)解算和顯示。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,247評(píng)論 6 543
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,520評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,362評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,805評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,541評(píng)論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,896評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,887評(píng)論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,062評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,608評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,356評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,555評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,077評(píng)論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,769評(píng)論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,175評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,489評(píng)論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,289評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,516評(píng)論 2 379

推薦閱讀更多精彩內(nèi)容