Страница 1 из 9

Тонкости работы с COM портом

СообщениеДобавлено: 31.08.2007 18:53:12
serg_iv
Разрабатываю систему, в которой компьютер общается с периферийными устройствами по шине RS485 на скорости 115200 бод.
Ведущим в шине является компьютер, соответственно общение происходит циклически:
запрос устройству 1 - ответ устройства 1
запрос устройству 2 - ответ устройства 2
...
запрос устройству N - ответ устройства N

Работа ведется через компонент Synaser.
Наконец то добрался до вопроса - между ответом устройства n и запросом устройству n+1, внедряется пауза длительностью примерно 3,5 миллисекунды.
Вот отрывок осцилограммы:
ЗУ1_ОУ1________________ 3,5мс ________________ЗУ2_ОУ2___________

где ЗУ-запрос устройству
ОУ-ответ устройства

и код который выполняется в отдельном потоке

Код: Выделить всё
...
ser:=TBlockserial.Create; //создаем устройство
ser.RaiseExcept:=false;   //не обрабатываем исключения ошибок связи
ser.Connect('com2');      //соединяемся с портом
ser.Config(115200,8,'N',0,false,false);//настраиваем скорость, стоп биты, паритет

repeat
ser.SendInteger((_data[1] shl 0)or(_data[2] shl 8)or(_data[3] shl 16)or(_data[4] shl 24));
ser.RecvInteger(1);//очистка приемного буфера
a:=ser.RecvByte(1);//читаем ответ

until Terminated;
ser.Free;
end;


Откуда берется пауза в 3,5 миллисекунды?
И как от нее избавиться? (Если это конечно возможно...)

СообщениеДобавлено: 31.08.2007 22:23:10
Sergei I. Gorelkin
Исходных данных явно не хватает. Чему равны таймауты на чтение? Если ответ устройства состоит из одного байта, зачем перед ним вхолостую читать четыре? Естественно, прочитав один байт, оно будет ждать дальше, пока не отвалится по таймауту...

СообщениеДобавлено: 01.09.2007 18:21:06
serg_iv
Если ответ устройства состоит из одного байта, зачем перед ним вхолостую читать четыре?

Конвертер RS232 -> RS485 устроен таким образом, что при посылке данных в шину их читает приемник USART'а компьютера. Читая вхолостую 4 байта очищаю приемный буфер. 5-ый байт - данные от устройтства.

СообщениеДобавлено: 01.09.2007 20:02:15
Sergei I. Gorelkin
Ага, уже понятнее... Тогда - я бы засек время между запросами и выяснил, который из них троих вносит задержку.
Данные правильно принимаются? В смысле, нет ли, например, такого, что в ответ на запрос N приходит ответ не N, а N-1 ?

СообщениеДобавлено: 02.09.2007 18:27:57
serg_iv
Запросы принимаются нормально, как я понял по осцилограмме задержка получается между функциями RecvByte и SendInteger. Задержка одинаково проявляется как в Винде так и в Мандриве.

СообщениеДобавлено: 02.09.2007 19:30:48
Sergei I. Gorelkin
По осциллограмме понятно, но что происходит в программе? RecvByte тормозит после принятия байта, или SendInteger чего-то ждет перед тем, как отправить, или еще что-нибудь?

СообщениеДобавлено: 02.09.2007 19:47:27
serg_iv
По осциллограмме понятно, но что происходит в программе? RecvByte тормозит после принятия байта, или SendInteger чего-то ждет перед тем, как отправить, или еще что-нибудь?

Как раз этого я и не могу понять...
Если вызываю SendInteger несколько раз подряд, например в цикле, то передача слитная.
После того как включаю RecvByte, при следующей передаче прохоисходит задержка.

СообщениеДобавлено: 28.10.2007 12:03:37
Demetrio
Как правило, при приёме передаче данных аппаратура вносит свои задержки. Кроме того, может иметь значительное время переключение с передачи на прием и обратно. Диапазон 3-6 мс это совершенно нормальное явление в работе устройств по RS485.

СообщениеДобавлено: 28.10.2007 19:11:03
serg_iv
Как правило, при приёме передаче данных аппаратура вносит свои задержки. Кроме того, может иметь значительное время переключение с передачи на прием и обратно. Диапазон 3-6 мс это совершенно нормальное явление в работе устройств по RS485.

Уже переделал логику обмена данными. За ответ - спасибо, не знал об этом.

СообщениеДобавлено: 20.11.2007 19:19:09
swa1
Вопрос по synaser

У меня выявился какой то непонятный баг:
Вначале все честно-
Создаю устройство, подключаюсь к занятому порту - выдает ошибку -LastError = 5 (Отказ в доступе) закрываю устройство.
Опять все заново, но только подключаюсь к незанятому порту, работаю, отключаюсь.
Повторяю попытку подключения к занятому....Подключаюсь. Ошибок НЕТ.. :( . (Т.е.LastError=0) И только при попытке записать что либо в порт - отбивает - Access violation.

Пытался ставить дополнительно при открытии проверку( Except) не помогает....

Может я что не так делаю?

СообщениеДобавлено: 21.11.2007 09:56:40
Attid
ОС ?
хотя у меня под линем что-то не понятное было но там и железо не совсем стандартное, списал на дрова, так как в исходниках вроде все нормально, и после того как ошибки с железом были поправлены костыликами вроде все стало ок. но у меня демон работает, он подключается к порту 1 раз при загрузке и не отпускает его больше.

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

СообщениеДобавлено: 21.11.2007 11:49:24
swa1
Attid писал(а):ОС ?

Сейчас в win....
Attid писал(а):там откатились на дельфевую версию

Вобще то, что я пытаюсь изобразить, уже написано в дельфях и прекрасно работает. Выбор FPC и Lazarus, а так же библиотеки synaser - это для будущего безболезненного перехода по nix-ы (по крайней мере, я на это надеюсь). А пока не перешли, все разработки приходится вести в windows. Причем задежка перехода именно в этих программах которые я и пытаюсь переписать.

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

СообщениеДобавлено: 21.11.2007 13:30:29
Attid
swa1
ты раскажи что ты хочешь. может можно проще =)

почему порты могут быть заняты ? кроме твоей проги с теми же портами работают другие ? их (портов) может быть много для твоей задачи? и т.д.

нескромный вопрос а InstanceActive проверяешь перед записью в порт ?

СообщениеДобавлено: 21.11.2007 18:19:26
swa1
Attid писал(а):что ты хочешь.

В двух словах: Грубо, это терминал(ы) работающий(ие) одновременно с несколькими устройствами через com порт. В основном следим, временами пишем. На одном ПК может быть задествовано от 1 до 8 или даже 10 портов (мультипортовая карта на 8 + 2 родных).

Attid писал(а):почему порты могут быть заняты ?

1-Потому что его использует другая программа .
2-Потому что его уже заняла эта же программа .

Attid писал(а):а InstanceActive проверяешь

Нет....Не проверял, но чуть позже попробую :oops: .
Вобще то я так ....начинающий. В свое время, когда создавалась ПО на дельфи под эту трехомудию, я был малость приобщен к этому процессу.
Мне показали как работать в дельфях, дали исходники ... А сейчас никак не могу уговорить авторов перевести все под линь, поэтому решил разбираться сам. Практики почти никакой, так... налобал несколько прикладных програмок для облегчения своей жизни и все, да и то половина писалась еще на бейсике

СообщениеДобавлено: 21.11.2007 18:37:32
swa1
Проверил....
В первый раз при обращении к занятому порту InstanceActive=False .
Подключаюсь к свободному, работаю, отключаюсь. Подключаюсь опять к занятому...InstanceActive=True :(
Может мне выложить исходник тестовой програмки с которой я и ковыряюсь?