Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » .NET - с# - не могу понять принцип чтения com-порта

Ответить
Настройки темы
.NET - с# - не могу понять принцип чтения com-порта

Новый участник


Сообщения: 8
Благодарности: 0

Профиль | Отправить PM | Цитировать


Здравствуйте. Имеется устройство, оно принимает от меня пакет данных (6 байт), и отправляет ответ - 28 байт.
Не могу понять как организовать чтение?
на данный момент на форму брошены 2 кнопки - нажимаю на первую, происходит :
Код: Выделить весь код
byte[] a = { 0x02, 0x4B, 0x00, 0x12, 0x04, 0x01 };
port.Open();
port.Write(a, 0, a.Length);
Соответственно вторая кнопка - чтение :
Код: Выделить весь код
byte[] b = new byte[28];
port.Read(b, 0, b.Length);
Клацаю на первую, после на вторую - все читается и обрабатывается.
Но(!) - если запихать это в одну процедуру - то ничего не получается, т.к. устройству нужно 600 мс для посылки ответа, т.е. в буфер для чтения попадают нули, 28 байт 0x00 - пустой буфер, т.к. устройство попросту не успевает прислать ответ.
Как правильно поступить в этом случае?
Могу предположить установить паузу, но это - костыль.
Как правильно выходить из данной ситуации?

Отправлено: 16:33, 02-12-2013

 
pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Варианты:
1. (самый простой) синхронное чтение (либо просто увеличь таймаут), читай сразу 28 байт.
2. если железяка поддерживает аппаратную синхронизацию - включи (и в настройках порта тоже)
3. если железяка поддерживает программную синхронизацию (xon/xoff) - включи в настройках порта
4. если железяка в любом случае шлёт 1-й байт определённый (например 27), укажи его в настройках как event char

Первый вариант подходит в 99.9% случаев

С таймаутом тоже неплохо. Особенно если совместить с поллингом
Это сообщение посчитали полезным следующие участники:

Отправлено: 18:06, 02-12-2013 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 8
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата pva:
Варианты:
1. (самый простой) синхронное чтение (либо просто увеличь таймаут), читай сразу 28 байт. »
А как читать сразу 28 байт? Я вроде так и делаю :
Код: Выделить весь код
byte[] b = new byte[28];
port.Read(b, 0, b.Length);
Поднимаю таймаут до 1000мс - в массиве байтов все 0x00

Да, я заранее знаю, какие байты будут идти первыми, и кол-во байт.
Поищу завтра event char

Последний раз редактировалось Carmageddon, 02-12-2013 в 18:27.


Отправлено: 18:22, 02-12-2013 | #3

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


покажи как настройки порта выставляешь

Отправлено: 10:42, 03-12-2013 | #4


Новый участник


Сообщения: 8
Благодарности: 0

Профиль | Отправить PM | Цитировать


Код: Выделить весь код
SerialPort MyPort = new SerialPort("COM2", 9600, Parity.Even, 8, StopBits.One);
MyPort.ReadBufferSize = 1024;
MyPort.WriteBufferSize = 1024;
MyPort.WriteTimeout = 1000;
MyPort.ReadTimeout = 1000;

Отправлено: 11:43, 03-12-2013 | #5

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Основываюсь на http://msdn.microsoft.com/ru-ru/libr...vs.110%29.aspx
глупый хелп, конечно. Совсем обленился микрософт.
Если не забываешь сделать Open(), то попробуй:
1. поотключать аппаратное управление портом
2. вызови 28 раз сподряд ReadByte(). Про неё точно написано что она синхронная. Если заработает - значит используй её либо ищи как работать асинхронно

вот такая штука может быть полезной:

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

Отправлено: 14:01, 03-12-2013 | #6


Новый участник


Сообщения: 8
Благодарности: 0

Профиль | Отправить PM | Цитировать


Цитата pva:
2. вызови 28 раз сподряд ReadByte(). »
Вроде сработало - данные пришли как нужно, но в полном масштабе не тестировал
Дополню таким фактом - при чтении Read() - в портмоне данные приходят (видны) как одна строка. В текущем случае, они видны как один байт на строку (что вполне понятно, т.к. читаю 28 байт в цикле). Но визуально в портмоне данные читаются блоками по 14 байт, между блоками некая задержка.
P.s. - когда читает родная утилита железяки, данные в портмоне видны "одной строкой"
Что ж за странность - читает 14 байт, ложит в массив и небольшая задержка, и дальше читает по 14 байт. Цикл то крутиться на 28
Вот, взгляните (картинка в хайде) :




Цитата pva:
вот такая штука может быть полезной:
ReceivedBytesThreshold »
Да, кстати, очень хороший вариант.
Однако, стоит заметить о многочисленных отзывах, и официальной информации с msdn - что сие событие не обязано срабатывать на каждый полученный байт. Вдруг мой 28й байт как раз станет тем самым. А после него данные не приходят, соответственно событие уже не сработает .
буду тестировать вариант с циклом.

P.s.s. уважаемый pva, а подскажите пожалуйста, где мне просвятиться, о том, что есть "синхронный" и "асинхронный режимы" в доступной форме?

Спасибо за Ваши ответы, очень помогли

Отправлено: 15:11, 03-12-2013 | #7

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Скажу честно, я не знаю. Отвечал на основе опыта работы с портом в C/C++. Принцип примерно такой:
к порту прицеплен драйвер, который держит очередь ввода-вывода и запуливает в порт данные с его скоростью (и читает обратно)
Всё это работает в соседнем процессе, значит можно помещать данные в очередь (пишем в порт) или снимать их оттуда (читаем порт) с небольшими задержками (чтобы не переполнить очередь), и заниматься своими делами. Видимо в этом и вся асинхронность.
здесь написано про настройки драйвера:
http://msdn.microsoft.com/en-us/library/bb202767.aspx
http://msdn.microsoft.com/en-us/library/aa909018.aspx

Это всё как-то намаплено на классы C# - ищи похожие названия

Отправлено: 18:50, 03-12-2013 | #8


Новый участник


Сообщения: 8
Благодарности: 0

Профиль | Отправить PM | Цитировать


Прочел ряд статей - насколько я понял, все для ПК по rs232 работает в асинхронном режиме - режиме, где единицей передачи информации является байт, т.е. каждый байт имеет старт и стоп биты, и как правило бит четности.
В противоположность ему, есть более быстрый - синхронный режим, когда поток бит идет непрерывно, но rs232 его не поддерживает.
буду пробовать

Отправлено: 19:39, 03-12-2013 | #9

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Carmageddon, не в этом смысле! Имеется в виду дожидается ли функция результата (синхронный режим) или возвращается сразу, а результат получается полингом, ожиданием события или обратным вызовом (асинхронный режим). Синхронность в межпотоковом смысле.

Отправлено: 20:39, 03-12-2013 | #10



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » .NET - с# - не могу понять принцип чтения com-порта

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Помогите тупому понять принцип сетевой коммуникации... Мутаген Хочу все знать 18 26-08-2013 21:38
Не могу понять... BlackPower Хочу все знать 3 10-10-2012 08:04
Не могу понять что с ним angelartem Непонятные проблемы с Железом 2 19-10-2011 22:05
[решено] Не могу понять причину Triplex Непонятные проблемы с Железом 16 24-05-2007 14:45
Не могу понять. slaine Вебмастеру 2 24-12-2004 09:59




 
Переход