Witam
Piszę aplikację do komunikacji z centralą telefoniczną przez RS232. W programie mam komponent ListView a w nim 8 pozycji każda pozycja odpowieda jednemu numerowi wewnętrznemu (21..28).
W OnCreate formy otwieram port COM1 i wysyłam odpowiednie instrukcje w celu nawiązania komunikacji z centralką Dostaje odpowiedź od centralki że połączenie nawiązano pomyślnie i zaczynam odbierać komunikaty.
Co 10-15 sekund trzeba wysłać do centralki komendę podtrzymującą połączenie ja zrobiłem to w Timerze w którym ustawiłem Interval na 10000.
Centralka wysyła ok 13 różnych komunikatów mnie interesują 2.
C01 aX 21 - Abonent o numerze 21 rozpoczął rozmowę
C02 ax 21 - Abonent o numerze 21 zakończył rozmowę
Jeżeli dostanę komunikat C01 aX 21 to wykonuję pętlę dla wszystkich pozycji na ListView i znajduję tą z numerem 21 i wywołuję procedurę StartRecord która rozpoczyna nagrywanie rozmowy na lini 21. Nagrywanie realizowane jest za pomocą biblioteki Bass.dll.
Kod procedurey StartRecord:
procedure TMain.StartRecord(UserI: Integer);
Var
Commands, FileName : String;
Dev, Inp, I, X: Integer;
begin
Dev := StrToInt(LUser.Items[UserI].SubItems[3]);
Inp := StrToInt(LUser.Items[UserI].SubItems[4]);
if BASS_RecordInit(Dev) then BASS_RecordFree();
BASS_RecordInit(Dev);
I := 0;
while BASS_RecordSetInput(i, BASS_INPUT_OFF, -1) do Inc(I);
BASS_RecordSetInput(Inp, BASS_INPUT_ON, 0.9);
ForceDirectories(DataDir + LUser.Items[UserI].Caption + '\' + DateToStr(Now) + '\');
RChan[UserI] := BASS_RecordStart(44100, 1, BASS_RECORD_PAUSE, @RecordingCallback, 0);
if RChan[UserI] = 0 then begin
ShowMessage('Nie można rozpocząć nagrywania. Sprawdź czy urządzenie jest podłączone prawidłowo.');
Exit;
end;
X := StrToInt(LUser.Items[UserI].SubItems[5]);
FileName := IntToStr(X+1) + '.mp3';
Commands := 'lame.exe -b 48 - Data\' + LUser.Items[UserI].Caption + '\' +
DateToStr(Now) + '\' + FileName;
if (BASS_Encode_Start(RChan[UserI], PChar(Commands), BASS_ENCODE_AUTOFREE, nil, 0) = 0) then
begin
ShowMessage('Couldn''t start encoding...' + #10
+ 'Make sure OGGENC.EXE (if encoding to OGG) is in the same' + #10
+ 'direcory as this RECTEST, or LAME.EXE (if encoding to MP3).');
BASS_ChannelStop(RChan[UserI]);
RChan[UserI] := 0;
Exit;
end;
LUser.Items[UserI].ImageIndex := 1;
LUser.Items[UserI].SubItems[2] := 'Nagrywam...';
BASS_ChannelPlay(RChan[UserI], FALSE);
end;
jeżeli dostanę komendę C02 aX 21 to wywołuję procedurę StopRecord:
procedure TMain.StopRecord(UserI: Integer);
Var
FName: String;
X : Integer;
begin
BASS_ChannelStop(RChan[UserI]);
RChan[UserI] := 0;
LUser.Items[UserI].ImageIndex := 0;
LUser.Items[UserI].SubItems[2] := 'Oczekuje...';
end;
Na początku wszystko działa dobrze ale po pewnym czasi (czasami po 1 minucie czasami po 5 minutach) program przestaje odbierać komunikaty na porcie COM1 NIE MA żadnych danych wysłanych z centralki. Nie bardzo wiem dlaczego tak się dzieje. Zaznaczam że jak wyłączę program i włączę ponownie to dane są odbierane dalej i za chwilę znów się zawiesza.
Kod odczytujący dane z Com1:
procedure TMain.ComPortRxChar(Sender: TObject; Count: Integer);
Var
RevS, S: String;
begin
ComPort.ReadStr(RevS, 128);
S := AdjustLineBreaks(RevS);
S := StringReplace(S, #13#10, '', [rfReplaceAll]);
if Pos('C01', S) > 0 then StartRecord();
if Pos('C02', S) > 0 then StopRecord();
ComMemo.Lines.Add(TimeToStr(Time) + ': ' + S);
end;
Czy możliwe jest że jak w krótkim odstępie czasu dostanę kilka komunikatów i będę chciał wywołać którąś z procedur kilka razy to zwiesi mi się komunikacja z centralką??
Czy ktoś ma może jaikś pomysł jak odbierać komunikaty z z portu COM nie zależnie od tego co się dzieje w programie? Czy jeśli odbieranie danych z portu COM będzie w osobnym wątku to coś zmieni?