arduino fft and matlab ifft - matlab

We currently work with Arduino.
I am using the fft library of "open music labs FFT library"
My question is two things.
Arduino code issues
Inverse fft in Matlab (With the FFT results from Arduino)
the following code using Arduino FFT library for FFT (fast Fourier transform)
/*
fft_adc_serial.pde
guest openmusiclabs.com 7.7.14
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.
*/
//#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft
void setup() {
Serial.begin(115200); // use the serial port
TIMSK0 = 0; // turn off timer0 for lower jitter
ADCSRA = 0xe5; // set the adc to free running mode
ADMUX = 0x40; // use adc0
DIDR0 = 0x01; // turn off the digital input for adc0
}
void loop() {
while(1) { // reduces jitter
cli(); // UDRE interrupt slows this way down on arduino1.0
for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
while(!(ADCSRA & 0x10)); // wait for adc to be ready
ADCSRA = 0xf5; // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = (j << 8) | m; // form into an int
k -= 0x0200; // form into a signed int
k <<= 6; // form into a 16b signed int
fft_input[i] = k; // put real data into even bins
fft_input[i+1] = 0; // set odd bins to 0
}
fft_window(); // window the data for better frequency response
for (int i = 0 ; i < 512 ; i += 2) {
fft_input[i] = (fft_input[i] >> 8);
fft_input[i+1] = -(fft_input[i+1] >> 8);
}
fft_reorder(); // reorder the data before doing the fft
fft_run(); // process the data in the fft
//fft_mag_log(); // take the output of the fft
sei();
Serial.print("start");
for (byte i = 0 ; i < FFT_N ; i+=2) {
if (! ((i>=20 && i<=40) || (i>=FFT_N-40 && i<=FFT_N-20)))
{
fft_input[i] = 0;
fft_input[i+1] = 0;
}
Serial.println(fft_input[i]); // send out the data
}
}
}
matlab serial communication code
clear all
clc
arduino=serial('COM22','BaudRate',115200 );
fopen(arduino);
data = fread(arduino, 256);
ifft(data , 'symmetric');
fclose(arduino);
delete(instrfindall);
With this code was an experiment. But it did not recover.
Perform fft_run () on the Arduino, and I'd like the inverse fft in matlab.
There are a lot of problems.
I would like to ask what to in some way.
Update
I've made changes based on SleuthEye's answer. But there is a problem.
-arduino code-
/*
fft_adc_serial.pde
guest openmusiclabs.com 7.7.14
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.
*/
//#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft
#include <FFT.h> // include the library
void setup() {
Serial.begin(115200); // use the serial port
TIMSK0 = 0; // turn off timer0 for lower jitter
ADCSRA = 0xe5; // set the adc to free running mode
ADMUX = 0x40; // use adc0
DIDR0 = 0x01; // turn off the digital input for adc0
}
void loop() {
while(1) { // reduces jitter
cli(); // UDRE interrupt slows this way down on arduino1.0
for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
while(!(ADCSRA & 0x10)); // wait for adc to be ready
ADCSRA = 0xf5; // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = (j << 8) | m; // form into an int
k -= 0x0200; // form into a signed int
k <<= 6; // form into a 16b signed int
fft_input[i] = k; // put real data into even bins
fft_input[i+1] = 0; // set odd bins to 0
}
fft_window(); // window the data for better frequency response
for (int i = 0 ; i < 512 ; i += 2) {
fft_input[i] = (fft_input[i] >> 8);
fft_input[i+1] = -(fft_input[i+1] >> 8);
}
fft_reorder(); // reorder the data before doing the fft
fft_run(); // process the data in the fft
// fft_mag_log(); // take the output of the fft
sei();
Serial.println("start");
for (byte i = 0 ; i < FFT_N ; i+=2) {
Serial.write(fft_input[i]); // send out the real part
Serial.write(fft_input[i+1]); // send out the imaginary part
}
}
}
-matlab side-
clear all
clc
arduino=serial('COM22','BaudRate',115200 );
fopen(arduino);
header = fread(arduino, 5); % skip "start" header
data = fread(arduino, 512); % read actual data
% now rearrange the data
rearranged = data(1:2:end) + 1i * data(2:2:end);
recoverd = ifft(rearranged, 'symmetric');
fclose(arduino);
delete(instrfindall);
My problem is: it deletes the filter part.
Arduino sends the data to MATLAB. 512 data from Arduino. (FFT_N- real 256 and imaginary 256.)
Not an exact recovery. Performing ifft in matlab, not the original data.
There is a problem with the data form.
This form of data seems to be a problem in communication.(arduino to matlab)
data = fread(arduino, 512); % read actual data.
But my guess. The exact reason was not found.
UPDATE
Thank you for your response.
for (int i = 0 ; i < 512 ; i += 2) {
fft_input[i] = (fft_input[i] >> 8);
fft_input[i+1] = -(fft_input[i+1] >> 8);
}
This code has been found that it is not necessary.
for (byte i = 0 ; i < FFT_N ; i+=2) {
Serial.write(fft_input[i]); // send out the real part
Serial.write(fft_input[i+1]); // send out the imaginary part
}
My difficulty is,
When you do this code, the part of OUTPUT is 256 REAL and 256 IMAGINARY.
but,
header = fread(arduino, 5); % skip "start" header
data = fread(arduino, 1024); % read actual data sent in binary form
% now rearrange the data
rearranged = (data(1:4:end) + 256*data(2:4:end)) + 1i *(data(3:4:end) + 256*data(4:4:end));
recovered = ifft(rearranged, 'symmetric');
"SIZE * PRECISION must be less than or equal to InputBufferSize.."
Problem of the buffer size...
So try again.
I had to modify the code as you said.
/*
fft_adc_serial.pde
guest openmusiclabs.com 7.7.14
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.
*/
//#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft
#include <FFT.h> // include the library
void setup() {
Serial.begin(115200); // use the serial port
TIMSK0 = 0; // turn off timer0 for lower jitter
ADCSRA = 0xe5; // set the adc to free running mode
ADMUX = 0x40; // use adc0
DIDR0 = 0x01; // turn off the digital input for adc0
}
void loop() {
while(1) { // reduces jitter
cli(); // UDRE interrupt slows this way down on arduino1.0
for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
while(!(ADCSRA & 0x10)); // wait for adc to be ready
ADCSRA = 0xf5; // restart adc
byte m = ADCL; // fetch adc data
byte j = ADCH;
int k = (j << 8) | m; // form into an int
k -= 0x0200; // form into a signed int
k <<= 6; // form into a 16b signed int
fft_input[i] = k; // put real data into even bins
fft_input[i+1] = 0; // set odd bins to 0
}
fft_window(); // window the data for better frequency respons
fft_reorder(); // reorder the data before doing the fft
fft_run(); // process the data in the fft
// fft_mag_log(); // take the output of the fft
sei();
Serial.println("start"); // header send
for (byte i = 0 ; i < FFT_N ; i+=2) {
Serial.write(fft_input[i]); // send out the real part
Serial.write(fft_input[i+1]); // send out the imaginary part
}
}
}
Your answer makes me busy. Makes active. good answer.

I assume that the additional spectrum transformations are intentional and not what you find problematic. For example you shouldn't be expecting to get back the spectrum values in bins 20-40 inclusive since you are explicitly zeroing them out. Also, the code
for (int i = 0 ; i < 512 ; i += 2) {
fft_input[i] = (fft_input[i] >> 8);
fft_input[i+1] = -(fft_input[i+1] >> 8);
}
is a trick to obtain the inverse transform using Arduino's forward transform. Since you start with time samples, I assume you want only the forward transform (and so do not need that part of the code).
Now, comparing with Arduino's FFT example, there are a few differences which may hint at what's going on. The first notable difference comes with what the example is sending which is the lower half of the spectrum magnitude (128 values), and is not sufficient to reconstruct the original signal. In your case you correctly commented out the fft_mag_log which should allow you to send spectrum's complex values. However as you loop over the fft bins, you are only sending every second value (thus missing all the imaginary parts).
The other thing to notice is the packaging of the data. More specifically you are sending a data header (the "start" string) which you will have to read on Matlab's receiving end otherwise it will just get mixed in your actual data.
Binary transfer
You are using Serial.println which sends your number in ASCII form, whereas you read them back with Matlab's fread which reads them assuming they are in binary form. For consitency you should send your data in binary form with Serial.write:
for (byte i = 0 ; i < FFT_N ; i+=2) {
Serial.write(fft_input[i]); // send out the real part
Serial.write(fft_input[i+1]); // send out the imaginary part
}
Then, since you are sending 256 complex values as interleaved real/imaginary parts (for a total of 512 values), you would need to read those 512 values (typically 2 bytes each, in little endian order) and rearrange the data on Matlab's side:
header = fread(arduino, 5); % skip "start" header
data = fread(arduino, 1024); % read actual data sent in binary form
% now rearrange the data
rearranged = (data(1:4:end) + 256*data(2:4:end)) + 1i *(data(3:4:end) + 256*data(4:4:end));
recovered = ifft(rearranged, 'symmetric');
ASCII transfer
Alternatively you can send the data with Serial.println (i.e. in plain ASCII):
for (byte i = 0 ; i < FFT_N ; i+=2) {
Serial.println(fft_input[i]); // send out the real part
Serial.println(fft_input[i+1]); // send out the imaginary part
}
and read it back in ASCII form in matlab with fscanf:
fscanf(arduino, "start"); % skip "start" header
data = fscanf(arduino, "%d"); % read actual data sent in plain ASCII form
% now rearrange the data
rearranged = data(1:2:end) + 1i * data(2:2:end);
recovered = ifft(rearranged, 'symmetric');

Related

Matlab: fastest method of reading parts/sequences of a large binary file

I want to read parts from a large (ca. 11 GB) binary file. The currently working solution is to load the entire file ( raw_data ) with fread(), then crop out pieces of interest ( data ).
Question: Is there a faster method of reading small (1-2% of total file, partially sequential reads) parts of a file, given something like a binary mask (i.e. a logical index of specific bytes of interst) in Matlab? Specifics below.
Notes for my specific case:
data of interest (26+e6 bytes, or ca. 24 MB) is roughly 2% of raw_data (1.2e+10 bytes or ca. 11 GB)
each 600.000 bytes contain ca 6.500 byte reads, which can be broken down to roughly 1.200 read-skip cycles (such as 'read 10 bytes, skip 5000 bytes').
the read instructions of the total file can be broken down in ca 20.000 similar but (not exactly identical) read-skip cycles (i.e. ca. 20.000x1.200 read-skip cycles)
The file is read from a GPFS (parallel file system)
Excessive RAM, newest Matlab ver and all toolboxes are available for the task
My initial idea of fread-fseek cycle proved to be extrodinarily much slower (see psuedocode below) than reading the whole file. Profiling revealed fread() is slowest (being called over a million times probably obvious to the experts here).
Alternatives I considered: memmapfile() [ ref ] has no feasible read multiple small parts as far as I could find. The MappedTensor library might be the next thing I'd look into. Related but didn't help, just to link to article: 1, 2.
%open file
fi=fopen('data.bin');
%example read-skip data
f_reads = [20 10 6 20 40]; %read this number of bytes
f_skips = [900 6000 40 300 600]; %skip these bytes after each read instruction
data = []; %save the result here
fseek(fi,90000,'bof'); %skip initial bytes until first read
%read the file
for ind=1:nbr_read_skip_cylces-1
tmp_data = fread(fi,f_reads(ind));
data = [data; tmp_data]; %add newly read bytes to data variable
fseek(fi,f_skips(ind),'cof'); %skip to next read position
end
FYI: To get an overview and for transparency, I've compiled some plots (below) of the first ca 6.500 read locations (of my actual data) that, after collapsing into fread-fseek pairs can, can be summarized in 1.200 fread-fseek pairs.
I would do two things to speed up your code:
preallocate the data array.
write a C MEX-file to call fread and fseek.
This is a quick test I did to compare using fread and fseek from MATLAB or C:
%% Create large binary file
data = 1:10000000; % 80 MB
fi = fopen('data.bin', 'wb');
fwrite(fi, data, 'double');
fclose(fi);
n_read = 1;
n_skip = 99;
%% Read using MATLAB
tic
fi = fopen('data.bin', 'rb');
fseek(fi, 0, 'eof');
sz = ftell(fi);
sz = floor(sz / (n_read + n_skip));
data = zeros(1, sz);
fseek(fi, 0, 'bof');
for ind = 1:sz
data(ind) = fread(fi, n_read, 'int8');
fseek(fi, n_skip, 'cof');
end
toc
%% Read using C MEX-file
mex fread_test_mex.c
tic
data = fread_test_mex('data.bin', n_read, n_skip);
toc
And this is fread_test_mex.c:
#include <stdio.h>
#include <mex.h>
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
// No testing of inputs...
// inputs = 'data.bin', 1, 99
char* fname = mxArrayToString(prhs[0]);
int n_read = mxGetScalar(prhs[1]);
int n_skip = mxGetScalar(prhs[2]);
FILE* fi = fopen(fname, "rb");
fseek(fi, 0L, SEEK_END);
int sz = ftell(fi);
sz /= n_read + n_skip;
plhs[0] = mxCreateNumericMatrix(1, sz, mxDOUBLE_CLASS, mxREAL);
double* data = mxGetPr(plhs[0]);
fseek(fi, 0L, SEEK_SET);
char buffer[1];
for(int ind = 1; ind < sz; ++ind) {
fread(buffer, 1, n_read, fi);
data[ind] = buffer[0];
fseek(fi, n_skip, SEEK_CUR);
}
fclose(fi);
}
I see this:
Elapsed time is 6.785304 seconds.
Building with 'Xcode with Clang'.
MEX completed successfully.
Elapsed time is 1.376540 seconds.
That is, reading the data is 5x as fast with a C MEX-file. And that time includes loading the MEX-file into memory. A second run is a bit faster (1.14 s) because the MEX-file is already loaded.
In the MATLAB code, if I initialize data = []; and then extend the matrix every time I read like OP does:
tmp = fread(fi, n_read, 'int8');
data = [data, tmp];
then the execution time for that loop was 159 s, with 92.0% of the time spent in the data = [data, tmp] line. Preallocating really is important!

Matlab - Serial timeout but good data received with multibytes datatypes sending

I am currently reading from an STM32 through UART using Matlab.
With the following program, I have been able to read single byte data (uint8, int8, char), even if several bytes come right after each others.
The problem comes when I try with multibytes datatypes (float32, uint32, ...). The console print me the received data, which is the one sent by the STM32, but the soft freezes and after the 10seconds default value timeout, I get this warning:
Warning: The specified amount of data was not returned within the Timeout period. 'serial' unable to read all requested data. For more information on possible reasons, see Serial Read Warnings.
The fact that I receive exactly the sent numbers (and that there is the good amount of bits sent when I check with an oscilloscope) tends to tell me that the problem is not from my soft in the STM32, but in the matlab interpretation, which seems to wait for something else.
Thank you all in advance for your ideas
clear;
clc;
% ------------------------ TWEAKING PARAMETERS -------------------------- %
port = 'COM4'; %Serial port
% seriallist : This command list all the COM port available
baudrate = 115200; % Frequency
dataType = 'uint32'; %Data to be received and transmitted
readDelay = 0.001; %The time between 2 buffer emptying in seconds
maxDataStored = 1000; %The number of data to be stored in final file
serialInBufferSize = 1024; %The input buffer size
%Make sure that sending frequency < serialInBufferSize / readDelay
storeCSV = 0; %Enable storage in CSV file
% ----------------------------------------------------------------------- %
totalData = 0;
maxDataReached = 0;
timeStamps(maxDataStored) = datetime;
timeElapsed = zeros(1, maxDataStored);
receivedData = zeros(1, maxDataStored, dataType);
%Creates main control panel to end serial streaming
controlPanel = figure('WindowStyle', 'docked', ...
'MenuBar', 'none');
stop = uicontrol('Style', 'PushButton', ...
'String', 'End communication', ...
'Position', [0, 0, 200, 40], ...
'Callback', 'delete(gcbf)');
drawnow;
% Initializes serial port
disp(['Initialising serial port ' port]);
s = instrfind('port',port);
if not(isempty(s)) % Destroy existing serial port
disp(['Killing existant communication on ' port]);
fclose(s);
delete(s);
clear s
end
s = serial(port,'BaudRate',baudrate, ...
'InputBufferSize', serialInBufferSize, ...
'Parity', 'even');
fopen(s);
startTime = datetime('now');
disp(['Port ' port ' initialised successfully at ' num2str(baudrate) ...
' bauds']);
disp('Beginning of communication');
disp(' ');
% Main script to stream data
while (ishandle(stop) && maxDataReached == 0)
%The < 4 condition was an unsuccessfull test, it used to be == 0
while (s.BytesAvailable < 4 && ishandle(stop))
pause (readDelay);
end
if(ishandle(stop))
in = fread(s, s.BytesAvailable, dataType);
for i = 1 : length(in)
if (totalData + 1 > maxDataStored)
maxDataReached = 1;
disp(' ');
disp('Maximum amount of received data reached');
break
end
dt = seconds((datetime('now') - startTime));
%Storage
timeStamps(totalData + 1) = datetime('now');
timeElapsed(totalData + 1) = dt;
receivedData(totalData + 1) = in(i);
%Console printing
disp([datestr(now,'HH:MM:SS.FFF'), ' || ', ...
num2str(dt, '%.3f'), ...
's since startup || received : ', ...
num2str(in(i))]);
totalData = totalData + 1;
end
pause(0.01);
end
end
% Closes serial port
disp(' ');
disp(['Ending communication on port ' port ' ...']);
fclose(s);
delete(s);
clear s
disp('Communication ended properly (I hope so...)');
%Script termination
close(gcf);
disp(' ');
disp('Script ended');
You are trying to read 4 times data bytes than available.
in = fread(s, s.BytesAvailable, 'uint32');, reads s.BytesAvailable*4 bytes, because size of uint32 elements is 4 bytes.
According to fread (serial) documentation:
A = fread(obj,size,'precision') reads binary data with precision specified by precision.
precision controls the number of bits read for each value and the interpretation of those bits as integer, floating-point, or character values.
Documentation is not so clear, but the size argument specifies the number of elements (e.g. number of uint32 elements), and not the number of bytes.
You can divide the size by 4:
dataType = 'uint32'; %Set dataType to 'uint32' or 'float32`.
in = fread(s, s.BytesAvailable/4, dataType);
A cleaner solution is reading uint8 elements, and using typecast:
in = fread(s, s.BytesAvailable/4, '*uint8'); %The '*uint8' keeps data in uint8 class (not double).
in = typecast(in, dataType); %Convert to 'uint32' or 'single', according to dataType.
in = double(in); %Convert to double (for compatibility).

Efficient import of semi structured text

I have multiple text files saved from a Tekscan pressure mapping system. I'm am trying to find the most efficient method for importing the multiple comma delimited matrices into one 3-d matrix of type uint8. I have developed a solution, which makes repeated calls to the MATLAB function dlmread. Unfortunately, it takes roughly 1.5 min to import the data. I have included the code below.
This code makes calls to two other functions I wrote, metaextract and framecount which I have not included as they aren't truly relevant to answering the question at hand.
Here are two links to samples of the files I am using.
The first is a shorter file with 90 samples
The second is a longer file with 3458 samples
Any help would be appreciated
function pressureData = tekscanimport
% Import TekScan data from .asf file to 3d matrix of type double.
[id,path] = uigetfile('*.asf'); %User input for .asf file
if path == 0 %uigetfile returns zero on cancel
error('You must select a file to continue')
end
path = strcat(path,id); %Concatenate path and id to full path
% function calls
pressureData.metaData = metaextract(path);
nLines = linecount(path); %Find number of lines in file
nFrames = framecount(path,nLines);%Find number of frames
rowStart = 25; %Default starting row to read from tekscan .asf file
rowEnd = rowStart + 41; %Frames are 42 rows long
colStart = 0;%Default starting col to read from tekscan .asf file
colEnd = 47;%Frames are 48 rows long
pressureData.frames = zeros([42,48,nFrames],'uint8');%Preallocate for speed
f = waitbar(0,'1','Name','loading Data...',...
'CreateCancelBtn','setappdata(gcbf,''canceling'',1)');
setappdata(f,'canceling',0);
for i = 1:nFrames %Loop through file skipping frame metadata
if getappdata(f,'canceling')
break
end
waitbar(i/nFrames,f,sprintf('Loaded %.2f%%', i/nFrames*100));
%Make repeated calls to dlmread
pressureData.frames(:,:,i) = dlmread(path,',',[rowStart,colStart,rowEnd,colEnd]);
rowStart = rowStart + 44;
rowEnd = rowStart + 41;
end
delete(f)
end
I gave it a try. This code opens your big file in 3.6 seconds on my PC. The trick is to use sscanf instead of the str2double and str2number functions.
clear all;tic
fid = fopen('tekscanlarge.txt','rt');
%read the header, stop at frame
header='';
l = fgetl(fid);
while length(l)>5&&~strcmp(l(1:5),'Frame')
header=[header,l,sprintf('\n')];
l = fgetl(fid);
if length(l)<5,l(end+1:5)=' ';end
end
%all data at once
dat = fread(fid,inf,'*char');
fclose(fid);
%allocate space
res = zeros([48,42,3458],'uint8');
%get all line endings
LE = [0,regexp(dat','\n')];
i=1;
for ct = 2:length(LE)-1 %go line by line
L = dat(LE(ct-1)+1:LE(ct)-1);
if isempty(L),continue;end
if all(L(1:5)==['Frame']')
fr = sscanf(L(7:end),'%u');
i=1;
continue;
end
% sscan can only handle row-char with space seperation.
res(:,i,fr) = uint8(sscanf(strrep(L',',',' '),'%u'));
i=i+1;
end
toc
Does anyone knows of a faster way to convert than sscanf? Because it spends the majority of time on this function (2.17 seconds). For a dataset of 13.1MB I find it very slow compared to the speed of the memory.
Found a way to do it in 0.2 seconds that might be usefull for others as well.
This mex-file scans through a list of char values for numbers and reports them back. Save it as mexscan.c and run mex mexscan.c.
#include "mex.h"
/* The computational routine */
void calc(unsigned char *in, unsigned char *out, long Sout, long Sin)
{
long ct = 0;
int newnumber=0;
for (int i=0;i<Sin;i+=2){
if (in[i]>=48 && in[i]<=57) { //it is a number
out[ct]=out[ct]*10+in[i]-48;
newnumber=1;
} else { //it is not a number
if (newnumber==1){
ct++;
if (ct>Sout){return;}
}
newnumber=0;
}
}
}
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
unsigned char *in; /* input vector */
long Sout; /* input size of output vector */
long Sin; /* size of input vector */
unsigned char *out; /* output vector*/
/* check for proper number of arguments */
if(nrhs!=2) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","two input required.");
}
if(nlhs!=1) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs","One output required.");
}
/* make sure the first input argument is type char */
if(!mxIsClass(prhs[0], "char")) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble","Input matrix must be type char.");
}
/* make sure the second input argument is type uint32 */
if(!mxIsClass(prhs[0], "char")) {
mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble","Input matrix must be type char.");
}
/* get dimensions of the input matrix */
Sin = mxGetM(prhs[0])*2;
/* create a pointer to the real data in the input matrix */
in = (unsigned char *) mxGetPr(prhs[0]);
Sout = mxGetScalar(prhs[1]);
/* create the output matrix */
plhs[0] = mxCreateNumericMatrix(1,Sout,mxUINT8_CLASS,0);
/* get a pointer to the real data in the output matrix */
out = (unsigned char *) mxGetPr(plhs[0]);
/* call the computational routine */
calc(in,out,Sout,Sin);
}
Now this script runs in 0.2 seconds and returns the same result as the previous script.
clear all;tic
fid = fopen('tekscanlarge.txt','rt');
%read the header, stop at frame
header='';
l = fgetl(fid);
while length(l)>5&&~strcmp(l(1:5),'Frame')
header=[header,l,sprintf('\n')];
l = fgetl(fid);
if length(l)<5,l(end+1:5)=' ';end
end
%all data at once
dat = fread(fid,inf,'*char');
fclose(fid);
S=[48,42,3458];
d = mexscan(dat,uint32(prod(S)+3458));
d(1:prod(S(1:2))+1:end)=[];%remove frame numbers
d = reshape(d,S);
toc

Matlab: Can't handle data

I am writing a program in Matlab that reads in a Matrix coming from a sensor (microcontroller is an Arduino Leonardo). You can choose how fast the matrices are being recorded (e.g. 60 frames per min would be one matrix every second).
All that works great, but I had to create a default file that records all the matrices that would not be recorded (let’s say it’s fast enough to record 8 matrices per sec and you only want one per sec, then the default file would record the other seven). Otherwise I’d get kicked out of here:
%Get data
%Data is read as string (CSV)
data = str2double(strsplit(fgetl(serialPort), ','));
if and(get(hObject,'Value') == 1, correctPort == 1)
%try for right ports
try
%Reshape data (1D -> 2D array) and display in matrix
k = 1;
for i = 1:nrow
for j = 1:ncol
% Reading in tag names
tagNames{k} = ['tag_matrix_' num2str(k)];
% Creating matrix
data2d(row_index(i), col_index(j)) = data(k);
% Display in matrix
set(handles.(tagNames{k}),'String',data2d(i,j));
set(handles.(tagNames{k}),'visible','on');
k = k + 1;
end
end
catch
set(handles.tag_txt3,'String','This is not the correct port. Please look up the correct port in your Device Manager. Set up the right port and start again');
set(handles.tag_OnOff,'Value',0);
set(handles.tag_log,'Value',0);
set(handles.tag_log,'Enable','off')
correctPort = 0;
end
end
It goes through the loop a couple of time (a different number of times every time) but eventually I’ll get send to “catch”. This happens if i started recording or not. Doesn't matter.
If I have it display the matrices in the Command Window (data2d(row_index(i), col_index(j)) = data(k) without ;) it works.
Here is how I record the data:
% Open for writing
% Preparation
if and(startLog == 1, correctPort == 1)
set(handles.tag_txt3,'String','Program running and recording data');
end
% Set interval = recTime after logging (don't worry about that)
if and(startLog == 1, counter == 0)
interval = recTime;
counter = 1;
end
% Making sure you have to restart after stop logging
if and(startLog == 0, counter == 1)
set(handles.tag_OnOff,'Value',0)
end
% Record data when the time has come
if and(startLog == 1,time > interval)
fprintf(fid, '#');
fprintf(fid, '%u', matrixNumber);
fprintf(fid, '\n');
for i=1:size(data2d,1)
fprintf(fid, '%g\t', data2d(i,:));
fprintf(fid,'\n');
end
interval = recTime + interval;
matrixNumber = matrixNumber + 1;
%Making sure you have choosen a unit and send out error
elseif and(startLog == 1,recTime == 0)
set(handles.tag_txt3,'String','Choose a unit and start again');
set(handles.tag_OnOff,'Value',0)
set(handles.tag_log,'Value',0)
counter = 0;
else
%This is where the default file would be recording all the other matrices
end
Hope someone can help me. I didn't wanna put in the entire code because it's already ten pages. Please let me know if you have further questions.
Thank you so much in advance
Mike

How to read from the buffer last valuse at spisific time, using fieldtrip toolbox

I want to read from fieldtrip toolbox buffer in specific time, I perform an experiment that causes brain stimulation, so i want to read the eeg data reaction of the
experiment.
I was able to read continuous data, here is my code:
run=1;
filename = 'buffer://localhost:1972'; %set buffer
% read the header for the first time to determine number of channels and sampling rate
hdr = ft_read_header(filename, 'cache', true); %header of buffer
count = 0;
prevSample = 0;
blocksize = hdr.Fs; %size if readig on blick
chanindx = 1:hdr.nChans;
while true
hdr = ft_read_header(filename, 'cache', true);
newsamples = (hdr.nSamples*hdr.nTrials-prevSample);
if newsamples>=blocksize
begsample = prevSample+1;
endsample = prevSample+blocksize ;
prevSample = endsample;
count = count + 1;
dat = ft_read_data(filename, 'header', hdr, 'begsample', begsample, 'endsample', endsample, 'chanindx', chanindx);
time = (begsample:endsample)/hdr.Fs;
vals= (dat([15 1 2 3],1:end)).';%get rows 1,2,3 and 15=timestamp, transpose it
plot(time,vals);
run=run+1;
if(run==100)
break;
end
end % if new samples available
end % while true