用matlab实时读取串口数据并动态显示曲线

原创 2016年08月29日 17:08:00

最近为了方便监控IMU的地磁传感器(HMC5983)数据,用matlab的GUI做了一个简易的串口助手,可实时显示地磁传感器X Y Z三轴的数据,并动态的显示曲线图。

*1. 串口助手的GUI图如下:

*2. 连接串口后的数据图如下(绘图时可勾选要显示的数据):

*3. 我所使用的串口发送的数据格式是

sprintf(buff,"%8f %8f %8f\n",IMU_MAGX,IMU_MAGY,IMU_MAGZ);

*4. 现将最主要的“打开串口”按钮回调函数和串口的回调函数分享出来:

“打开串口”按钮的callback函数:

function open_serial_Callback(hObject, eventdata, handles)
%   【打开/关闭串口】按钮的回调函数
%% 定义一些全局变量并初始化
global XData; %定义一全局变量,坐标轴X轴的数据
global YData1;%坐标轴IMU_MAGX的数据
global YData2;%坐标轴IMU_MAGY的数据
global YData3;%坐标轴IMU_MAGZ的数据
global Xlim;%坐标轴X轴的范围
global L1;%用来存储IMU_MAGX线的句柄
global L2;%用来存储IMU_MAGY线的句柄
global L3;%用来存储IMU_MAGZ线的句柄
global Checkbox_x;%用来判定是否选中了IMU_MAGX复选框
global Checkbox_y;%用来判定是否选中了IMU_MAGY复选框
global Checkbox_z;%用来判定是否选中了IMU_MAGZ复选框
Checkbox_x = 0;%初始化为未选中
Checkbox_y = 0;
Checkbox_z = 0;
XData = 0;%初始化坐标轴的数据为0
YData1 = 0;
YData2 = 0;
YData3 = 0;
Xlim = 0;

%打开串口,并初始化相关参数
%% 若按下【打开串口】按钮,打开串口
if get(hObject,'value')
%% 获取串口的端口名
com_n = sprintf('com%d', get(handles.com, 'value'));

%% 获取波特率
rates = [9600 38400 115200];
baud_rate = rates(get(handles.baudrate, 'value'));
%% 获取校验位设置
switch get(handles.jiaoyan, 'value')
case 1
jiaoyan = 'none';
case 2
jiaoyan = 'odd';
case 3
jiaoyan = 'even';
end
%% 获取数据位个数
data_bits = 5 + get(handles.data_bit, 'value');
%% 获取停止位个数
stop_bits = get(handles.stop_bit, 'value');
%% 创建串口对象
scom = serial(com_n);
%% 配置串口属性,指定其回调函数
set(scom, 'BaudRate', baud_rate, 'Parity', jiaoyan, 'DataBits',...
data_bits, 'StopBits', stop_bits,...
'BytesAvailableFcnMode', 'Terminator', 'BytesAvailableFcn', {@my_callback, handles});
%% 将串口对象的句柄作为用户数据,存入窗口对象
set(handles.figure1, 'UserData', scom);
%% 尝试打开串口
try
fopen(scom);  %打开串口
catch   % 若串口打开失败,提示“串口不可获得!”
msgbox('串口不可获得!');
set(hObject, 'value', 0);  %弹起本按钮 
return;
end
%% 能够打开串口后,设定绘图的相关属性
if get(handles.checkbox1,'value')
Checkbox_x = 1;
L1 = plot(handles.axes,XData,YData1,'r','EraseMode','none','MarkerSize',5);
hold on;
end
if get(handles.checkbox2,'value')
Checkbox_y = 1;
L2 = plot(handles.axes,XData,YData2,'b','EraseMode','none','MarkerSize',5);
hold on;
end
if get(handles.checkbox3,'value')
Checkbox_z = 1;
L3 = plot(handles.axes,XData,YData3,'m','EraseMode','none','MarkerSize',5);
end
set(handles.axes,'XLim',[Xlim-400 Xlim+100],'YLim',[-2 +2]);%设定坐标轴的范围
grid on; %绘出网格
%% 设定其它按钮的属性
set(handles.pause_start,'enable','on');
set(hObject,'string','关闭串口');
set(handles.lamb,'backgroundcolor','g');
 else %若关闭串口 
%% 删除line对象
Linehandle = get(gca,'children');%获取坐标轴的子对象的句柄
delete(Linehandle);
%% 停止并删除串口对象
scoms = instrfind;
fclose(scoms);
delete(scoms);
set(hObject,'string','打开串口');
set(handles.lamb,'backgroundcolor','r');
set(handles.pause_start,'enable','off');
set(handles.pause_start,'string','暂停显示');
set(handles.pause_start,'value',0);

end 

串口的回调函数:

function my_callback(obj,~,handles)
%   串口的BytesAvailableFcn回调函数
%% 定义一些全局变量
    global XData;
    global YData1;
    global YData2;
    global YData3;
    global Xlim;
    global L1;
    global L2;
    global L3;
    global Checkbox_x;
    global Checkbox_y;
    global Checkbox_z;
%% 每运行一次本函数X轴的数据+1
    Xlim = Xlim+1;
    XData =[XData Xlim];

%% 接收串口发送过来的数据(这里有时会出现BUG,具体原因不详)
    outdata = fscanf(obj);%接收串口发来的ASII数据,串口发过来的数据是字符串“IMU_MAGX IMU_MAGY IMU_MAGZYData = str2num(outdata);%将字符串转化成数值类型
    YData1 = [YData1 YData(:,1)];%存储IMU_MAGX的数据
    YData2 = [YData2 YData(:,2)];%存储IMU_MAGY的数据
    YData3 = [YData3 YData(:,3)];%存储IMU_MAGZ的数据
%% 限定坐标轴X Y的数组长度不能超过500,防止数据过多时易导致内存消耗过大卡死
    if (length(XData)) > 500
        XData = XData(:,2:end);%数组长度一旦超过500就丢弃第1列的值
    end
    if (length(YData1)) > 500
        YData1 = YData1(:,2:end);
    end
    if (length(YData2)) > 500
        YData2 = YData2(:,2:end);
    end
    if (length(YData3)) > 500
        YData3 = YData3(:,2:end);
    end
%% 通过判定勾选的复选框的值来更新相应Y轴坐标的数据
if (~get(handles.pause_start,'value'))%如果点击了暂停显示,是停止更新Y轴的数据
    if Checkbox_x
        set(L1,'Xdata',XData,'YData',YData1);
    end
    if Checkbox_y
        set(L2,'Xdata',XData,'YData',YData2);
    end
    if Checkbox_z
        set(L3,'Xdata',XData,'YData',YData3);
    end
end
%% 求出Y轴数据的最小最大值
    min_1 = min(YData1(:));
    min_2 = min(YData2(:));
    min_3 = min(YData3(:));
    max_1 = max(YData1(:));
    max_2 = max(YData2(:));
    max_3 = max(YData3(:));
%% 通过判定复选框的勾选值来采用相应的最小最大值,并求出整个Y轴数据的最小最大值
    if Checkbox_x && Checkbox_y && Checkbox_z
        min_array = [min_1 min_2 min_3];
        max_array = [max_1 max_2 max_3];
    elseif Checkbox_x && Checkbox_y
        min_array = [min_1 min_2];
        max_array = [max_1 max_2]; 
    elseif Checkbox_y && Checkbox_z
        min_array = [min_2 min_3];
        max_array = [max_2 max_3]; 
    elseif Checkbox_x
        min_array = min_1;
        max_array = max_1;
    elseif Checkbox_y
        min_array = min_2;
        max_array = max_2;
    elseif Checkbox_z
        min_array = min_3;
        max_array = max_3;
    else
        min_array = -2 + 0.2;
        max_array = 2 + 0.2;
    end
        min_all = min(min_array);
        max_all = max(max_array);
%% 更新坐标轴范围
if (~get(handles.pause_start,'value'))%如果点击了暂停显示,是停止更新坐标轴范围
    set(handles.axes,'XLim',[Xlim-400 Xlim+100],'YLim',[min_all-0.2  max_all+0.2]);
end
%% 将数值数据格式化成字符串
    IMU_MAGX = sprintf('%f',YData(:,1));
    IMU_MAGY = sprintf('%f',YData(:,2));
    IMU_MAGZ = sprintf('%f',YData(:,3));

%% 显示接收的字符串
if (~get(handles.pause_start,'value'))
    set(handles.display_x,'string',IMU_MAGX);
    set(handles.display_y,'string',IMU_MAGY);
    set(handles.display_z,'string',IMU_MAGZ);
end

*5. 为方便大家阅读,我对代码进行了详细的注释,希望对有需要的人有所帮助;另我这代码写得并不简洁,希望大家能优化改进

参考书籍:《MATLAB GUI设计学习手记》罗华飞著

版权声明:本文为博主原创文章,未经博主允许不得转载。

highchart实时曲线实例:highchart实时曲线,java web

最近研究将传感器传过来的数据以实时曲线的形式显示在web前端,在网上找了又找,最终实现了基本功能,拿出来和大家分享一下~~ 曲线是用Highchairs实现的,使用起来非常方便~~ web...

【OpenBCI】(1):Matlab实时读取数据流(labstreaminglayer)

OpenBCI是个面向脑机接口EEG信号采集的开源硬件,本文使用python SDK(因为OpenBCI官方还没有Matlab的SDK,Matlab读个串口那么难吗?肯定是开发人员懒)实时获取Open...

C#调用matlab函数详细步骤和例程

C#调用matlab函数详细步骤和例程 参考文档:http://www.csdn123.com/html/blogs/20131107/94039.htm        在项目过程中需要在ASP.NE...

惯性导航系统、加速度计、陀螺仪原理

1. 惯性导航系统 INS( Inertia Navigation System,以下简称惯导) 是一种利用惯性传感器测量载体的比力及角速度信息,并结合给定的初始条件实时推算速度、位置、姿态等参数的自...

vb串口数据采集及曲线动态显示

  • 2014年10月08日 09:06
  • 78KB
  • 下载

python 处理csv数据 动态显示曲线 matplot动画

python matplotlib animation import csv

C# chart控件实时动态显示数据

这里介绍了一个最简单的实时显示数据的例子
  • lj22377
  • lj22377
  • 2014年08月04日 18:51
  • 14441

C#串口采集短信GSM chart图表使用示例 保存数据到access数据库和每日.txt文件并实时显示各参数曲线

C#串口采集短信GSM数据采集。 可以实时采集多终端24小时数据,存入access数据库和每日.txt文件,并实时显示各参数曲线。 可以按终端按日期查询历史数据。 接收数据格式:$REP,H3,160...

Matlab使用Plot函数实现数据动态显示方法总结

引子 对于真实系统或者仿真平台,数据是增量式的产生的。Matlab除了强大的矩阵运算外,还具有强大的数据可视化库。由于静态画图的方法较多,本文只针对增量式数据流的动态显示。本文主要介绍几种Matl...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用matlab实时读取串口数据并动态显示曲线
举报原因:
原因补充:

(最多只允许输入30个字)