日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

matlab检测串口数据帧头,MATLAB 串口读取姿态数据及GUI实时动态显示设计

發(fā)布時間:2025/3/15 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 matlab检测串口数据帧头,MATLAB 串口读取姿态数据及GUI实时动态显示设计 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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

GUI設(shè)計效果:

姿態(tài)GUi.png

分別設(shè)置三個區(qū)域,分別為數(shù)據(jù)接收顯示區(qū)域,串口設(shè)置區(qū)域和區(qū)域顯示區(qū)域。

串口參數(shù)設(shè)置與上一篇基本一直,只是將串口號和波特率設(shè)置為全局變量。matlab GUI 編程可以看其他教程,主要調(diào)用函數(shù)參數(shù)與hObject,eventdata,handles。

hObject 和handles 都可以設(shè)置相應(yīng)的空間的性能,但是區(qū)別在于hObject只是一個局部變量,而handles 相當(dāng)于一個全局變量。當(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è)置部分基本與上一篇博客一致,有問題可以對照理解。

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

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

姿態(tài)gui2.png

【源方法】

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

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

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);

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

【源代碼】上傳到github

總結(jié)

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

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的matlab检测串口数据帧头,MATLAB 串口读取姿态数据及GUI实时动态显示设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。