Create a buffer matrix in order to perform real-time operations on incoming data

조회 수: 2 (최근 30일)
Hello.
I have data incoming to MATLAB via RS232 at a rate of one byte every 256Hz
In order to perform frequency analysis and filtering I need to break this incoming stream of data into 'chunks' to be processed. To this end I have been trying to create an input buffer that stores 32 bytes of selected data, on which I can perform operations.
I have tried numerous ways of implementing my plan, which is shown in a basic form in the code below. Unlike other languages MATLAB seems to go nuts about modifying the counter variable from within a loop, and seems to outright ignore "counter = 1;", which messes up the whole plan.
I am very open to other methods that will achieve the same result. I have been stuck on this annoying little issue for a week now and am I'm very grateful for any help that will allow me to move on.
Please be aware I am relatively new to MATLAB, so please do not assume prior knowledge.
Thank you once again. The breif section of code below is a general summary of the problem, not the complete code. The complete code can be found underneath the summary.
The lines: tempvariable = buffercounter + 1; buffercounter = tempvariable; are to circumvent some wierd matlab feature that creates an error when simply using "buffercounter = buffercounter +1;"
counter = 1;
Inbuff1 = zeros(32,1); %Pre-allocate the input buffer
for n = 1:(256*capturetime)
rawdata = fread(hCom,17,'uchar'); %read in the next packet
if counter <= 32
Inbuff1 = vertcat(Inbuff1, 'the selected byte');
counter = counter +1;
else
CH1 = vertcat(CH1, Inbuff1); %copy buffered data
Inbuff1 = zeros(32,1);
counter = 1; %this line is ignored entirely
end
THE FULL CODE FOR THIS SECTION IS LISTED BELOW:
clear;
capturetime = 5;
delete(instrfindall); % Read in a block of data from the OpenEEG board
hCom = serial('COM1','BaudRate',57600,'timeout',5);% Open the serial port
fopen(hCom); % Open the serial port
FPshift = zeros(1,3); %create a shift register
while ((FPshift(1,2) ~= (165)) || (FPshift(1,3) ~= (90))) %while data is not in position:-
FPshift(1,1:2) = FPshift(1,2:3); %shift bits along one
FPshift(1,3) = fread(hCom, 1, 'uchar');
end %Now we have detected the start-bits of the first packet
rawdata = zeros(17,1);
rawdata(1:2,1) = FPshift(1,2:3); %put the packet headers that we stole earlier back
rawdata(3:17,1) = fread(hCom, 15,'uchar'); %get the rest of the first packet
CH1(1,1) = ( ( (rawdata(5,1) * 256) + (rawdata(6,1))) - 512); %put the first packet into a grand matrix
CH2(1,1) = ( ( (rawdata(7,1) * 256) + (rawdata(8,1))) - 512);
%Now we can start gathering data and concatonating the channel matrices
% create plot and capture handle
figure(1)
subplot(2,1,1)
handle = plot(nan); xlim([0 2560]); ylim([-600 600]);
title('Channel 1');
subplot(2,1,2)
handle2 = plot(nan); xlim([0 2560]); ylim([-600 600]);
title('Channel 2');
xlength = 2560; %set initial upper graph limit where 1 second = 256
inputBuffer = zeros(544,1); %(32*17) which is 0.125 seconds of data
buffercounter = 1;
for n = 1:(256*capturetime) %CAPTURE TIME NEEDS A VALUE, SPECIFIED IN FUNCTION DECLARATION
rawdata = fread(hCom, 17, 'uchar');
%BUFFERING MECHANISM TO PERFORM SHORT WINDOW FILTERING & PROCESSING
if mod(n,544) ~= 0
%start stuffing data into the inputbuffer
inputBuffer((((17*buffercounter)-16):(17*buffercounter)),1) = rawdata;
%Matlab is relentless in its attempts to infuriate me...
tempvariable = buffercounter + 1;
buffercounter = tempvariable;
else
%
%perform filtering here
%
buffercounter = 1;
end
CH1 = vertcat(CH1, ( ( (rawdata(5,1) * 256) + (rawdata(6,1))) - 512)); %CH1 matrix will grow with data
CH2 = vertcat(CH2, ( ( (rawdata(7,1) * 256) + (rawdata(8,1))) - 512));
%window = 0.5 - 0.5 * cos(2*pi*(0:32)/32); % Von-Hann Window
%f = abs(fft(window' .* CH1( (length(CH1)-32):length(CH1),1 )));
if mod(n,16) == 0 % Update the plot every 1/16 seconds
if length(CH1) > 2560 %if more than (256*seconds) then
xlength = xlength + 16; %Move the plot on by 1/16 of a second
%Raw Data Plots
subplot(2,1,1)
xlim([(xlength-2560) xlength])% Keep at a constant 2560
subplot(2,1,2)
xlim([(xlength-2560) xlength])
end
set(handle,'YData',CH1);
set(handle2,'YData',CH2);
drawnow % Update plot
end
end
%Perform VEFD
fclose(hCom);
  댓글 수: 4
Nicholas Rawson
Nicholas Rawson 2011년 2월 15일
Post updated. I am entirely happy with how the code runs except for the "buffercounter = 1;" line not executing. I have tested to see if the program enters the else statement and it does, leaving me entirely perplexed as to what the problem with it could be.
Jan
Jan 2011년 2월 15일
There seems to be no reason in the posted code not to perform "buffercounter=1;". The rawdata are not caught if "mod(n,544)==0". There is no need to use "tempvariable". Does "%perform filtering here" hide any relevant code?
I suggest to make a break, drink a cup of coffee, and use the debugger to step through the code line by line.

댓글을 달려면 로그인하십시오.

답변 (1개)

Jan
Jan 2011년 2월 15일
It is just a wild guess: Some sentences of the question seem to be solved by this method:
nByte = 256 * capturetime;
rawdata = fread(hCom, nByte, 'uchar');
rawdata = reshape(rawdata, 32, []);
No counter, no FOR-loop, no pre-allocation, no time-consuming VERTCAT (repeated growing of an array is very expensive!), no buffer. But perhaps: not what you are looking for...
  댓글 수: 3
Nicholas Rawson
Nicholas Rawson 2011년 2월 15일
I suppose an underlying question I have is "is there a way to tell when a matrix has been filled with data?".
Jan
Jan 2011년 2월 15일
@Nicholas: If you want to stop the reading after 32 bytes, simply use:
for i = 1:(256*capturetime)/32, rawdata = fread(hCom, 32, 'uchar'); <your "realtime calculation" here>; end
A way to tell if a matrix is filled?! Simply count the number of inserted elements.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 EEG/MEG/ECoG에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by