Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проверка очереди Com порта неработает. [D7, Win95/98]


Kolan ©   (2005-07-19 12:45:00) 

Проблема вот в чём:
 Хочу считать всё что есть в буфере. Для чего написал процедуру:

function TStringWriteComm.ReadWholeBufferAsString: string;
var
 Queue: Integer;
 Buffer: array of Byte;
 I: Integer;                    
begin
 Queue := DataInBuffer;
 SetLength(Buffer, Queue);
 Read(Buffer, Queue);
 Result := '';
 for I := Low(Buffer) to High(Buffer) do
 begin
   Result := Result + Chr(Buffer[I]);
 end;
end;


и
function TStringWriteComm.DataInBuffer: Integer;
var
 ComStat: TComStat;
 lpErrors: DWORD;
 Handle: THandle;
begin
   Handle := ComPort;
   if ClearCommError(Handle, lpErrors, @ComStat) then
   begin
     Result := ComStat.cbInQue;
   end
   else
     Result := 0;
end;


Но вот интересно. Если запустить это дело то в очереди ничего нет(те DataInBuffer возвращает 0). Если ставить точки останова до или после строки Queue := DataInBuffer;тоже самое причем сколько раз не повторяй(пробовал в цикле).

А если пройтиси пошагово или поставить BreakPoint на эту строку то всё OK и в очереди данные есть. Данные в порте точно есть.

Если убираю проверку очереди и читаю напямую, то тоже свё нормально. Вчём может быть проблема.

Кстати если сделать
Sleep(10);
Queue := DataInBuffer;

То работает тоже. почему так?

PS решение Sleep(10);мне не подходит.


tesseract   (2005-07-24 19:53:00) [1]

PS. А мож есть такое сообшение системы возникающее когда что-то
приходит в порт?

>>> WaitCommEvent с EV_RXCHAR not EV_RING

Я сдесь в каком-то посте исходник передавал, пошукай


Digitman   (2005-07-20 12:43:00) [2]


> мож есть такое сообшение системы возникающее когда что-то
> приходит в порт?


сообщения нет, но зато с ком-портом можно работать в асинхронно, в overlapped-режиме по событиям

под НТ есть Read/WriteFileEx - эти ф-ции, кр.всего того что делают Read/WriteFile, позволяют еще и организовать нотификацию о событиях ввода/вывода вызовом колбэк-функции


Kolan   (2005-07-20 12:32:00) [3]


> А ты почему не анализируешь lpErrors после возврата из ClearCommError()
> ?

Сделал в примере [6] ответ такой
Queue = 0; S = 'w' lpErrors = 0;


> что за дивайс к порту подключен ?
> или у тебя лупбэк организован для целей отладки ?


Работаю с RS-485; Есть преобразователь RS-232 <-> Rs-485. У него есть эхо. Я шлю команду получив эхо устанавливаю RST и читаю ответ.

Работая над проектом возникла идея, хотел узнать у вас можно ли вообще такое сделать:

1:
Имеется два потока. Один (может и главный) убирает RTS и шлёт команды, а второй выгребает всё что есть в потре и анализирует. Если встретил эхо то еще и включает RTS.

2: Почти тоже самое, но эхо проверяет первый поток и он влючает RTS, а второй только забирает всё что приходит и парсит.

PS. А мож есть такое сообшение системы возникающее когда что-то приходит в порт?

С уважением,
 Kolan


Digitman   (2005-07-20 10:37:00) [4]

А ты почему не анализируешь lpErrors после возврата из ClearCommError() ?


> S = 'w' Значит очередь всеже не пустая так как пришел ответ.


что за дивайс к порту подключен ?
или у тебя лупбэк организован для целей отладки ?


Kolan   (2005-07-19 16:09:00) [5]

Попробую обяснить чего я не понимаю.
Тестовый пример:
begin
 ComPort.WriteString('w');
 K := 0;
 for I := 1 to 1000 do
 begin
   Queue := ComPort.DataInBuffer;
   K := K + 1;
 end;
 K := 0; (*)
end;


Break на (*). Queue = 0; Значит за 1000 проверок очередь не изменилась.

begin
 ComPort.WriteString('w');
 K := 0;
 for I := 1 to 1000 do
 begin
   Queue := ComPort.DataInBuffer;
   S := ComPort.ReadAsString(1);
   K := K + 1; (*)
 end;
 K := 0;
end;

Break на (*). Queue = 0; S = 'w' Значит очередь всеже не пустая так как пришел ответ.

Во втором тесте ответ был уже на первом шаге цикла.
А первый тест показал, что очередь равно 0 всё 1000. Как так?


Digitman   (2005-07-19 15:13:00) [6]

в период между остановом на брейкпойнте и последующим F7 (этот период вряд ли будет менее сотен м/секунд) поступили данные в приемный буфер порта, их ты и получил нажав F7


Kolan   (2005-07-19 13:46:00) [7]

Да нет есть. Это эхо ответ.
Как понять вот это

Queue := ComPort.DataInBuffer; (**)
 ComPort.Read(Buffer, Length(S));
 Echo := ArrayToString(Buffer);
(*)

Ставлю BreakPoint на (*) и вижу Queue = 0;А в
Bufferпрочитанно 4 байта?

Ставлю BreakPoint на (**) иду по F7 и в Queue4 байта?


Digitman   (2005-07-19 13:37:00) [8]


> в том и дело что Queue равно 0.


значит в этот момент действительно нет актуально приянятых данных


Kolan   (2005-07-19 13:33:00) [9]

Так в том и дело что Queueравно 0.
А если пошагово иду то нет.
Или вот шас для того чтобы продолжить работу заменил просто на чтение без проверки и читает нормально.


Digitman   (2005-07-19 13:05:00) [10]

Queue := DataInBuffer;
if Queue > 0 then ..


Наверх

Титульная страница Поиск, карта сайта Написать письмо