Поскольку вы передаете 'Terminator', 'CR/LF'
в открытом вызове последовательного порта, вы можете заменить
if s.BytesAvailable >= 13
line = fgets(s);
if length(line) == 13
на line = fscanf(s);
.fscanf
будет ожидать терминатора и вернет целую строку (при условии, что в проводе нет ошибок).Вы также можете удалить часть else pause
.Эти изменения должны сделать цикл достаточно быстрым, чтобы не отставать от последовательных данных.Я бы предположил, что s.BytesAvailable
и pause
на самом деле занимают гораздо больше времени, чем вы ожидаете - первое, потому что оно вызывает ОС, а второе, потому что пауза может идти намного дольше, чем вы указываете, в зависимости от временного среза.*
При внесении этого изменения возникает новая проблема: fscanf
заблокирует ожидание терминатора, то есть, если устройство прекратит отправку до того, как ваше условие toc >= timer
станет истинным, программа зависнет.Поэтому вы должны убедиться, что в вызове serial
установлено разумное время ожидания.
Вы можете сделать два небольших ускорения в теле цикла: tdata(i,:) = a';
заполнит строку за один выстрел, а fprintf(data, '%s\r', line);
пропустит printf
.Итак, все вместе:
s = serial('COM1', 'BaudRate', 115200, 'DataBits', 8, 'Terminator','CR/LF', 'InputBufferSize', 1024, 'Timeout', 3);
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),'wt');
tic;
while toc <= timer
% Read data into an array, and write to file.
line = fscanf(s); %# waits for CR/LF terminator
a = sscanf(line, '%u %u');
if length(a) == 2
tdata(i,:) = a'; %# ' assumes sscanf returned a column vector
fprintf(data, '%s\r', line);
i++;
end
end
disp(toc);
fclose(data);
fclose(s);
fprintf('Finished!\r');