MATLAB实现串口输入数据的实时绘图

MATLAB实现串口输入数据的实时绘图

  最近做了一个基于单片机的心率计,其中需要用计算机将波形数据以实时绘图的方式呈现出来。参考了一些网上的资料,写了一个简单的matlab程序,记录一下。

0 说明

  1. 基本原理:通过手指指尖的血流变化反映脉搏变化。传感器(KY-039,淘宝上可以搜到)的一端是红外二极管,一端是光敏三极管,脉搏引起的血流变化引发光强变化,进而导致电压变化。
  2. 脉搏信号被一个红外传感器采集后,经过放大滤波电路输入单片机,再经ADC,从串口输出。
  3. 输出在0-1023范围内,需要用两个字节表示。

1 创建串口对象

  创建串口对象s,并对其部分参数进行设置。下面只设置了一部分,当然,可以根据自己的需要进一步设置,比如波特率之类,可以运行这段代码后在工作区点开s查看:
串口对象

s=serial('com3');  % COM
s.BytesAvailableFcnMode='byte';  
s.InputBufferSize=4096;
s.OutputBufferSize=1024;
s.BytesAvailableFcnCount=100;
s.ReadAsyncMode='continuous';
s.Terminator='CR';

2 数据读取与转化

  打开串口,同时打开一个文件保存数据。

fopen(s);    % 打开串口
fid=fopen('serial_data.txt','wt');

  寻找读取起点:

init = 1;
while(init~='#')
    init = fread(s,1,'uint8');
end
out = fread(s,2,'uint8');  % 8bit读两次

  这里 ‘#’ 是一个标志字符(这是单片机代码中设置的),因为需要用两个字节表示一个点的值,#的作用就是让程序知道,从这里开始往后两个字节拼起来是一个数。这组数据是不用的(其实要用也可以,但不差这一个点的数据),之后再读取就只需循环:

out = fread(s,3,'uint8');

  注意out是一个列向量,out(1)是#,out(2)是数值的高8位,out(3)是低8位。
  接下来是对数据的转换,将两个8位二进制数位拼接转成一个十进制数:

num = out(2)*256+out(3);

  或者也可以将这个数存在out(1)中,反正 ‘#’ 已经达成使命,现在它反而变成了一个累赘。

3 绘图

  设置一个向量t作为横坐标,长度是InputBufferSize,纵坐标上下留出margin的空间。

hold on
grid on
InputBufferSize = 100;
margin = 50;
t = 1:InputBufferSize;

  用InputBuffer存放当前需要绘制区域内的所有数值,即它的长度也是InputBufferSize。那么画“一帧”的图像就是:

plot([1:i],InputBuffer(1,1:i),'-r');
axis([t(1) t(InputBufferSize) min(InputBuffer)-margin max(InputBuffer)+margin]);

4 绘制动态图像

  怎么让上述图像动起来呢?其实很简单,只要将每次新读进来的数据放到InputBuffer的最后,InputBuffer中所有元素向前移动一格,再把坐标轴右移1,就得到了下一帧图像的全部信息。让这个过程循环往复,图线就动起来了。

for i = 1:1000
    t=t+1;
    for j = 2:InputBufferSize  % 循环左移一格
        InputBuffer(j-1) = InputBuffer(j);
    end
    out = fread(s,3,'uint8');   % 一次读出3个字符
    out = out';  % 其实没什么必要
    num = out(2)*256+out(3);
    fprintf(fid,'%g\n',num);  % 存入文件
    InputBuffer(InputBufferSize) = num;
    plot(t,InputBuffer(1,:),'-r');
    axis([t(1) t(InputBufferSize) min(InputBuffer)-margin max(InputBuffer)+margin]);
    pause(0.001);
end

  如果想做得再好一点,能呈现最开始从0慢慢长到InputBufferSize过程中的图线,那就在这段之前加一段:

for i = 1:InputBufferSize
    out = fread(s,3,'uint8');   % 一次读出3个字符
    out = out';
    num = out(2)*256+out(3);
    InputBuffer(i) = num;
    fprintf(fid,'%g\n',num);
    plot([1:i],InputBuffer(1,1:i),'-r');
    axis([t(1) t(InputBufferSize) min(InputBuffer)-margin max(InputBuffer)+margin]);
    pause(0.001);
end

  与上面一段类似,只是这里固定坐标轴,且新数据只加在InputBuffer的最后。
  最后别忘了关掉串口和文件~

fclose(s);
fclose(fid);

5 完整代码

clear;
s=serial('com4');
s.BytesAvailableFcnMode='byte';  % 串口设置
s.InputBufferSize=4096;
s.OutputBufferSize=1024;
s.BytesAvailableFcnCount=100;
s.ReadAsyncMode='continuous';
s.Terminator='CR';

fopen(s);    % 打开串口
fid=fopen('serial_data.txt','wt');
init = 1;
while(init~='#')
    init = fread(s,1,'uint8');
end
out = fread(s,2,'uint8');

hold on
grid on
InputBufferSize = 100;
margin = 50;
t = 1:InputBufferSize;
% InputBuffer = zeros(1,InputBufferSize);
for i = 1:InputBufferSize
    out = fread(s,3,'uint8');   % 一次读出3个字符
    out = out';
    num = out(2)*256+out(3);
    InputBuffer(i) = num;
    fprintf(fid,'%g\n',num);
    plot([1:i],InputBuffer(1,1:i),'-r');
    axis([t(1) t(InputBufferSize) min(InputBuffer)-margin max(InputBuffer)+margin]);
    pause(0.001);
end

for i = 1:1000
%     hold on
    t=t+1;
    for j = 2:InputBufferSize
        InputBuffer(j-1) = InputBuffer(j);
    end
    out = fread(s,3,'uint8');   % 一次读出3个字符
    out = out';
    num = out(2)*256+out(3);
    fprintf(fid,'%g\n',num);
    InputBuffer(InputBufferSize) = num;
    plot(t,InputBuffer(1,:),'-r');
    axis([t(1) t(InputBufferSize) min(InputBuffer)-margin max(InputBuffer)+margin]);
    pause(0.001);
end
fclose(s);
fclose(fid);

6 补充

  1. 如果需要中断运行,可以在命令行中Ctrl + C,但记得随后在命令行中输入fclose(s)以关闭串口,否则下次启动会报错。无论何种方式导致程序没有执行到fclose(s),都应在下次运行前手动关闭串口。
  2. 若开始运行时报错,先检查串口是否匹配,若匹配,再检查串口当前是否被其他程序占用,若没有,尝试重启MATLAB。(再不行,重启电脑,再不行我也不知道了2333
  3. 放几张运行结果图(更新了一张动图)
    在这里插入图片描述
    在这里插入图片描述
  • 50
    点赞
  • 360
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: 实现串口输入数据实时绘图可以通过以下步骤完成: 1. 连接串口设备:首先,你需要将电脑与串口设备(如Arduino或传感器)进行连接。确保串口连接正常并已正确安装驱动程序。 2. 打开串口:使用MATLAB的serial函数,打开串口连接。需要指定串口号、波特率和数据位等设置。 3. 实时绘图:创建一个图形窗口,用于显示实时绘图。使用MATLAB的figure和plot函数,绘制初始化的曲线或图形。 4. 循环读取数据并更新绘图:使用MATLAB编写一个无限循环,在循环内使用fread函数读取串口接收数据。将数据添加到绘图数据序列中,并使用MATLAB的set函数更新图形。 以下是大致代码框架,用于帮助理解: ```MATLAB % 设定串口参数 s = serial('COMX', 'BaudRate', 9600); % 替换X为正确的串口号 fopen(s); % 创建绘图窗口 figure; h = plot(NaN, NaN); % 初始化曲线 % 实时绘图循环 while true % 读取串口数据 data = fread(s, 1, 'float'); % 根据实际情况设置数据类型和字节数 % 更新绘图数据 xdata = get(h, 'XData'); ydata = get(h, 'YData'); xdata = [xdata, xdata(end)+1]; % 横坐标递增 ydata = [ydata, data]; set(h, 'XData', xdata, 'YData', ydata); % 调整坐标轴范围,保持滚动显示 xlim([xdata(1), xdata(end)]); % 根据实际情况设置横坐标范围 % 绘图刷新 drawnow; end % 关闭串口 fclose(s); ``` 上述代码仅为示例,具体实现需要根据实际情况进行适当修改。同时,你也可以根据需求添加其他处理,如数据解析、滤波等。 ### 回答2: 要实现串口输入数据实时绘图,可以使用MATLAB的Instrument Control Toolbox来完成。 首先,将串口设备连接到计算机上,并获取串口对象。可以使用MATLAB的serial函数来创建一个串口对象,指定串口号、波特率等参数。 然后,打开串口连接,使用fopen函数打开串口连接,准备开始数据接收。 使用MATLAB的figure函数创建一个图形窗口,用于绘制实时数据图形。 在一个循环中,使用fread函数从串口对象中读取数据。读取的数据可以是一个数值,也可以是一个数据向量。将读取的数据存储到一个变量中,用于后续的绘图。 使用MATLAB的plot函数将读取到的数据绘制在图形窗口中。 重复上述步骤,实现不断地从串口接收数据实时绘制图形。 最后,通过使用MATLAB的fclose函数关闭串口连接,释放资源。 总结起来,实现串口输入数据实时绘图的步骤包括:创建串口对象、打开串口连接、创建图形窗口、循环读取串口数据、绘制图形、关闭串口连接。 ### 回答3: 要使用Matlab实现串口输入数据实时绘图,首先需要准备好以下材料: 1. 一台装有Matlab软件的电脑 2. 串口接口硬件(例如Arduino开发板) 3. USB连接线缆 接下来,按照以下步骤进行操作: 1. 使用Matlab软件打开“串口设置工具”: 在主界面的“工具”菜单中,选择“串口设置工具”选项,弹出串口设置工具对话框。 2. 配置串口参数: 在串口设置工具对话框中,选择正确的“串口号”和“波特率”,并设置其他参数如数据位、停止位、奇偶校验位等。 3. 打开串口后获取数据: 在Matlab命令窗口中输入以下命令来打开串口并获取数据: s = serial('COMx'); %将x替换为正确的串口号 fopen(s); 4. 设定绘图参数: 设置图形窗口的坐标轴、标题和轴刻度等信息,并根据需要配置绘图样式(例如线型、颜色等)。 5. 绘制实时图形: 使用一个循环来实时获取串口输入数据,然后将数据添加到绘图中。例如,可以使用“drawnow”来刷新图形窗口,以实时显示数据。 6. 关闭串口: 在绘图完成后或需要停止时,记得关闭串口,释放相关资源。在Matlab命令窗口中输入以下命令: fclose(s); delete(s); clear s; 总结: 通过上述步骤,我们可以使用Matlab实现串口输入数据实时绘图接收到的数据实时显示在Matlab的图形窗口中,可以根据需要调整绘图样式,并可以随时关闭串口和停止绘图

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值