powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Чтение из COM-порта без признака окончания передачи информации
3 сообщений из 3, страница 1 из 1
Чтение из COM-порта без признака окончания передачи информации
    #39783023
WinterGraveyard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ситуация: на COM-порт поступают некие данные. Размер пакета - от 4 до 8 байт. Данные поступают не непрерывно - т.е., например, пришло 6 байт, потом пауза минут 5, потом пришло 8 байт, пауза 2 секунды, пришло еще сколько-то байт. Можно считать, что минимальная пауза передачи данных - 1 секунда. Данные не содержат никаких признаков начала/окончания передачи. EOF на порт также не поступает - пишущая сторона постоянно держит свой порт открытым. Плюс есть еще такой нюанс: в зависимости от причин непонятного характера, весь пакет можно сразу получить на единственном срабатывании DataReceived - т.е. весь пакет находится внутри буфера чтения порта. А иногда получение пакета происходит за несколько срабатываний DataReceived, т.е. в буфер чтения пакет попадает порциями. При этом эмпирически выяснено, что между срабатываниями DataReceived при получении одного пакета интервал не более 0.1 сек. Вопрос: каким образом можно при считывании очередного пакета сгенерировать событие для передачи данных на обработку? Навскидку в голову приходит решение держать в переменной класса-обертки над COM-портом время последнего срабатывания DataReceived, если разница текущего времени, и времени последнего срабатывания больше 1 сек., то началась передача новой порции данных, и предыдущую можно отдавать на обработку. Но требуется полученную порцию данных отдавать на обработку сразу, как только истечет минимальный интервал паузы передачи данных (та самая 1 секунда). В DataReceived запускать таймер с таймаутом в 1 сек. (и который по срабатыванию будет райзить событие для обработки), если новый DataReceived сработал с интервалом меньше 1 сек., то останавливать таймер, и запускать его заново? Вместо таймера запускать Task? Еще как-то? Как лучше поступить в вышеописанной ситуации?
...
Рейтинг: 0 / 0
Чтение из COM-порта без признака окончания передачи информации
    #39783029
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
WinterGraveyard,

SetCommTimeouts из WinAPI
...
Рейтинг: 0 / 0
Чтение из COM-порта без признака окончания передачи информации
    #39783555
WinterGraveyard
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ИзопропилWinterGraveyard,

SetCommTimeouts из WinAPI
Спасибо за указание в нужном направлении - у SerialPort есть свойство ReadTimeout, при установке которого как раз вызывается SetCommTimeouts. По умолчанию оно равно бесконечности, мне просто нужно было на время чтения очередной порции выставить его в минимальный промежуток времени между поступлением порций. Сделал примерно так:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
public event Action<byte[]> OnPacketReceived;

const int PacketReadTimeout = 500;
const int MaxPacketSize = 8;

readonly List<byte> _readBuffer = new List<byte>(MaxPacketSize);

void ListenPort(object sender, SerialDataReceivedEventArgs args)
{
  if (args.EventType == SerialData.Eof)
    return;
  if (_scannerPort.ReadTimeout != PacketReadTimeout)
    _scannerPort.ReadTimeout = PacketReadTimeout;
  try
  {
    while (_readBuffer.Count<MaxPacketSize)
    {
      var current = _scannerPort.ReadByte();
      if (current == -1) break;
      _readBuffer.Add((byte)current);
    }
    ReadCompleted();
  }
  catch (TimeoutException)
  {
    ReadCompleted();
  }
  catch (Exception e)
  {
    LogManager.GetLogger("*").Error(e.StackTrace);
  }
}

void ReadCompleted()
{
  _scannerPort.ReadTimeout = SerialPort.InfiniteTimeout;
  _scannerPort.DiscardOutBuffer();
  OnPacketReceived?.Invoke(_readBuffer.ToArray());
  _readBuffer.Clear();
}
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Чтение из COM-порта без признака окончания передачи информации
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]