2016-05-06 31 views
0

SASが、11ビットのデータパケットでポーリングすることが記載されているSASプロトコルを実装しています。この場合、1つのスタートビット、8データビット、9ウェイクアップビット、ストップビット。また、SASがメッセージをスヌーズした後、他のバイトメッセージウェイクアップビットがクリアされた後に、メッセージの最初のバイトのウェイクアップビットを設定することも記載されています。 また、ウェイクアップビットとしてパリ​​ティビットを使用する必要があります。cでシリアルポートからフルパケットデータを読み取る方法

私はcomportからデータを受け取ることに問題があります。 私はデータを取得することとしている。

01 73 1D 00 09 03 00 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 B3 74 A4 02 0E 76 

が、私は

73 1D 00 09 03 00 00 01 02 03 04 05 06 

を取得しています、ここで最初のバイトが01であることは06

後に受信したデータだけでなく、データに来ていませんシリアルポートオブジェクトを作成するためのコードです。

SerialPort _serialPort = new SerialPort("COM1", 19200, Parity.None, 8, StopBits.One); 

私がComportに書いているとき、私はパリティをMARKに設定しました。以下のような:

byte[] f = Response.ToArray(); 
    _serialPort.Parity = Parity.Mark; 
    _serialPort.Write(f, 0, f.Length); 

と私はあなたのプロトコルはパリティビットを乱用しているように見えるので、あなたがデータの受信を開始する前に、あなたはSerialPort.ParityReplaceゼロに設定することで開始する必要がありますコンポート

private void port_DataReceived_1(object sender, SerialDataReceivedEventArgs e) 
{ 
      SASobj._serialPort.ParityReplace = 0; 

      SASobj._serialPort.Parity = Parity.Space; 

      byte[] data = new byte[SASobj._serialPort.BytesToRead]; 
      SASobj._serialPort.Read(data, 0, data.Length); 

      InputData = ByteToHex(data); 

      this.BeginInvoke(new SetTextCallback(SetText), new object[] { InputData }); 


     } 

private void SetText(string text) 
     { 

      this.txtMessage.Text += text; 

     } 
+0

このコードは期待通りに動作しません。読み取り操作で完全なパケットを受け取ることは何も保証されません。これらの質問に関する私の回答を見て、データを正しく読み取る方法を理解する助けになります。http: //stackoverflow.com/questions/35175874/does-function1-and-function2-use-my-serial-port-class-in-thread-safe-way/35246817#35246817 http://stackoverflow.com/questions/35636655/msvs-c-sharp-serialport-received-data-loss/35637286#35637286 http://stackoverflow.com/questions/30499210/using-dma-to-access-high-speed-serial-port/ 30781505#30781505 – Gusman

+0

'DataReceived'イベントの中でポート' Parity'を変更することは意味がありません。最初に 'Parity.None' /' .Space'か '.Mark'かどうかを判断してください。私はこれが最初の塊の後にデータを受け取るのを止める理由だと推測します。 'ByteToHex'メソッドも投稿してください。バグがあるかもしれないからです。また、ブロックが順不同で連結されないようにするには、データを 'Queue '(または 'string')に同期して(ハンドラ内で)エンキューする必要があります。 'SetText'の内部での連結が順序どおりに実行されない可能性があるため、キュー全体のUI更新を/ stringにディスパッチします。 – Groo

答えて

1

から読んでいます。実際の値SerialPort.Parityは実際には無関係です。とにかく時間の半分のパリティエラーが発生しますが、着信メッセージの途中でこれらのプロパティを変更すると、必ず問題が発生します。

ただし、パリティエラーは異なるイベント(SerialPort.ErrorReceived)を使用して報告され、引数の1つはSerialError.RXParityに設定されています。また

、私はコメントで述べたように、それはSetTextへの複数の呼び出しが発生する順番をする必要がないことを意味し、バックグラウンド(ThreadPool)スレッド、上のメソッド呼び出しをキューにためBeginInvokeを呼び出すことは良いアイデアではありませんシーケンシャル。 @Gusmanが示唆したように

、そこポートからデータを得るためのより良い方法がありますが、最も簡単な方法は、あなたが注文したマージが何かのようになり得ることを保証するために:SerialPort.ErrorReceivedため

readonly object _lock = new object(); 
SerialPort _serialPort; 
string _text = ""; 

public void Init() 
{ 
    _serialPort = new SerialPort("COM1", 19200, Parity.Space, 8, StopBits.One); 
    _serialPort.ParityReplace = 0; 
    _serialPort.DataReceived += DataReceived; 
    _serialPort.ErrorReceived += ErrorReceived; 
    _serialPort.Open(); 
} 

void DataReceived(object sender, SerialDataReceivedEventArgs e) 
{ 
    DumpToHexString(); 
} 

void ErrorReceived(object sender, SerialErrorReceivedEventArgs e) 
{ 
    if (e.EventType == SerialError.RXParity) 
     DumpToHexString(); 
} 

void DumpToHexString() 
{ 
    lock (_lock) 
    { 
     while (_serialPort.BytesToRead > 0) 
     { 
      var chunk = new byte[_serialPort.BytesToRead]; 
      _serialPort.Read(chunk, 0, chunk.Length); 
      _text += ByteToHex(chunk); 
     } 
    }   
    this.BeginInvoke(new Action(() => txtMessage.Text = _text)); 
} 

また、MSDNのドキュメントRXパリティエラーについての発言を持っている:

パリティエラーがストリームの末尾のバイトで発生した場合、余分なバイトが126

012の値を入力バッファに追加されます

これは、値126の末尾のバイトがErrorReceivedであることを意味していると推定していますが、実際にこのような特殊なケースはありませんでした。

+0

ありがとう..これは大きな助けですが、私はもう1つ問題があります。実際にはSASプロトコルは常に80と81でポーリングします。この結果が出ると、開始時と終了時に80と81が追加されます。 like "80 {01 73 1D 00 09 03 00 00 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 B3 74 A4 02 0E 76} 81 80 81 80"中括弧のみの結果私が価値を得るためのロジックを置いているなら、結果は私が得ているのと同じ方法で来ています。実際に、これはパケットの開始であり、このビットはパケットの終わりです。 –

+0

これらのバイトは常に先頭と末尾にあるべきですか?このメッセージはCRC /チェックサムを持っていますか? – Groo

+0

はい。これらのメッセージにはCRCがあります。 –

関連する問題