Create a buffer matrix in order to perform real-time operations on incoming data
2 views (last 30 days)
Show older comments
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 Comments
Jan
on 15 Feb 2011
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.
Answers (1)
Jan
on 15 Feb 2011
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 Comments
Jan
on 15 Feb 2011
@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.
See Also
Categories
Find more on EEG/MEG/ECoG in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!