.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", и теперь нет переполнения буфера.