简体   繁体   English

.NET SerialPort.Read 跳过字节

[英].NET SerialPort.Read skipps bytes

Solution解决方案

Reading the data byte wise via "port.ReadByte" is too slow, the problem is inside the SerialPort class.通过“port.ReadByte”读取数据字节太慢,问题出在 SerialPort 类内部。 i changed it to reading bigger chunks via "port.Read" and there are now no buffer overruns.我将其更改为通过“port.Read”读取更大的块,现在没有缓冲区溢出。

although i found the solution myself, writing it down helped me and maybe someone else has the same problem and finds this via google...虽然我自己找到了解决方案,但写下来对我有帮助,也许其他人也有同样的问题,并通过谷歌找到了这个...

(how can i mark it as answered?) (我如何将其标记为已回答?)

EDIT 2编辑 2

by setting通过设置

port.ReadBufferSize = 2000000;

i can delay the problem for ~30 seconds.我可以将问题延迟约 30 秒。 so it seems, .Net really is too slow... since my application is not that critical, i just set the buffer to 20MB, but i am still interested in the cause.所以看起来,.Net 真的太慢了​​......因为我的应用程序不是那么重要,我只是将缓冲区设置为 20MB,但我仍然对原因感兴趣。

EDIT编辑

i just tested something i had not thought of before (shame on me):我刚刚测试了一些我以前没有想到的东西(我很惭愧):

port.ErrorReceived += (object self, SerialErrorReceivedEventArgs se_arg) => { Console.Write("| Error: {0} | ", System.Enum.GetName(se_arg.EventType.GetType(), se_arg.EventType)); };

and it seems that i have an overrun.看来我已经超支了。 Is the .Net implementation too slow for 500k or is there an error on my side? .Net 实现对于 500k 来说是否太慢了,还是我这边有错误?

Original Question原始问题

i built a very primitive oszilloscope (avr, which sends adc data over uart to an ftdi chip).我构建了一个非常原始的示波器(avr,它通过 uart 将 adc 数据发送到 ftdi 芯片)。 On the pc side i have a WPF Programm that displays this data.在 PC 端,我有一个显示这些数据的 WPF 程序。

The Protokoll is: Protokoll 是:

two sync bytes (0xaffe) - 14 data bytes - two sync bytes - 14 data bytes - ...两个同步字节 (0xaffe) - 14 个数据字节 - 两个同步字节 - 14 个数据字节 - ...

i use 16bit values, so inside the 14 data bytes are 7 channels (lsb first).我使用 16 位值,所以在 14 个数据字节内有 7 个通道(lsb 在前)。

I verified the uC Firmware with hTerm, and it does send and receive everything correct.我用 hTerm 验证了 uC 固件,它确实发送和接收了所有正确的东西。 But, if i try to read the data with C#, sometimes some bytes are lost.但是,如果我尝试使用 C# 读取数据,有时会丢失一些字节。 The oszilloscop programm is a mess, but i created a small sample application, which has the same symptoms. oszilloscop 程序一团糟,但我创建了一个小示例应用程序,它具有相同的症状。

I added two extension methods to a) read one byte from the COM Port and ignore -1 (EOF) and b) wait for the sync pattern.我添加了两个扩展方法 a) 从 COM 端口读取一个字节并忽略 -1 (EOF) 和 b) 等待同步模式。

The sample programm first syncs onto the data stream by waiting for (0xaffe) and then compares the received bytes with the expected values.示例程序首先通过等待 (0xaffe) 同步到数据流,然后将接收到的字节与预期值进行比较。 the loop runs a few times until an assert failed message pops up.循环运行几次,直到弹出断言失败消息。 I could not find anything about lost bytes via google, any help would be appreciated.我无法通过谷歌找到任何关于丢失字节的信息,任何帮助将不胜感激。

Code代码

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SerialTest
{
    public static class SerialPortExtensions
    {
        public static byte ReadByteSerial(this SerialPort port)
        {
            int i = 0;
            do
            {
                i = port.ReadByte();
            } while (i < 0 || i > 0xff);
            return (byte)i;
        }

        public static void WaitForPattern_Ushort(this SerialPort port, ushort pattern)
        {
            byte hi = 0;
            byte lo = 0;

            do
            {
                lo = hi;
                hi = port.ReadByteSerial();
            } while (!(hi == (pattern >> 8) && lo == (pattern & 0x00ff)));
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //500000 8n1
            SerialPort port = new SerialPort("COM3", 500000, Parity.None, 8, StopBits.One);
            port.Open();
            port.DiscardInBuffer();
            port.DiscardOutBuffer();

            //Sync
            port.WaitForPattern_Ushort(0xaffe);


            byte hi = 0;
            byte lo = 0;
            int val;

            int n = 0;

            // Start Loop, the stream is already synced
            while (true)
            {
                //Read 7 16-bit values (=14 Bytes)
                for (int i = 0; i < 7; i++)
                {
                    lo = port.ReadByteSerial();
                    hi = port.ReadByteSerial();

                    val = ((hi << 8) | lo);
                    Debug.Assert(val != 0xaffe);
                }
                //Read two sync bytes
                lo = port.ReadByteSerial();
                hi = port.ReadByteSerial();

                val = ((hi << 8) | lo);
                Debug.Assert(val == 0xaffe);

                n++;
            }
        }
    }
}

Reading the data byte wise via "port.ReadByte" is too slow, the problem is inside the SerialPort class.通过“port.ReadByte”读取数据字节太慢,问题出在 SerialPort 类内部。 i changed it to reading bigger chunks via "port.Read" and there are now no buffer overruns.我将其更改为通过“port.Read”读取更大的块,现在没有缓冲区溢出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM