MATLAB串口连接速度太慢

时间:2011-11-30 17:17:38

标签: performance matlab input serial-port

当我打开它时,我有一个探测器以高速率喷出两个数字。我一直在使用HyperTerminal捕获我的数据,这似乎能够跟上设备。

我想通过Matlab完全自动化流程并控制设备,但发现只有不到一半的数据通过Matlab。 Matlab在这方面的速度是否有任何已知问题?

以下是我用来阅读数据的内容:

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%i \ n'格式。也许有一些方法可以读取所有数据并在完成后处理它?<​​/ p>

1 个答案:

答案 0 :(得分:2)

由于您在串口打开调用中传递了'Terminator', 'CR/LF',因此可以替换

if s.BytesAvailable >= 13
        line = fgets(s);
        if length(line) == 13

line = fscanf(s);fscanf将等待终结符,并返回整行(假设线路上没有错误)。您也可以删除else pause部分。这些更改应使循环运行得足够快以跟上串行数据。我猜想s.BytesAvailablepause实际上花费的时间比你预期的要长得多 - 前者是因为它调用操作系统和后者,因为暂停可能比你指定的时间长得多,具体取决于时间片。

进行此更改会引入一个新问题: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');