【问题标题】:Real Time Workaround using windows for fixed sampling time使用固定采样时间窗口的实时解决方法
【发布时间】:2016-06-28 14:37:58
【问题描述】:

我正在尝试从加速度计传感器收集数据。我有一个 Arduino 进行信号的模数转换,并通过串行端口将其发送到 Windows 上的 MATLAB。

我每 5 毫秒通过串口从 Arduino 发送一个读数。我正在使用 MATLAB 在向量中的串行读取以及使用时钟方法读取数据的时间来保存该数据。

如果我要绘制在我读取的那一秒时保存的向量列,我会得到一条曲线(非线性),当我查看 1 读取和另一个读取之间的差异时,我看到它略有不同。

有什么方法可以让数据实时保存,采样时间固定?

注意:我使用的是 250000 波特率。

Matlab 代码:

    %%%%% Initialisation %%%%%
clear all
clc
format shortg

cnt = 1;%File name changer
sw = 1;%switch: 0 we add to current vector and 1 to start new vector
%%%%% Initialisation %%%%%

%%%%% Communication %%%%%
arduino=serial('COM7','BaudRate',250000);
fopen(arduino);
%%%%% Communication %%%%%

%%%%% Reading from Serial and Writing to .mat file%%%%%
while true,
    if sw == 0,
        if (length(Vib(:,1))==1000),% XXXX Samples in XX minutes
            filename = sprintf('C:/Directory/%d_VibrationReading.mat',cnt);
            save (filename,'Vib');
            clear Vib
            cnt= cnt+1;
            sw = 1;
        end
    end
    scan = fscanf(arduino,'%f');
    if isfloat(scan) && length(scan(:,1))==6,% Change length for validation
        vib = scan';
        if sw == 1,
            Vib = [vib clock];
            sw = 0;
        else
            Vib = [Vib;vib clock];
        end
    end
end
%%%%% Reading from Serial and Writing to .mat file%%%%%

% Close Arduino Serial Port
fclose(arduino);

图 1 显示了通过串行接收的数据(每行对应 1 次串行读取) 图 2 显示了与时钟一起保存的数据

图 1:

图 2:

【问题讨论】:

  • 请将您的代码和测量值放入您的问题中。您不会达到完美的精度,因为 MATLAB 无法进行实时处理,但曲线应该是(大致)线性的。
  • 我已经添加了代码,我对实时主题进行了一些研究,发现 matlab 中有一个工具箱,专门用于从一些“特定”设备(如 National)读取数据Instruments 数据采集工具,我不太了解它们是如何做到的,但显然必须有办法解决这个问题,希望更简单。顺便说一句,如果你的采样频率变低,我看到 Matlab 有点能够处理这个问题,但是我需要一个高采样率,这样就不会为我削减它
  • 该行length(scan(:,1))==6 可能会丢弃消息,当您的系统运行缓慢时,它可能会同时收到两条消息。
  • 是的,但这是(我发现)确保不会由于串行通信而读取错误字符的唯一方法
  • 您能否将收到的示例消息放入问题中?我的猜测是你已经超过了可用的波特率。每个数字使用多少个字符?

标签: windows matlab real-time frequency sampling


【解决方案1】:

我知道我的回答不包含快速简便的解决方案。相反,它主要提供如何重新设计系统的建议。我使用实时系统工作了几年,发现它做错了太多次。可能只是“修复”,但使用您当前的通信模式调整性能,但我相信您永远不会收到可靠的时间信息。

我将从一般系统设计的角度回答这个问题,而不是尝试修复您的代码。我在哪里看到问题:

  1. 通常,在接收 PC 上附加时间信息是个坏主意。只要传感器有能力并且有时钟,就在传感器系统本身上附加时间信息。这允许测量之间的准确相对时间。当传感器上的时钟设置不正确时,可能需要进行一些时钟调整,但这只是一个恒定的偏移量。
  2. 从 ASCII 编码数据切换到二进制数据。设置采样率和波特率后,每条消息只有 50 个字节。
  3. 编写一个健壮的接收器。只删除您“不理解”的消息不是一个好主意。每当缓冲区已满时,您可能会收到多条消息,除非您使用适当的终止符。
  4. 使用预分配。您知道要编写的批次有多大。

消息的简单解决方案:

2 bytes - clock milliseconds
4 bytes - unix timestamp of measurement
For each sensor
    2 bytes int32 sensor data
2 bytes - Terminator, constant value. Use a value which is outside the range for all previous integers, e.g. intmax

理论上,这种消息格式应该允许您使用 21 个传感器。现在到接收部分:

要让第一个版本以良好的性能运行,请使用大量数据(size 参数)调用fread (serial),并将所有读数转储到一个大型元胞数组中。比如:

C=cell(1000,1)
%seek until you hit a terminator
while not(terminator==fread(arduino,1));
for ix=1:numel(C)
    C{ix}=fread(arduino,'int16',1000)
end
fclose(arduino);

读取数据后,将其附加到单个向量:C=[C{:}]; 并尝试在后处理中对其进行解析。如果您管理性能,您稍后可能会返回到动态处理,但我建议以这种方式开始以建立系统。

【讨论】:

  • Daniel 非常感谢您的回答,您所说的听起来是优化设计的好方法,所以我打算实现它
猜你喜欢
  • 2015-02-02
  • 1970-01-01
  • 2020-05-04
  • 2020-10-23
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 2014-11-23
相关资源
最近更新 更多