2010-12-31 3 views
1

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

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

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

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

+2

Что вы делаете, кроме 'ReadByte' внутри цикла while? Сколько времени занимает обработка? –

+0

После прочтения байта из последовательного порта он будет помещен в буфер до тех пор, пока буфер не достигнет 12 байтов. как только он достигнет 12 байтов, он будет сравниваться с определенными командами, которые занимают очень мало времени. – user209293

+1

Вы должны убедиться, что используете управление потоком, если вы еще этого не сделали. –

ответ

3

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

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

я устанавливаю ReadBuffer размер, 100 * 1024 * 1024

Это должно быть (путь) более чем достаточно.

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

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

4

Размер буфера приема 100 * 1024 * 1024 ОГРОМНЫЙ! Я бы серьезно сомневался, что вам нужен этот размер вообще, и, конечно, не для реального буфера последовательного порта.

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

Аппаратный контроль потока (обычно) используется через контакты RTS (Request To Send) и CTS (Clear To Send).

Посмотрите на статью this, в которой объясняется немного больше об этом.

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

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

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

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

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

+1

+1 для рекомендации управления потоком –

+0

Я добавил данные, полученные событием, и установил прием байта thresold на 1. Я заметил, что другие потоки затронуты этим принятым событием. Может ли это случиться? Определено 4 timers.timer, в результате чего происходит событие таймера. Как только последовательный порт принимается, события таймера не срабатывают с заданными интервалами. Это смещение на 1 или 2 секунды. – user209293

Смежные вопросы