问题
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?
回答1:
Since you pass 'Terminator', 'CR/LF' in the serial port open call, you can replace
if s.BytesAvailable >= 13
line = fgets(s);
if length(line) == 13
with 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 the else pause part. These changes should make the loop run fast enough to keep up with the serial data. I would guess that s.BytesAvailable and pause actually take much more time than you'd expect - the former because it calls out to the OS and the latter because
来源:https://stackoverflow.com/questions/8330121/matlab-serial-port-connection-is-too-slow