.NET SerialPort. Читайте байты skipps

Решение

Чтение байтов данных через "port.ReadByte" происходит слишком медленно, проблема заключается в классе SerialPort. я изменил его на чтение больших кусков через "port.Read", и теперь нет переполнения буфера.

хотя я сам нашел решение, записать его мне помогло, и, возможно, у кого-то есть такая же проблема, и он находит это через Google...

(как я могу отметить это как ответ?)

РЕДАКТИРОВАТЬ 2

установив

port.ReadBufferSize = 2000000;

Я могу отложить проблему на ~30 секунд. кажется, что.Net на самом деле слишком медленный... поскольку мое приложение не так критично, я просто установил буфер в 20 МБ, но я все еще заинтересован в причине.

РЕДАКТИРОВАТЬ

я только что проверил то, о чем раньше не думал (позор мне):

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

и кажется, что у меня переполнение. Реализация.Net слишком медленная для 500k или есть ошибка на моей стороне?

Оригинальный вопрос

Я построил очень примитивный осциллограф (AVR, который отправляет данные АЦП через UART на чип FTDI). На стороне ПК у меня есть программа WPF, которая отображает эти данные.

Протоколл это:

два байта синхронизации (0xaffe) - 14 байтов данных - два байта синхронизации - 14 байтов данных - ...

Я использую 16-битные значения, поэтому внутри 14 байтов данных 7 каналов (сначала lsb).

Я проверил прошивку uC с помощью hTerm, и он все отправляет и получает все правильно. Но, если я пытаюсь прочитать данные с помощью C#, иногда некоторые байты теряются. Программа oszilloscop - беспорядок, но я создал небольшое приложение, которое имеет те же симптомы.

Я добавил два метода расширения для а) чтения одного байта из COM-порта и игнорирования -1 (EOF) и б) ожидания шаблона синхронизации.

Пример программы сначала синхронизируется с потоком данных, ожидая (0xaffe), а затем сравнивает полученные байты с ожидаемыми значениями. цикл запускается несколько раз, пока не появится сообщение об ошибке подтверждения. Я не мог найти что-нибудь о потерянных байтах через Google, любая помощь будет оценена.

Код

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++;
            }
        }
    }
}

1 ответ

Решение

Чтение байтов данных через "port.ReadByte" происходит слишком медленно, проблема заключается в классе SerialPort. я изменил его на чтение больших кусков через "port.Read", и теперь нет переполнения буфера.

Другие вопросы по тегам