![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проверка очереди 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 ..