web-dev-qa-db-ja.com

シリアルポートReadLineとReadExisting、またはシリアルポートからデータを正しく読み取る方法

シリアルポートからデータを読み取っています。データはスケールから外れます。現在、Readline()を使用しており、DiscardInBuffer()を削除した後でもデータが削除されます。シリアルポートからデータを読み取る適切な方法は何ですか?オンラインでの例は非常に少ないので、誰も理解していない聖杯のようなものだと思います。

何か助けてください?

シリアルポートは気まぐれな子のようです。

C#、WinCE 5.0、HPシンクライアント、Compact Framework 2.0

 private void WeighSample()
    {
        this._processingDone = false;
        this._workerThread = new Thread(CaptureWeight);
        this._workerThread.IsBackground = true;
        this._workerThread.Start();
    } //end of WeighSample()


    private void CaptureWeight()
    {
         globalCounter++;
         string value = "";


          while (!this._processingDone)
          {
              try
              {

                 value = this._sp.ReadLine();

                  if (value != "")
                  {
                      if (value == "ES")
                      {
                          _sp.DiscardInBuffer();
                          value = "";
                      }
                      else
                      {
                          this.Invoke(this.OnDataAcquiredEvent, new object[] { value });
                      }
                  }
              }
              catch (TimeoutException)
              {
                  //catch it but do nothing
              }
              catch
              {
                  //reset the port here?
                  MessageBox.Show("some other than timeout exception thrown while reading serial port");
              }
          }


    } //end of CaptureWeight()

私のアプリケーションについて注意すべきことの1つは、カーソルがテキストボックスにジャンプしたときにスレッド(weighSample)を開始することです。これは、重みを手動で入力することもできるためです(要件の一部)。そのため、ユーザーが天びんでPRINTを押すのか、重量を入力するのかは事前にわかりません。いずれの場合も、データが取得された後、ワーカースレッドを終了します。また、信頼できないと言われているため、シリアルポートイベントDataReceivedを使用していないことに注意してください。

コメント/アイデアは大歓迎です。シリアルポートを使ったのはこれが初めてです。

14
sarsnake

私は決して ReadLineが機能して運が良かった。データが利用可能な場合はいつでもローカルバッファへの読み取りを実行し、別のスレッドを使用してデータをスキャンし、自分で改行を見つけます。

5
ctacke

入力データの行末(EOL)文字が何であるかによって異なります。データが行指向の場合、ReadLineは使用するのに有効な関数ですが、NewLineプロパティを調べて、入力データに対して適切に設定されていることを確認することをお勧めします。

たとえば、体重計がEOLのラインフィードを出力する場合は、port.NewLine = "\n";を設定します。

http://msdn.Microsoft.com/en-us/library/system.io.ports.serialport.newline.aspx

11
joshperry

エリアス・サントスにコメントしたいのですが、評判がよくありません。 ReadExistingメソッドの使用にはいくつかの落とし穴があります。

https://msdn.Microsoft.com/en-us/library/system.io.ports.serialport.readexisting(v = vs.110).aspx

このメソッドは、内部バッファーに末尾の先頭バイトを残す可能性があることに注意してください。これにより、BytesToRead値がゼロより大きくなります。

以前にReadExistingでいくつかの問題に直面しましたが、これは不要なバイトが原因です。 Readlineを使用すると、これらの問題が修正されました。

1
if (serialPort1->IsOpen){
    if (serialPort1->BytesToRead>0){
        this->textBox1->Text += serialPort1->ReadExisting();
    }
}
0
Elias Santos