Форум: "Система";
Текущий архив: 2003.01.16;
Скачать: [xml.tar.bz2];
ВнизПомогите с логикой Найти похожие ветки
← →
AndrewK (2002-11-03 00:50) [0]Доброго времени суток, господа.
Помогите, пожалуйста, определить логику работы. Сроки жмут очень.
Есть устройство, которое по сигналу, передаваемому из модема, передает в него пакет своего состояния. Этот пакет должен быть прочитан и обработан. С этим проблем нет.
Мне хотелось бы услышать Ваше мнение о том как надо организовать сей процесс. Именно процесс дозвона по телефону, передачу строки "XXXX", которая является сигналом к передаче данных и прием данных. Если на передачу сигнала "XXXX" не пришел никакой пакет, то надо повторить его еще раз (всего раза 3). Если пакет был принят, но расшифровался не правильно, то снова запросить его (тоже ограниченное число раз).
У меня был такой алгоритм:
1) Дозвон
4) Если не получилось, то повторить дозвон. Если не получилось три раза, то выйти и сообщить об ошибке.
5) Если сообщение установлено, то послать "XXXX".
4) Ждать 5 сек
5) Проверить, пришел ли информационный пакет
6) Если не пришел, или расшифровался не верно, то послать "XXXX". До трех раз
7) Разорвать связь если все хорошо.
Работаю с пакетом Async32. Использую TVAComm и TVAModem.
Проблема в том, как мне расписать такой алгоритм по событиям, которые возникают в этих компонентах.
Вот процедура, которую я пытался использовать при обработке этой задачи.
function TfrmMain.SendPacketOnStation (aBRPhone : Integer; aPacket : TList): Boolean;
var I : Integer;
_Byte : Byte;
SizeOfByte : Integer;
AllDone : Boolean;
CallCounter : Integer;
RepeatPresent : Boolean;
CountRepeatEnabled : Integer;
AttemptCallCount : Integer;
CountRepeat : Integer;
InfoPacketPresent : Boolean;
Byt : Byte;
begin
SizeOfByte := SizeOf(Byte);
CountRepeatEnabled := 3;
AttemptCallCount := 3;
// Соединение со станцией
// Организация дозвона
CallCounter := 0;
repeat
VaModem.Cancel;
Inc(CallCounter);
// Набор номера
VaModem.Dial(IntToStr(aBRPhone));
// Ожидание соединения
Sleep(VaModem.DialTimeout+3000);
until ModemConnected or (CallCounter > AttemptCallCount);
// Если не удалось, то закончить
AllDone := ModemConnected;
if not AllDone then begin
Result := AllDone;
Exit;
end;
// Посылка инициализирующего потока и организация его повтора при необходимости
CountRepeat := 0;
repeat
// Посылка потока
for I := 0 to aPacket.Count-1 do begin
_Byte := Byte(aPacket.Items[I]);
VaComm.WriteBuf(_Byte, SizeOfByte);
end;
// Ожидание запроса на повтор посылки инициализирующего пакета
Sleep(5000);
// Проверка на наличие запроса на подтверждение
RepeatPresent := WordInReceiveBuf ("REPT"); // Проверяет вхождение слова REPT в принятую строку (REPT - Команда на повтор посылки пакета на терминал. Инициируется удаленным устройством)
if RepeatPresent then begin
ClearReceiveBuf; // Здесь очищается буфер приема символов
Inc (CountRepeat);
end;
AllDone := (CountRepeat <= CountRepeatEnabled) or not RepeatPresent;
until AllDone or (CountRepeat > CountRepeatEnabled);
// Если не удалось, то закончить
if not AllDone then begin
Result := AllDone;
Exit;
end;
CountRepeat := 0;
repeat
// Посылка команды на запрос состояния
Byt := Ord("S");
VaComm.WriteBuf(Byt, SizeOfByte);
Byt := Ord("E");
VaComm.WriteBuf(Byt, SizeOfByte);
Byt := Ord("N");
VaComm.WriteBuf(Byt, SizeOfByte);
Byt := Ord("D");
VaComm.WriteBuf(Byt, SizeOfByte);
// Ожидание передачи инфопакета со станции
Sleep(WaitDelayForReplaySendPacket);
// Проверка на наличие запроса на подтверждение
InfoPacketPresent := WordInReceiveBuf ("START"); // Проверяю наличие инфопакета по стартовому слову
if not InfoPacketPresent then begin
ClearReceiveBuf;
Inc (CountRepeat);
end;
AllDone := (CountRepeat <= CountRepeatEnabled) or InfoPacketPresent and InfoPacketIsCorrect; // Проверяю корректность расшифровки пакета
until AllDone or (CountRepeat > CountRepeatEnabled);
// Если не удалось, то закончить
if not AllDone then begin
Result := AllDone;
Exit;
end;
Result := AllDone;
end;
Здесь я использовал Sleep для создания таймаутов при работе. Однако программа просто вешается на веремя этих таймаутов. Да и смысл событийно ориентированного программирования здесь заметно хромает.
Подскажите, пожалуйста, как правильно решаются такие задачи. Если необходимы разъяснения или подробности - напишу.
С уважением, Андрей
← →
Evgeny V (2002-11-04 12:34) [1]Обычно я работаю с СOM в отдельном потоке, и жду событий от порта по WaitCommEvent, или работаю с компонентом который позволяет это делать. Но даже в твойм случае (по твоему тексту), можно не вешать задачу sleep-ом, а запустить цикл , например с компонентом TTimer: Timer1.Interval=время ожидания; Timer1.Enabled:=true;
while(Timer.Enabled=true)
begin
Application.ProcessMesages;
end;
Естественно, когда сработает таймер, ты должен Timer1.Enabled:=false;
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2003.01.16;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.009 c