2

シナリオを説明しましょう: 次の例のように、データ (文字列) をもたらすシリアル ポート:

02051014 0009 M 0 741 30041105 2632 0 30041105

私はあらゆる種類の読み取りを試みました(読み取り、バイトの読み取り、文字の読み取り、行の読み取り、既存の読み取り)。新しい行を変更しようとしましたが、データが重複しています。上記の例を見て、データがどのように来ているか見てみましょう:

0220510114 00009 M 0 741 300441105 2632 0 300411055

どうすればこの問題を解決できるか、誰にも分かりますか?

コード:

[...]
try
{
    this.serialPort = new SerialPort("COM1", 2400, Parity.None, 7, StopBits.One);
    this.serialPort.DataReceived += new SerialDataReceivedEventHandler(portaSerial_DataReceived);
    this.serialPort.Handshake = Handshake.XOnXOff;
    this.serialPort.Encoding = Encoding.ASCII;
    this.serialPort.Open();
}
[...]
private void portaSerial_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        var invalidValuesToBreakLine = new int[] { 13, 10, 0 };
        int data;

        while (this.serialPort.BytesToRead > 0)
        {
            data = this.serialPort.ReadChar();

            if (invalidValuesToBreakLine.Contains(data))
            {
                if (!this.breakLineWasPerformed)
                {
                    this.breakLineWasPerformed = true;

                    this.dataList.Add(this.temporaryString);

                    this.temporaryString = string.Empty;
                }
            }
            else
            {
                if (this.breakLineWasPerformed)
                {
                    this.breakLineWasPerformed = false;
                }

                this.temporaryString += (char)data;
            }
        }
[...]
4

2 に答える 2

0

私が最初に試みることはdata、メソッドを呼び出すたびに空の文字列にリセットするReadChar()か、入力バッファーをフラッシュすることです。

への呼び出しBytesToRead()が 0 より大きい値を返していると思われますが、ReadChar() 呼び出しはシリアル ポート バッファーの元の文字を返しています。これは、シリアル ポートの内部タイミングと、コードがハードウェア デバイスに対して「実行速度が速すぎる」可能性が高いという事実によるものです。

メソッドのwhileループ全体を再考するかもしれません。おそらくこれをかなり単純化して、次のことを試してみてください(カスタマイズしたコードを使用して)

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    SerialPort sp = (SerialPort)sender;
    string indata = sp.ReadExisting();
    Console.WriteLine("Data Received:");
    Console.Write(indata);
}

改行文字を変更するには、indata文字列を調べて文字を分割し、結果をグローバル変数に保存してから、残ったデータを再利用します。

于 2013-02-05T14:17:15.397 に答える
0

掘り下げてみると、予期しないタイミングでイベントが発生する可能性があることを示唆するこのStackOverflow の質問/回答が見つかりました。DataReceivedしたがって、可能であれば、NewLineそれにトリガーを設定する必要があります。

このアイデアのテストとして、ボタンを追加してみて、データがあることがわかるまで待っから、クリックしてストリームを表示することができます。重複がない場合は、DataReceivedイベントが過度に熱心であり、正しく起動していないことを示しています。NewLine次に、DtrEnableなどを確認することをお勧めしますDsrHolding

private void TestButton_Click(object sender, EventArgs e)
{
    string indata = this.serialPort.ReadExisting();
    MessageBox.Show(indata);
}
于 2013-02-05T13:38:56.443 に答える