Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.10.02;
Скачать: CL | DM;

Вниз

Проблемы с портом   Найти похожие ветки 

 
Замученный ©   (2003-07-15 14:57) [0]

Уважаемые граждане, помогите пожалуйста.

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

Проблема в следующем. При посылке ему какой-то команды, перед ответом возникает определенная задержка, которой в принципе быть не должно (смотрел по осциллографу). Задержка где-то около 46 мсек. Это мешает работать.

В работе использовал различные компоненты для работы с портом. Везде тот же результат.
Что можно сделать??? Заранее благодарен.


 
Kostya ©   (2003-07-15 15:37) [1]

Есть в инете модуль sadirectport -отличная вещь
нет проблем


 
Замученный ©   (2003-07-15 15:45) [2]

А что же делать с задержкой??? и где найти это модуль???


 
Лёша   (2003-07-15 17:48) [3]

Задержка - понятие растяжимое!
Где задержка?


 
jack128 ©   (2003-07-16 11:02) [4]

Замученный © (15.07.03 14:57) В смысле задержка? Между запросом и ответом? и правильно, Ведь должно твое устройство подумать, что ответить..


 
Замученный ©   (2003-07-16 11:26) [5]

Задержка между запросом и ответом.

Так устройство отвечает сразу же после посланной ему команды. Проверял на осциллографе.

Может вставку на асме сделать? Может поможет? Если кто код знает, помогите please, а то горю совсем. Буду благодарен за любую инфу


 
pasha676   (2003-07-16 12:54) [6]

Что задержка будет это понятно (правда должна быть махонькая, в пределах 2-3 мс а то и меньше). Непонятно чем она тебе мешает. Кстати как общаешься с устройством? Может задержка в коде.


 
Лёша   (2003-07-16 14:00) [7]

То, что ты проверил на осциле, ничего не значит. Проверь PortMonitor"ом или другой гляделкой порта. Если убедишься, что обмен данными имеет место и данные корректны, проверь/настрой таймауты порта: COMMTIMEOUTS (GetCommTimeouts/SetCommTimeouts). Если не поможет, сообщи, будем копать дальше.


 
Замученный ©   (2003-07-16 15:24) [8]

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

Проверил PortMonitor"ом, обмен данными имеет место.
Что касается таймаутов то они такие (использую свойство TimeOuts компонента ComPort Library):
ReadInterval = 0;
ReadTotalConstant = 0;
ReadTotalMultiplier = 0;
WriteTotalConstant = 0;
WriteTotalMultiplier = 0;


 
pasha676   (2003-07-16 16:52) [9]

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


 
Замученный ©   (2003-07-16 16:59) [10]

Так откуда берется задержка, может быть это проблемы с системой и так должно быть


 
Verg ©   (2003-07-16 17:40) [11]

Win32 - это не система реального времени и требовать какого-либо времени реакции приложения на событие нельзя.
Это в общем.
А потом, уточни все же между чем и чем задержка? Между тем как пролетел байт (по осцилу) и он "упал" в апликуху? Как ты мерял эту задержку?


 
jack128 ©   (2003-07-16 19:44) [12]

Мне тоже интресно как можно замерить такую задержку...
И кстати укажи скорость и размер посылки от устройства, а то если скорость 300 bps и посылка в 10 байт, то около 30 мс и выходит ;-)


 
Лёша   (2003-07-16 20:31) [13]

Попробуй:
ReadInterval := 100;
ReadTotalConstant ( см. MSDN "Serial Communications Functions") Попробуй:
ReadInterval := 100;
ReadTotalConstant := 100;
ReadTotalMultiplier := 100;
WriteTotalConstant := 100;
WriteTotalMultiplier:= 100;

когда присвоены значения "0" - таймауты не используютсья вообще. Кто знает, как работает твоя компонента, может это его сбивает. А лучше перепеши на WIN32 API - четко, быстро, без глюков и отладить легко. (см. MSDN "Serial Communications Functions")


 
pasha676   (2003-07-17 09:06) [14]


> WIN32 API - четко, быстро, без глюков и отладить легко

Помоему это тоже выход. Во всяком случае контроля больше. Ведь не известно что там в компоненте понаписано.


 
Замученный ©   (2003-07-17 13:35) [15]

Verg Задержка возникает между тем как была послана команда устройству и получен ответ в приложении. Задержку мерял сл. образом. Измерял время, после отправки и перед приемом, затем находил разницу.

Что касается скорости то она 2400 bps. Посылка 8 байт, 2 стопа.

Попробую сейчас покапаться в MSDN "Serial Communications Functions", может что и поможет. Если у кого есть код, буду рад принять.


 
Замученный ©   (2003-07-17 14:05) [16]

Пробовал

ReadInterval := 100;
ReadTotalConstant := 100;
ReadTotalMultiplier := 100;
WriteTotalConstant := 100;
WriteTotalMultiplier:= 100;

После первого запуска 37 мс, а затем опять 46 мс. Что за чертовщина??? Может во всем виноват XP?


 
Лёша   (2003-07-17 14:53) [17]

Так я и не понял где задержка...

| | | ( RS232) Так я и не понял где задержка...

| | | |
| [ПО] <-> [порт] <---> (RS232) <-> [порт] <-> [ПО] |
| | | | | | |
| | |
| |__________________ |
| _________T1_______||
| |
|______________________________ |
___________T2_________________|

Почувствуй разницу и проверь еще раз значение своей задержки!
1.
>Verg Задержка возникает между тем как была послана команда
>устройству и получен ответ в приложении. Задержку мерял сл.
>образом. Измерял время, после отправки и перед приемом,
>затем находил разницу.
T2
2. Т1
3. другие варианты



 
Замученный ©   (2003-07-17 15:30) [18]

Приведу кусок кода, может поможет

Procedure TForm1.Tik;
Begin

ComPort1.Open; // Открываю порт

// Подготавливаю данные для отправки
dim_send[0]:= ord(chr(StrToInt("1")));
dim_send[1]:= ord(chr(StrToInt("$90")));
dim_send[2]:= ord(chr(StrToInt("0")));

// Отправляю 3 байта в порт
ComPort1.Write(dim_send,3);
End;

procedure TForm1.Button1Click(Sender: TObject);
Var
i,k:integer;
begin
// Щелкаем на кнопке, оправляем данные в порт и замеряем время
Tik;
Time1:=Time;
end;

// В порт что-то пришло, принимаем

procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
var i,p:byte;
begin
// Измеряем время и декодируем его. Далее находим MSec2-MSec1
Time2:=Time;
DecodeTime(Time1,Hour1,Min1,Sec1,MSec1);
DecodeTime(Time2,Hour2,Min2,Sec2,MSec2);

// Принимаем данные
ComPort1.ReadStr(Answer,3);
end;

В итоге MSec2-MSec1 = 46


 
pasha676   (2003-07-17 15:43) [19]

так время замерять не совсем коректно. Особенно в виндах.
Где по твоей проге тратиться время?
Ты перед отправлением запоминаешь время. Символы бегут в компорт, оттуда в девай, девайс думает, девайс отвечает, символы ответа приходят в ком порт, генериться сообщение, сообщение генерит эвент ComPort1RxChar, тут ты опять запоминаешь время. Тебе не кажеться что ты меряешь время всего цикла?


С момента прихода символа, до вваливания в обработку ComPort - вот время задержки виндоуз. Где оно у тебя считается? И я не знаю.


 
Замученный ©   (2003-07-17 16:11) [20]

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

Как же я буду проверять, какой сигнал от него пришел, не используя эвент ComPort1RxChar? Вот я и смотрю, сколько времени требуется, чтобы сигнал дошел до девайса и получен ответ, чтобы его обработать в проге.

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

Эвент ComPort1RxChar возникает, как только в порт приходит символ.
Пробовал не использовать этот этот эвент. Считывал данные постоянно - та же самая ситуация.


 
jack128 ©   (2003-07-17 16:12) [21]


> После записи каждого коэфф. устройство сообщает, что процесс
> записи коэфф. закончился удачно и ждет след., если он не
> приходит (в течение 10 мс.)выскакивает ошибка



> Что касается скорости то она 2400 bps. Посылка 8 байт, 2
> стопа.
.
Предположу, что у тебя dcb.ByteSize := 8; тогда (8 бит + 2стоп бита + 1 старт бит)*8 байт ответа от устройства/2400 bps = 88/2400 = 0,036 = 36 мс, а тебе нужно еще второй коэфициэнт отправить, тебе не кажется, что ты ну никак не успеваешь? 10 мс это уж ОЧЕНЬ мало для таких скоростей




 
Замученный ©   (2003-07-17 16:53) [22]

Формат посылки - 11 бит: старт-бит(ноль), 8 бит данных, два стоп бита (единица), контроль по четности отсутствует.

В качестве теста выбрана команда $90 - проверка связи.
После распознавания этой комамнды девайс сразу же(без задержки) передает на ЭВМ трехбайтовое сообщение с кодом ответа $90.

Т.о., если я правильно понимаю имеем:

(8 бит + 2стоп бита + 1 старт бит)*3 байта ответа от устройства/2400 bps = 33/2400 = 0,00125 = 1,25 мс.

Я же имею 47 мс.


 
jack128 ©   (2003-07-17 17:19) [23]


> 33/2400 = 0,00125

Купи колькулятор полудше :-)


 
jack128 ©   (2003-07-17 17:25) [24]

И все таки по поводу времени, ты учти что эти формулы учитывают только физическую передачу сигнала через канал связи и не учитывают что винда думает, переходные процессы в приемопередатчике (UART - так он на буржуйском завется?)идут, устройство тотже думает, UART устройства тоже тупит ;-) и все это вместе дает твои 50 мс...


 
Замученный ©   (2003-07-17 17:43) [25]

jack128 Извиняюсь, облажался :(((

Так что можно что-то сделать или нет, как ты думаешь?


 
Лёша   (2003-07-17 19:58) [26]

...да, затянулась ветка!
...а главное без толку...


 
jack128 ©   (2003-07-18 00:32) [27]


> Так что можно что-то сделать или нет, как ты думаешь?

ИМХО, нет (покрайней мере не под Windows). Если есть доступ к разработчикам устройства, то заставь их переписать программу контроллера (или пусть сами приведут пример рабочей программы)


 
pasha676   (2003-07-18 10:13) [28]

Что бы написать такой контроллер в девайсе, как задержка в 50мс и все падает (особенно при записи параметров), надо быть не совсем нормальным (особенно когда идет обмен по схеме "запрос-ответ"). Есть версия, что ты что то не то пихаешь в контроллер.


 
Замученный ©   (2003-07-18 12:57) [29]

Пихаю я то, иначе бы он отвечал неправильно


 
Verg ©   (2003-07-18 14:42) [30]

Под NT (2000) можно попробовать задрать приоритет процесса и потока:
SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);


Только работать в таком потоке надо крайне аккуратно: для ввода с порта никакого полинга, только overlapped io+waitxxxxxx и т.п., а то повесишь все остальные потоки...

Может поможет, может нет - все зависит от того будут ли и сколько будет запущено еще таких же "умников" с REALTIME_PRIORITY_CLASS/THREAD_PRIORITY_TIME_CRITICAL.

А реально - только модернизацией самого устройства. Время-ориентированные протоколы обмена мало подходят для простых смертных приложений под винды. Либо писать специальный драйвер уровня ядра.



 
Замученный ©   (2003-07-18 14:46) [31]

Читал, что можно работать с портом напрямую с помощью giveo.sys. Но как это делать не знаю. Может кто знает??


 
N169   (2003-07-18 17:15) [32]

>с портом напрямую ... giveo...

нет, мужик, тока хуже будет. Ибо теряем буферизацию --> вероятность потери данных увеличивается.
К тому же конфликтность с serial.sys


 
jack128 ©   (2003-07-18 21:57) [33]


> Verg © (18.07.03 14:42)


> Может поможет, может нет - все зависит от того будут ли
> и сколько будет запущено еще таких же "умников" с REALTIME_PRIORITY_CLASS/THREAD_PRIORITY_TIME_CRITICAL.

Самое смешное что системные процессы работают с меньшим приоритетом и к чему приведет такое положение вещей одному Гейтсу известно..


 
AlexR ©   (2003-07-19 23:05) [34]

>Читал, что можно работать с портом напрямую с помощью giveo.sys. Но как это делать не знаю. Может кто знает??

goveio точно не поможет. Может драйвер попробовать? Но это не так-то просто.


 
Verg ©   (2003-07-20 09:52) [35]


> jack128 ©


Если поток будет грамотно работать, то ни к чему плохому не приведет, а если while true do; то энтя умрет вплоть до ресета.


 
CaveDweller ©   (2003-07-20 12:54) [36]

Если такая задержка - то это похоже на таймер в компоненте, который каждые 50мс ходит в порт за данными. Я в своё время использовал API - функцию WaitCommEvent, которая возвращает управление сразу по событию в порте. Понятное дело, что функция запускалась в отдельном потоке. Думаю, что стоит попробовать API, тем более, что не так оно и сложно.


 
jack128 ©   (2003-07-20 14:21) [37]


> API - функцию WaitCommEvent,

ИМХО очень неудобно..Возиться с асинхронными операциями....И потом здесь это не поможет, почитай выше...



 
AnS   (2003-07-20 15:10) [38]

Работал я с компонентом ComPort Library (писал программу обмена данными с ЭККА ЭРА-201). Компонент отличный и работает прекрасно.
Вопрос такой: твой девайс выдает что-то типа XOFF после приема пакета от тебя и XON после обработки пакета и ответа на него?


 
Замученный ©   (2003-07-21 13:02) [39]

>твой девайс выдает что-то типа XOFF после приема пакета от тебя и XON после обработки пакета и ответа на него?

Девайсу отсылается команда вида 01 $90 00 (01 - номер устройства, $90 - команда проверки связи) при приеме данной команды должен вернуться ответ 01 $90 00 (команду принял). Именно ее я и получаю.

К тому же при посылке ему других команд, а их около 5, также получаю результат



Страницы: 1 вся ветка

Текущий архив: 2003.10.02;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.015 c
14-4134
Ru
2003-09-12 15:11
2003.10.02
Vy vse i ochen chasto hoteli imet . Tak vot IMEIYTE:


1-3937
Sergiy
2003-09-21 13:45
2003.10.02
Блокировка перевода времени


1-3851
SiJack
2003-09-19 10:21
2003.10.02
Нормальный Popup в Edit


4-4168
Delphi5.01
2003-07-31 05:42
2003.10.02
Fomra na chistom API


1-3965
sword
2003-09-20 10:52
2003.10.02
Как нарисовать таблицу в Richedit e