c # потеря данных последовательного порта - PullRequest
1 голос
/ 31 декабря 2010

Я написал программу на C # для получения данных через порт COM2. Скорость передачи данных установлена ​​на 115200. Отправитель отправляет данные со скоростью 115200 бит / с. Моя программа иногда теряет несколько байтов. Я вызываю ReadByte метод для чтения данных в цикле while(true) с com-порта.

У меня есть несколько вопросов:

  • Когда установлена ​​высокая скорость передачи данных, следует ли ожидать потери данных? если да, то почему?
  • Я устанавливаю размер считывающего буфера как 100 *1024* 1024. Это устанавливает размер буфера последовательного драйвера равным 100 *1024* 1024?

Есть мысли о том, как отладить эту проблему?

Ответы [ 2 ]

4 голосов
/ 31 декабря 2010

Размер буфера приема 100 *1024* 1024 огромен!Я серьезно сомневаюсь, что вам нужен этот размер вообще, и уж точно не для реального буфера последовательного порта.

Возможно, вы переполняете физический приемный буфер приемника, поэтому вам, возможно, придется посмотреть на использованиеуправление потоком.Это позволит вашему приемнику сказать вашему передатчику «Подождите, перестаньте посылать на некоторое время, позвольте мне разобраться с тем, что у меня есть вначале».

Аппаратное управление потоком (обычно) используется через контакты RTS (Запрос на отправку) и CTS (Очистить для отправки).

Взгляните на эту статью , которая объясняет немного больше об этом.

Я бы лично рекомендовал оставить для свойства ReceivedBytesThreshold последовательного порта значение по умолчанию, равное 1, и затем обработать событие DataReceived.Кто знает, может быть, завтра вам понадобится прочитать сообщение размером 20 байт или 5 байт.Может быть, вам нужно будет читать сообщения переменной длины в будущем?Если оставить пороговое значение равным 1, это означает, что вы можете обрабатывать любые и все байты, которые будут получены, сейчас и в будущем.

Этот порог будет означать, что событие сработает при вминимум 1 байт в буфере.Там может быть больше, и, вероятно, будет.Обратите внимание, что значение NOT обязательно означает, что оно будет срабатывать для каждого полученного байта.В каждом событии вам нужно проверить свойство BytesToRead и прочитать это число в свой собственный буфер.

Стоит повторить, что событие NOT обязательно будет срабатывать для каждого полученного байта.

Кроме того, лучше всего делать как можно меньше в обработчике событий DataReceived.Прочитайте любые байты, полученные в ваш буфер, и, возможно, добавьте завершенные сообщения в очередь для дальнейшей обработки, но сделайте немного больше.

Также обратите внимание, что standard максимумспецификация RS232 - скорость 19200 бод и длина кабеля 50 футов.Все, что выше этого, не определено.Для более высоких скоростей обычно требуется более качественный кабель (меньшая емкость) и более короткая длина кабеля.Убедитесь, что он экранирован и не работает рядом с другими «шумными» объектами, такими как двигатели, инверторы двигателей, кабели под напряжением и т. Д.

3 голосов
/ 31 декабря 2010

Когда установлена ​​высокая скорость передачи данных, следует ли ожидать потери данных? если да, то почему?

Не обязательно. Это может произойти из-за плохого физического соединения (слишком длинное).

Я устанавливаю размер считывающего буфера как 100 *1024* 1024

Этого должно быть (кстати) более чем достаточно.

Сказав, что зацикливание и чтение отдельных байтов - не самый эффективный способ чтения порта.

Вы можете подключиться к событию DataReceived и установить ReceivedBytesThreshold = 12. Таким образом, вы всегда можете просто прочитать (Buffer, 0, 12)

...