system.io.ports 使用 rtsenabled 接收错误的数据包

发布于 2024-09-16 03:02:59 字数 1995 浏览 2 评论 0原文

我正在编写一种发送特定数据包并从电子设备获取答复的方法。我正在将 system.io.ports 与 rtsEnabled = true 结合使用。

问题在于,当进入应用程序时,接收到的数据包被更改。我正在监视使用 eltima 接收的内容,并且 eltima 接收的数据包和应用程序接收的数据包有两个字节不同。

应用程序将十六进制双倍的每个字节(例如 FF 或 BB)更改为 3F。 以下是 Eltima 给出的内容:

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();
            }

        }

请帮我弄清楚为什么会发生这种情况

i am writing a method which sends a particular packet and gets an answer back from an electronic device. I am using system.io.ports with rtsEnabled = true.

The problem is that when entering the application the received packet is altered. I am monitoring what is being received using eltima and the packet received by eltima and that by the application have two bytes different.

The application is changing every byte which is double in hex (example FF or BB) to 3F.
The following is what Eltima is giving:

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

The following is my code:

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();
            }

        }

Please help me figure out why this is happening

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

素手挽清风 2024-09-23 03:02:59

如果您查看 ASCII 代码表,您会发现 0x3f 是 ? 的字符代码。这是当 Encoding.GetString() 无法将字节值转换为字符时您将获得的替换字符。有道理,默认的 SerialPort.Encoding 是 ASCII,0xff 不是该编码中的有效字符代码。

根本问题是您正在读取字符串。但设备不是发送字符串,而是发送字节。您必须使用 SerialPort.Read() 而不是 ReadExisting()。

It you look in an ASCII code chart, you'll see the 0x3f is the character code for ?. That's the substitution character you'll get when Encoding.GetString() cannot convert a byte value to a character. Makes sense, the default SerialPort.Encoding is ASCII, 0xff is not a valid character code in that encoding.

The root problem is that you are reading strings. But the device is not sending strings, it is sending bytes. You must use SerialPort.Read() instead of ReadExisting().

Smile简单爱 2024-09-23 03:02:59

不要将读取的字节放入字符串中。正如 SwDevMan 所说,您不是通过端口发送字符串,而是发送字节数组。作为良好的做法,请避免将数据转换为不属于的类型。有时,框架背后的代码会在您不知情的情况下更改数据。

使用 Read() 或 ReadByte() 并将字节放入您将构建的一个或多个字节数组或列表中。 Read() 是逻辑方法,但 ReadByte 有它的用途。使用 ReadByte() 将一次读取一个字节。如果您期望第一个字节是一个特殊标志,例如命令开始标志,您可以立即验证它并选择丢弃或继续读取。

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

否则,使用 Read() 将一定数量的字节放入预设数组中。

Do not place your read bytes into a string. As stated by SwDevMan, you're not sending a string through the port but a byte array. As good practice, avoid casting your data into types that don't belong. Sometimes, the code behind the framework changes the data without your knowledge.

Use Read() or ReadByte() and place your bytes into an array or bytes or list that you will build. Read() is the logical way but ReadByte has it's uses. Using ReadByte() will read one byte at a time. If you are expecting the first byte to be a special flag, a start of command flag for instance, you can immediatly validate it and choose to either discard or continue reading.

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

Otherwise, use Read() to get a certain number of bytes into a preset array.

╰◇生如夏花灿烂 2024-09-23 03:02:59

设备规范对握手?您可能必须将握手设置为 RequestToSend。另外,如果可能,请使用 DataReceived 接收数据而不是休眠。

我还会检查 编码串行端口,以确保它与设备正在使用的端口匹配。默认值为 ASCIIEncoding,因此如果设备正在使用其他内容(例如:Unicode)你需要改变它。

What does the device spec say about the Handshaking? You might have to set the handshake to RequestToSend. Also, If possible, use the DataReceived to receive data rather than sleeping.

I would also check the Encoding of the serial port to make sure it matches what the device is using. The default is ASCIIEncoding, so if the device is using something else (ex: Unicode) you'll need to change it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文