2016-03-13 4 views
0

Я пытаюсь собрать данные с датчика акселерометра. У меня есть Arduino, делающий аналоговое цифровое преобразование сигнала и отправляя его через последовательный порт в MATLAB на Windows.Временное решение в режиме реального времени с использованием окон для фиксированного времени выборки

Я отправляю чтение каждые 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 последовательного чтения) Image 2 показывает, что данные сохранены с часами

Изображение 1: enter image description here

изображение 2: enter image description here

+0

Пожалуйста, внесите свой код и измерения в ваш вопрос. Вы не достигнете совершенной точности, потому что MATLAB не способен обрабатывать в реальном времени, но кривая должна быть (грубо) линейной. – Daniel

+0

Я добавил код, я провел некоторое исследование темы в режиме реального времени и увидел, что в Matlab есть панель инструментов, которая посвящает ядро ​​только для чтения данных с некоторых «конкретных» устройств, таких как National Instruments. Инструменты для сбора данных, я не знаю много знаю о том, как они это делают, но, видимо, должен быть путь вокруг этого, надеюсь, намного проще. Кстати, если частота дискретизации снижается, я увидел, что Matlab в некоторой степени способен справиться с этим, однако мне нужна высокая частота дискретизации, поэтому я не буду ее обрезать – AnarKi

+0

Эта строка 'length (scan (:, 1)) == 6 'потенциально отбрасывает сообщения, когда ваша система работает медленно, она может сразу получать два сообщения. – Daniel

ответ

1

Я знаю, что мой ответ не содержит быстрого и простого решения. Вместо этого он в основном дает советы о том, как перепроектировать вашу систему. Я работал в системах реального времени в течение нескольких лет и видел, что это было сделано неправильно слишком много времени. Возможно, можно просто «исправить», но работая с вашим текущим шаблоном связи, улучшающим производительность, но я убежден, что вы никогда не получите достоверную информацию о времени.

Я отвечу на это с точки зрения общей системы, вместо того, чтобы пытаться исправить ваш код. Где я вижу проблемы:

  1. В общем, это плохая идея добавить информацию о времени на принимающем ПК. Всякий раз, когда датчик способен и имеет часы, добавьте информацию о времени на саму систему датчиков. Это позволяет обеспечить точное относительное время между измерениями. Некоторая настройка часов может потребоваться, если часы на датчике установлены неправильно, но это только постоянное смещение.
  2. Переключение с ASCII-кодированных данных на двоичные данные. При установленной частоте дискретизации и скорости baut для каждого сообщения должно быть всего 50 байт.
  3. Напишите надежный приемник. Просто отказ от сообщений, которые вы «не понимаете», не является хорошей идеей. Всякий раз, когда буфер заполнен, вы можете получать несколько сообщений, если не используете правильный терминатор.
  4. Использовать prealocation. Вы знаете, насколько велики партии, которые вы хотите написать.

Простое решение для сообщения:

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{:}]; и попытаться разобрать его в пост-обработки. Если вы будете управлять производительностью, вы можете позже вернуться к обработке «на лету», но я рекомендую начать этот путь, чтобы получить систему.

+0

Даниэль благодарит за ответ, что вы говорите, это хороший способ оптимизировать дизайн, поэтому я собираюсь реализовать это – AnarKi