Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 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
1-49142
lipskiy
2003-01-05 18:41
2003.01.16
Как работать с фреймами?


7-49320
Zolen
2002-11-03 00:54
2003.01.16
блокирование CD-Rom


3-48848
Weare
2002-12-23 14:00
2003.01.16
Excel и Delphi


3-48940
Che
2002-12-20 02:07
2003.01.16
DBComboBox


3-48868
VS2002
2002-12-24 09:19
2003.01.16
Удобный Grid





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский