从udp()对象编组任意长度的二进制数据

时间:2017-07-26 22:46:04

标签: matlab networking

我正在使用Matlab udp()对象从仪器中读取二进制数据。

我很惊讶显然缺乏对读取任意长度数据类型的支持。如何读取24位整数?还是24位浮点数?这些在仪器中并不奇怪,我在文档中只找到了8/16/32/64数据类型。

1 个答案:

答案 0 :(得分:2)

你看过help fread了吗?文档显示它支持使用bitN一次最多读取64位,其中N是1到64之间的值。

fid = udp(<your parameters here>);  % use fopen to open the stream.
...
A = fread(fid,1,'bit24=>int32');  % stream 24 bits to a 32 bit integer.
B = fread(fid,1,'ubit24=>uint32');  % stream 24 bits to a 32 bit unsigned integer.

由于浮点规格不同,所以这可能适用于您的情况,也可能不适用:

C = fread(fid,1,'bit24=>float32');  % transcode 24bits to 32 bit float (MATLAB spec)

<强>更新

看到udp/fread实现不支持此转换,您可以尝试一些非常漂亮的解决方法。

  1. 以3的倍数读入uchar数据,然后将其直接乘以字节偏移量。例如:

    % First determine number of bytes on the stream and make sure you
    % have at 3 or more bytes to read so you can calculate thirdOfBytesExpected.  
    
    [anMx3result, packetCount] = fread(fid,[thirdOfBytesExpected,3]);
    unsigned20bitInt = anMx3result*(2.^(0:8:16))';
    

    确切地说,unsigned20bitInt实际上存储为MATLAB double。因此,如果您需要在其他地方编写它,则需要将其恢复到它来自的各个uchar类型。

  2. 不那么漂亮的选择是将数据流回到二进制文件格式作为临时步骤的开销,以便您可以使用上面提到的基本fread方法。不是一个理想的解决方案,但如果你只需要某些东西就可能值得考虑。

    % your original code for opening the udp handle
    
     ....
    
    tmpFid = fopen('tmp.bin','rw');
    [ucharVec, bytesRead] = fread(udpFid,bytesExpected,'uchar=>uchar');
    bytesWritten = fwrite(tmpFid,ucharVec,'uchar');
    
    % Do some quality control on bytes read vs written ...
    
    fseek(tmpFid,-bytesWritten,'cof');  
    % in theory you should be able to just go to the beginning 
    % of the file each time like this fseek(tmpFid, 0, 'bof');
    % provided you also reset to the beginning prior writing or after reading
    
    % Read in the data as described originally
    num24ByteIntsToRead = bytesWritten/3;
    A = fread(tmpFid,num24BytsIntsToRead,'bit24=>int32');