Связь через последовательный порт в .NET - PullRequest
4 голосов
/ 03 июня 2010

Я использую C # для получения данных от последовательного порта, но есть некоторые проблемы. Я новичок в этом, поэтому мне нужна помощь.

  1. Прежде всего, я хочу знать, какие функции управляются событиями:

    ReadExisting()
    Read()
    Readbyte() 
    Readchar()
    ReadLine()
    Readto()
    
  2. Как я могу взять необходимые данные из входного потока этого порта?

    У меня есть протоколы статического размера. Могу ли я использовать специальный символ для указания пределов данных протокола, и какой из них будет подходящим для этого?

  3. Как мне обработать это исключение:

    C # SerialPort System.ObjectDisposedException, безопасный дескриптор закрыт в System.DLL

Ответы [ 2 ]

7 голосов
/ 03 июня 2010

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

например. если ваш протокол сообщений имеет длину 20 байтов, событие DataReceived срабатывает, и вы пытаетесь прочитать 20 байтов. Они все могут быть там, они не могут. Вполне вероятно, что они не будут, в зависимости от вашей скорости передачи.

Вам необходимо проверить свойство BytesToRead порта, с которого вы читаете, и прочитать это количество в свой буфер. Если и когда будет доступно больше байтов, событие DataReceived будет запущено снова.

Обратите внимание, что событие DataReceived будет запущено, когда число байтов для приема будет, по крайней мере, равно свойству ReceivedBytesThreshold последовательного порта. По умолчанию я считаю, что это значение равно 1.

Если вы установите это значение, например, равное 10, событие сработает, когда ожидается получение 10 или более байтов, но не меньше. Это может вызвать или не вызвать проблемы, и я лично предпочитаю оставить значение этого свойства равным 1, чтобы все полученные данные инициировали событие, даже если получен только 1 байт.

Не допускайте ошибки в том, что это вызовет событие для каждого полученного байта - он этого не сделает.

7 голосов
/ 03 июня 2010

Ни один из этих методов не является "управляемым событиями", вы бы использовали их в событии DataReceived. Который вызывается, когда последовательный порт имеет хотя бы один байт данных, доступных для чтения.

Не уверен, что означает "статический размер". Если устройство отправляет фиксированное количество байтов, вы должны использовать метод Read () для их чтения. Обратите внимание на возвращаемое значение, вы получите столько байтов, сколько доступно. Сохраните их в байте [] и добавляйте к нему в следующем событии DR, пока не получите их все.

Если устройство отправляет символы, а не байты, обычно вы можете воспользоваться свойством NewLine. Установите его в символ или строку, которая завершает ответ. Перевод строки ("\ n") является наиболее типичным выбором. Прочитайте ответ с помощью ReadLine (). В этом случае буферизация не требуется.

Вы получите исключение ObjectDisposed при закрытии формы, но не гарантируете, что устройство прекращает отправку данных. Обязательно используйте только BeginInvoke в событии DataReceived, а не Invoke. И не вызывайте BeginInvoke, если свойство IsDisposed формы имеет значение true.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...