实时解决方法使用窗口固定采样时间

时间:2016-03-13 16:15:32

标签: windows matlab real-time frequency sampling

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

我通过串口从Arduino每5ms发送一次读数。我使用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: enter image description here

图片2: enter image description here

1 个答案:

答案 0 :(得分:1)

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

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

  1. 通常,在接收PC上附加时间信息是个坏主意。只要传感器能够并且有时钟,就将时间信息附加到传感器系统本身。这允许测量之间的精确相对定时。当传感器上的时钟设置不正确时,可能需要进行一些时钟调整,但这只是一个恒定的偏移。
  2. 从ASCII编码数据切换到二进制数据。设置采样率和保证率后,每封信息只有50个字节。
  3. 写一个强大的接收器。只是删除你不明白的消息"不是个好主意。只要缓冲区已满,除非使用正确的终结符,否则可能会收到多条消息。
  4. 使用预分配。你知道你想要写的批次有多大。
  5. 消息的简单解决方案:

    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个传感器。现在到接收部分:

    要使第一个版本以良好的性能运行,请使用大批量数据(fread (serial)参数)调用size并将所有读数转储到大型单元阵列中。类似的东西:

    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{:}];并尝试在后处理中解析它。如果你管理性能,你可能会在以后返回动态处理,但我建议以这种方式开始建立系统。