2

Arduinoボードからシリアルラインを介して入ってくるデータのストリームがあります。ストリームは次のようになります。

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

最初の2バイト(0x43および0x03)は、シングルバイト整数値です。次の2バイト(0x39および0x00)は、単一の16ビットリトルエンディアン符号付き整数値です。最後の2バイト(0x10と0x13)は、ターミネータシーケンス( "\ r \ n")であると想定されています。

このデータを読み込むためにMATLABを使用しています。シリアル接続を作成して開き、データを読み込みます。残念ながら、fscanfは0x00を文字列のヌルターミネータと見なすだけなので、バイト値として0x00を使用する際に問題が発生します。

サンプルコードは次のとおりです。

%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要素の配列ではなく、fscanf0x00をnullで終了する文字列値と見なすため、1要素の配列になります。ただし、文字列に使用される「%s」ではなく「%c」を使用してデータを入力しているため、これには驚かされます。

私が必要としているのは、ゼロバイトであってもこれらのバイトをデータとして読み取り、破棄しない関数です。それを行うために私が利用できる機能は何ですか?fscanfに強制的にそうさせることはできますか?

4

1 に答える 1

2

freadはこれを行うための良い方法です。

次のコマンドで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値は正しいですか?

于 2012-03-14T07:34:35.707 に答える