I've got a detector that spits out two numbers at a high rate when I turn it on. I've been capturing my data using HyperTerminal, which seems to be able to keep up with the device.
I wanted to automate the process and control the device entirely through Matlab, but discovered that less than half of the data gets through to Matlab. Are there any known issues with Matlab's speed in this area?
Here's what I'm using to read in data:
s = serial('COM1', 'BaudRate', 115200, 'DataBits', 8, 'Terminator','CR/LF', 'InputBufferSize', 1024);
T1 = 1; % Initial T1, T2 values
T2 = 10000;
timer = 300;
% Inputs to serial device: T1, T2, runtime (seconds)
fprintf(s, sprintf('%d %d %d\r', T1, T2, timer));
tdata = zeros(1e5,2,'uint16');
data = fopen(sprintf('%s.txt',date_and_trial),'w');
tic;
while toc <= timer
% Read data into an array, and write to file.
if s.BytesAvailable >= 13
line = fgets(s);
if length(line) == 13
a = sscanf(line, '%u %u');
if length(a) == 2
tdata(i,1) = a(1);
tdata(i,2) = a(2);
fprintf(data, sprintf('%d %d\r', tdata(i,1), tdata(i,2)));
i++;
end
end
else
pause(0.01);
end
end
disp(toc);
fclose(s);
fclose(data);
fprintf('Finished!\r');
I've been thinking that the conditionals might be slowing it down, but they also seem to be necessary to keep things in the '%i %i\n' format that I need. Maybe there's some way to read in all the data and process it after completion?
Since you pass
'Terminator', 'CR/LF'
in the serial port open call, you can replacewith
line = fscanf(s);
.fscanf
will wait for the terminator, and return a whole line (assuming there aren't errors on the wire). You can also remove theelse pause
part. These changes should make the loop run fast enough to keep up with the serial data. I would guess thats.BytesAvailable
andpause
actually take much more time than you'd expect - the former because it calls out to the OS and the latter because the pause could go much longer than you specify depending on timeslicing.Making this change introduces a new problem though:
fscanf
will block waiting for the terminator, meaning if the device stops sending before yourtoc >= timer
condition becomes true, the program will hang. So you should make sure to set a sensible timeout in theserial
call.You can make two minor speedups in the body of the loop:
tdata(i,:) = a';
will fill the row in one shot, andfprintf(data, '%s\r', line);
will skipprintf
. So putting it all together: