0

RS485 を介して ModBus ネットワークで通信をリッスンするプログラムを作成する必要があります。RS485 <> USB ドングルでネットワークに接続しています。

SerialPort.DataReceived イベントを使用して一部のデータを読み取ることができますが、奇妙な結果が得られます。多くの場合、データは 1 つにまとめられるべきときに分割されます。(Modbus マスターは 100ms ごとに送信します)。

class Serial
{
    private SerialPort port;
    Queue<byte[]> buffer;

    public Serial()
    {
        buffer = new Queue<byte[]>();
        port = new SerialPort("COM3", 19200, Parity.Even, 8, StopBits.One);
        port.DataReceived += port_DataReceived;
    }

    public void Open()
    {
        if (port.IsOpen)
        {
            port.Close();
        }

        port.Open();
    }

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        byte[] buff = new byte[port.BytesToRead];
        port.Read(buff, 0, port.BytesToRead);
        buffer.Enqueue(buff);
    }
}

送信開始のサインがありません。フレーム間の遅延は最小です。3.5 文字、文字間の最大遅延は 1.5 文字です。

4

1 に答える 1

2

これは正常な動作であり、シリアル ポートは非​​常に低速なデバイスです。DataReceived イベントは、1 バイトが受信されるとすぐに発生します。Read() を呼び出して、返される値 (入力バッファーから取得できたバイト数) に注意する必要があります。これは複数になる可能性がありますが、「パケット」のバイト数と同じになることはめったにありません。これは、何らかの理由でマシンが非常に遅くなった場合にのみ発生する可能性があります。

デバッガーは、イベントハンドラーコードのブレークポイントまたはシングルステップを遅くする1つの方法であることに注意してください。ドライバーは、パケット内のすべてのバイトを受信するのに十分な時間を与えます。Read() 呼び出しがそれらすべてを返すようにします。しかし、そのコードのデバッグを停止するとすぐに、それは機能しなくなります。

ReceivedBytesThreshold プロパティを使用してイベントを遅らせることができますが、これはパケットのサイズが固定されている場合にのみ機能します。Read() 呼び出しの 2 番目の引数を使用して、取得したバイトを byte[] に追加するだけです。そして、それらがすべて揃うまでパケットを処理しないでください。

于 2012-11-16T14:14:56.157 に答える