2

modbus およびシリアル接続用のクラス ライブラリを構築しています。バイト配列を返す必要がありますが、System.IO.Ports から DataReceived イベントを使用する場合、型が void であるため何も返すことができません。また、DataReceived が起動していないことに気付きました。以下は私のコードです:

        public void ConnectSerialModBus_Loopback(string COM, int baud, int meter_address, int function, int Code_HighByte, int Code_LowByte, int data_high_byte, int data_low_byte)
    {
        SerialPort port = new SerialPort(COM, baud);
        try
        {

            if (!(port.IsOpen))
            {
                byte[] sendPacket = BuildPacket(meter_address, function, Code_HighByte, Code_LowByte, data_high_byte, data_low_byte);
                double dataBytes = 2.0;

                port.Open();
                port.RtsEnable = false;//rts = high
                port.Handshake = Handshake.None;
                //SEND PACKET TO DEVICE
                port.Write(sendPacket, 0, sendPacket.Length);

                #region RECEIVE DATA FROM SERIAL
                //MAKE DELAY TO SEND
                Thread.Sleep(10);

                port.RtsEnable = true;
                //MAKE DELAY TO RECEIVE
                port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
                //Thread.Sleep(CalculateDelay(dataBytes)+90);

                port.Close();
                port.Dispose();
                #endregion

            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (port != null)
            {
                if (port.IsOpen)
                {
                    port.Close();
                }
                port.Dispose();
            }
        }
    }

    void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        SerialPort port = (SerialPort)sender;
        byte[] readingbyte = new byte[port.BytesToRead];
        if (port.BytesToRead > 0)
        {
            port.Read(readingbyte, 0, readingbyte.Length);   
        }
    }

port_DataReceived何らかの方法で、またはから受信したバイトを返したいのですConnectSerialModBus_Loopbackが、DataReceivedも起動していません。これは非常に緊急です助けてください

4

2 に答える 2

22

DataReceived が発火していない

port.Close()ハンドラをアタッチした直後で、SerialPort の受信スレッドが実行される前に呼び出すため、DataReceived は起動しません。

バイト配列を返す - 簡単な答え

あなたが提供する簡単なコード サンプルでは、​​プライベート メンバーを作成し、イベント ハンドラー内からそれByte[]にオブジェクトを割り当てることができます。readingbyteport_DataReceived

バイトの配列を返す - OO ヒントの回答

ただし、より厳格なアプリケーションでは、Modbus ADU プロトコル部分をカプセル化し、クライアント要求の送信とサーバーの応答の (レイヤー 2) 処理の両方を処理する Transaction クラスを作成することを検討する必要があります。

ADU 層に加えて、PDU 層を、ADU クラスが要求バイトを取得して応答バイトを返すためのインターフェイスを提供する抽象 ModbusFunction 基本クラスに分離します。次に、クライアントに使用させたい各 modbus 機能は、PDU 基本クラスから派生した独自のクラスで実現されます。

このようにして、サーバーと対話する必要がある場合、正しい PDU データ パケットを形成するための適切なパラメーターを使用して PDU 関数クラスのインスタンスを作成し、それを要求/再試行/応答ロジックを処理する Transaction オブジェクトに渡します。返されたデータを PDU オブジェクトに戻して、適切に解析します。

PDU 基本クラスにイベントを追加すると、コードの他の部分を PDU クラスのイベントに関連付けて、関数が正常に完了したときに通知を受け取ることができます。

Modbus 関数を介して実装された複数のアドレス指定可能なプロパティを持つサーバーでは、各プロパティ (または連続したレジスタのセットなど) に適切な Modbus Function クラスのインスタンスを作成し、イベントにアタッチしてモデルを更新します。および/またはオブジェクトが更新イベントを発生させるたびにUI。サーバーに手動でクエリを実行する場合は UI コマンドをフックして、Properties Modbus Function オブジェクトを Transaction オブジェクトに渡します。プロパティを定期的にポーリングする場合は、スケジュールに従ってクエリを実行するタイマー スレッドを実装します。

于 2014-07-14T18:18:42.290 に答える
0

datareceived イベントをスリープさせません。

イベントが発生すると、バイトがキューに入れられます。バイトのチャンクを元に戻すために UI が使用できるメソッドが必要になります。

詳細については、 SerialPort101を参照してください。

于 2010-10-17T14:58:50.860 に答える