使用'fscanf'在MATLAB中从串行线读取数据时解释零

时间:2012-03-14 05:35:59

标签: matlab serial-port arduino scanf null-terminated

我有来自Arduino板的串行线路的数据流。流看起来像这样:

0x43 0x03 0x39 0x00 0x0D 0x0A

前两个字节(0x43和0x03)是单字节整数值。接下来的两个字节(0x39和0x00)是一个16位的小端有符号整数值。最后两个字节(0x10和0x13)应该是终结符序列(“\ r \ n”)。

我正在使用MATLAB读取这些数据。我创建一个串行连接,打开它,并读入数据。不幸的是,我遇到使用0x00作为字节值的问题,因为 fscanf 只是将它视为字符串的空终止符。

以下是一些示例代码:

%Create and open serial connection
serialcon = serial('COM5');
fopen(serialcon);

firstChar = fscanf(serialcon, '%c', 1); %Read 0x43
secondChar = fscanf(serialcon, '%c', 1); %Read 0x03
integerByteChars = fscanf(serialcon, '%c', 2); %Read 0x39 and 0x00
fscanf(serialcon, '%c'); %Read until end-of-line

integerBytes = uint8(integerByteChars); %value should be (in hex): [ 0x39 0x00 ]
integerValue = typecast(integerBytes, 'uint16'); %value should be (in hex): 0x0039

不幸的是,发生的事情是“integerByteChars”不是我想要的2元素数组,而是1元素数组,因为fscanf只考虑0x00是一个空终止字符串值。然而,这让我感到惊讶,因为我使用'%c'而不是'%s'(用于字符串)输入数据。

我需要的是一个将这些字节作为数据读取的函数,即使它是一个零字节而不是丢弃它。我可以使用哪些功能? fscanf可以强制这样做吗?

1 个答案:

答案 0 :(得分:2)

恐惧是一种很好的方式。

您可以使用以下内容读取所有6个字节:

 data = fread(s2,6,'uint8')

然后处理返回的向量。

 firstChar = data(1);
 secondChar = data(2);
 integerValue = data(3) + data(4) * 256;  % Need to check endian calc
 if data(5) ~= 13 || data(6) ~= 10
    error('Not terminated correctly')
 end

顺便说一句,你确定你的CR / LF ASCII值是否正确?