0


0

rtsenabledを使用してsystem.io.portsが間違ったパケットを受信する

特定のパケットを送信し、電子デバイスから応答を取得するメソッドを作成しています。 「rtsEnabled = true」でsystem.io.portsを使用しています。

問題は、アプリケーションに入るときに受信パケットが変更されることです。 eltimaを使用して何が受信されているかを監視しており、eltimaが受信したパケットとアプリケーションが受信したパケットには2バイトの違いがあります。

アプリケーションは、16進数で2倍のすべてのバイト(例FFまたはBB)を3Fに変更しています。 以下は、エルティマが提供しているものです。

_ _ 5b 00 00 09 32 13 31 33 35 36 31 39 31 30 30 38 32 35 00 01 ff 64 01 00 bb 0f 5d --Eltima

5B 00 00 09 32 13 31 33 35 30 32 37 31 30 30 38 32 35 00 01 3F 64 01 00 3F 04 5D --MyApplication _ _

以下は私のコードです:

public string MakeSerialConnection(string COM, int baud, string dest)
    {
        SerialPort port = new SerialPort(COM, baud, Parity.None, 8, StopBits.One);
        try
        {
            if (!(port.IsOpen))
            {
                string destination = dest;
                //BUILD PACKET FOR SENDING
                byte[] fullPacket = BuildPacket(destination);
                port.Open();
                port.RtsEnable = false;

                port.Handshake = Handshake.None;

                //SEND PACKET TO DEVICE
                port.Write(fullPacket,0,9);

                #region RECEIVE DATA FROM SERIAL
                //MAKE PROCESS STOP FOR 5sec
                Thread.Sleep(240);

                port.RtsEnable = true;

                Thread.Sleep(1000);
                string reading = port.ReadExisting();
               // int readingint = port.ReadByte();

                    port.Close();
                    port.Dispose();
                    return reading;
                #endregion
            }
            else
            {
                return "";
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (port != null)
            {
                //port.Close();
                if (port.IsOpen)
                {
                    port.Close();
                }
                port.Dispose();
            }

        }

これが起こっている理由を理解するのを手伝ってください

3 Answer


1


ASCIIコードチャートを見ると、0x3fが?の文字コードであることがわかります。 これは、Encoding.GetString()がバイト値を文字に変換できないときに取得する置換文字です。 理にかなっています、デフォルトのSerialPort.EncodingはASCIIです。0xffはそのエンコーディングの有効な文字コードではありません。

根本的な問題は、文字列を読んでいることです。 しかし、デバイスは文字列を送信せず、バイトを送信しています。 ReadExisting()の代わりにSerialPort.Read()を使用する必要があります。


1


読み取りバイトを文字列に入れないでください。 SwDevManが述べているように、ポートを介して文字列を送信するのではなく、バイト配列を送信しています。 良い習慣として、所属していない型にデータをキャストしないでください。 フレームワークの背後にあるコードが、知らないうちにデータを変更する場合があります。

Read()またはReadByte()を使用して、作成するバイトを配列またはバイトまたはリストに配置します。 Read()は論理的な方法ですが、ReadByteにはその用途があります。 ReadByte()を使用すると、一度に1バイトが読み取られます。 最初のバイトが特別なフラグ、たとえばコマンド開始フラグであることを期待している場合、すぐに検証して、破棄するか、読み取りを続行するかを選択できます。

        while (serialport.BytesToRead > 0)
        {
            startingByte= Convert.ToByte(serialport.ReadByte());
            CheckIfStartOfCommand(startingByte)
            ...
        }

それ以外の場合は、Read()を使用して、特定のバイト数をプリセット配列に取得します。


0


Handshakingについて、デバイス仕様には何と書かれていますか? ハンドシェイクを「RequestToSend」に設定する必要がある場合があります。 また、可能であれば、http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspx [DataReceived]を使用して、スリープ状態ではなくデータを受信します。

また、シリアルポートのhttp://msdn.microsoft.com/en-us/library/system.io.ports.serialport.encoding.aspx[Encoding]をチェックして、デバイスが使用しているものと一致することを確認します。 デフォルトはhttp://msdn.microsoft.com/en-us/library/system.io.ports.handshake.aspx[ASCIIEncoding]であるため、デバイスが他のものを使用している場合(例:http://msdn.microsoft .com / en-us / library / system.text.unicodeencoding.aspx [Unicode])変更する必要があります。