First version f Rotor control added

This commit is contained in:
darekper 2013-03-24 18:41:46 +01:00
parent 073d40b9c6
commit 1ff35a56db
4 changed files with 841 additions and 0 deletions

76
src/fRotControl.lfm Normal file
View File

@ -0,0 +1,76 @@
object frmRotControl: TfrmRotControl
Left = 384
Height = 167
Top = 304
Width = 214
BorderIcons = [biSystemMenu]
BorderStyle = bsDialog
Caption = 'Rotor control'
ClientHeight = 167
ClientWidth = 214
OnClose = FormClose
OnShow = FormShow
LCLVersion = '0.9.30.2'
object ButtonShortP: TButton
Left = 72
Height = 25
Top = 80
Width = 75
Caption = 'Short Path'
OnClick = ButtonShortPClick
TabOrder = 1
end
object rbRotor1: TRadioButton
Left = 16
Height = 24
Top = 128
Width = 60
Caption = 'ROT: '
Checked = True
OnChange = rbRotor1Change
OnClick = rbRotor1Click
TabOrder = 2
TabStop = True
end
object rbRotor2: TRadioButton
Left = 112
Height = 24
Top = 128
Width = 60
Caption = 'ROT: '
OnChange = rbRotor2Change
OnClick = rbRotor2Click
TabOrder = 3
end
object GroupBox2: TGroupBox
Left = 8
Height = 72
Top = 0
Width = 197
Caption = 'Azimuth'
ClientHeight = 53
ClientWidth = 193
TabOrder = 0
object lblAzimuth: TLabel
Left = 10
Height = 49
Top = -1
Width = 168
Alignment = taRightJustify
AutoSize = False
Caption = '0.0'
Font.Color = clBlue
Font.Height = 30
Font.Style = [fsBold]
ParentColor = False
ParentFont = False
end
end
object tmrRotor: TTimer
Enabled = False
Interval = 500
OnTimer = tmrRotorTimer
left = 80
top = 120
end
end

24
src/fRotControl.lrs Normal file
View File

@ -0,0 +1,24 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TfrmRotControl','FORMDATA',[
'TPF0'#14'TfrmRotControl'#13'frmRotControl'#4'Left'#3#128#1#6'Height'#3#167#0
+#3'Top'#3'0'#1#5'Width'#3#214#0#11'BorderIcons'#11#12'biSystemMenu'#0#11'Bor'
+'derStyle'#7#8'bsDialog'#7'Caption'#6#13'Rotor control'#12'ClientHeight'#3
+#167#0#11'ClientWidth'#3#214#0#7'OnClose'#7#9'FormClose'#6'OnShow'#7#8'FormS'
+'how'#10'LCLVersion'#6#8'0.9.30.2'#0#7'TButton'#12'ButtonShortP'#4'Left'#2'H'
+#6'Height'#2#25#3'Top'#2'P'#5'Width'#2'K'#7'Caption'#6#10'Short Path'#7'OnCl'
+'ick'#7#17'ButtonShortPClick'#8'TabOrder'#2#1#0#0#12'TRadioButton'#8'rbRotor'
+'1'#4'Left'#2#16#6'Height'#2#24#3'Top'#3#128#0#5'Width'#2'<'#7'Caption'#6#5
+'ROT: '#7'Checked'#9#8'OnChange'#7#14'rbRotor1Change'#7'OnClick'#7#13'rbRoto'
+'r1Click'#8'TabOrder'#2#2#7'TabStop'#9#0#0#12'TRadioButton'#8'rbRotor2'#4'Le'
+'ft'#2'p'#6'Height'#2#24#3'Top'#3#128#0#5'Width'#2'<'#7'Caption'#6#5'ROT: '#8
+'OnChange'#7#14'rbRotor2Change'#7'OnClick'#7#13'rbRotor2Click'#8'TabOrder'#2
+#3#0#0#9'TGroupBox'#9'GroupBox2'#4'Left'#2#8#6'Height'#2'H'#3'Top'#2#0#5'Wid'
+'th'#3#197#0#7'Caption'#6#7'Azimuth'#12'ClientHeight'#2'5'#11'ClientWidth'#3
+#193#0#8'TabOrder'#2#0#0#6'TLabel'#10'lblAzimuth'#4'Left'#2#10#6'Height'#2'1'
+#3'Top'#2#255#5'Width'#3#168#0#9'Alignment'#7#14'taRightJustify'#8'AutoSize'
+#8#7'Caption'#6#3'0.0'#10'Font.Color'#7#6'clBlue'#11'Font.Height'#2#30#10'Fo'
+'nt.Style'#11#6'fsBold'#0#11'ParentColor'#8#10'ParentFont'#8#0#0#0#6'TTimer'
+#8'tmrRotor'#7'Enabled'#8#8'Interval'#3#244#1#7'OnTimer'#7#13'tmrRotorTimer'
+#4'left'#2'P'#3'top'#2'x'#0#0#0
]);

178
src/fRotControl.pas Normal file
View File

@ -0,0 +1,178 @@
unit fRotControl;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
StdCtrls, ExtCtrls, uMyIni, uRotControl, fNewQSO;
type
{ TfrmRotControl }
TfrmRotControl = class(TForm)
ButtonShortP: TButton;
GroupBox2: TGroupBox;
lblAzimuth: TLabel;
rbRotor1: TRadioButton;
rbRotor2: TRadioButton;
tmrRotor: TTimer;
procedure ButtonShortPClick(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormShow(Sender: TObject);
procedure rbRotor1Change(Sender: TObject);
procedure rbRotor1Click(Sender: TObject);
procedure rbRotor2Change(Sender: TObject);
procedure rbRotor2Click(Sender: TObject);
procedure tmrRotorTimer(Sender: TObject);
private
{ private declarations }
rotor : TRotControl;
public
{ public declarations }
procedure SynROT;
function InicializeRot : Boolean;
end;
var
frmRotControl: TfrmRotControl;
implementation
{ TfrmRotControl }
uses dUtils;
procedure TfrmRotControl.FormShow(Sender: TObject);
begin
dmUtils.LoadWindowPos(frmRotControl);
rbRotor1.Caption := cqrini.ReadString('ROT1','Desc','Rotor 1');
rbRotor2.Caption := cqrini.ReadString('ROT2','Desc','Rotor 2')
end;
procedure TfrmRotControl.rbRotor1Change(Sender: TObject);
begin
end;
procedure TfrmRotControl.rbRotor1Click(Sender: TObject);
begin
InicializeRot
end;
procedure TfrmRotControl.rbRotor2Change(Sender: TObject);
begin
end;
procedure TfrmRotControl.rbRotor2Click(Sender: TObject);
begin
InicializeRot
end;
procedure TfrmRotControl.tmrRotorTimer(Sender: TObject);
begin
SynROT
end;
procedure TfrmRotControl.FormClose(Sender: TObject;
var CloseAction: TCloseAction);
begin
dmUtils.SaveWindowPos(frmRotControl);
end;
procedure TfrmRotControl.ButtonShortPClick(Sender: TObject);
begin
rotor.SetAzimuth(fNewQSO.Azimuth)
end;
function TfrmRotControl.InicializeRot : Boolean;
var
n : String = '';
id : Integer = 0;
Resume : Boolean = False;
begin
if Assigned(rotor) then
begin
FreeAndNil(rotor);
end;
Application.ProcessMessages;
Sleep(500);
tmrRotor.Enabled := False;
if rbRotor1.Checked then
n := '1'
else
n := '2';
rotor := TRotControl.Create;
rotor.DebugMode := True;
if not TryStrToInt(cqrini.ReadString('ROT'+n,'model',''),id) then
rotor.RotId := 1
else
rotor.RotId := id;
rotor.RotCtldPath := cqrini.ReadString('ROT','RigCtldPath','/usr/bin/rotctld');
rotor.RotCtldArgs := dmUtils.GetRotorRotCtldCommandLine(StrToInt(n));
rotor.RunRotCtld := cqrini.ReadBool('ROT'+n,'RunRotCtld',False);
rotor.RotDevice := cqrini.ReadString('ROT'+n,'device','');
rotor.RotCtldPort := StrToInt(cqrini.ReadString('ROT'+n,'RotCtldPort','4533'));
rotor.RotCtldHost := cqrini.ReadString('ROT'+n,'host','localhost');
rotor.RotPoll := StrToInt(cqrini.ReadString('ROT'+n,'poll','500'));
tmrRotor.Interval := rotor.RotPoll;
tmrRotor.Enabled := True;
if not rotor.Connected then
begin
FreeAndNil(rotor);
end;
end;
procedure TfrmRotControl.SynROT;
var
Az : Double ;
begin
if Assigned(rotor) then
Az := rotor.GetAzimut
else
Az := 0;
lblAzimuth.Caption := FormatFloat(empty_azimuth+';;',Az);
{ UpdateModeButtons(m);
ClearButtonsColor;
if f = 0 then
exit;
b := dmUtils.GetBandFromFreq(lblAzimuth.Caption);
if b = '160M' then
btn160m.Font.Color := clRed
else if b = '80M' then
btn80m.Font.Color := clRed
else if b = '40M' then
btn40m.Font.Color := clRed
else if b = '30M' then
btn30m.Font.Color := clRed
else if b = '20M' then
btn20m.Font.Color := clRed
else if b = '17M' then
btn17m.Font.Color := clRed
else if b = '15M' then
btn15m.Font.Color := clRed
else if b = '12M' then
btn12m.Font.Color := clRed
else if b = '10M' then
btn10m.Font.Color := clRed
else if b = '6M' then
btn6m.Font.Color := clRed
else if b = '2M' then
btn2m.Font.Color := clRed
else if b = '70CM' then
btn70cm.Font.Color := clRed }
end;
initialization
{$I fRotControl.lrs}
end.

563
src/uRotControl.pas Normal file
View File

@ -0,0 +1,563 @@
unit uRotControl;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Process, ExtCtrls, lNetComponents, lnet;
{type TRigMode = record
mode : String[10];
pass : word;
end;
type TVFO = (VFOA,VFOB);
type
TExplodeArray = Array of String;
}
type TRotControl = class
rcvdAzimut : TLTCPComponent;
rotProcess : TProcess;
tmrRotPoll : TTimer;
private
fRotCtldPath : String;
fRotCtldArgs : String;
fRunRotCtld : Boolean;
// fMode : TRigMode;
fAzimut : Double;
fRotPoll : Word;
fRotCtldPort : Word;
fLastError : String;
fRotId : Word;
fRotDevice : String;
fDebugMode : Boolean;
fRotCtldHost : String;
// fVFO : TVFO;
RotCommand : TStringList;
fRigSendCWR : Boolean;
function RotConnected : Boolean;
function StartRotctld : Boolean;
// function Explode(const cSeparator, vString: String): TExplodeArray;
procedure OnReceivedRcvdAzimut(aSocket: TLSocket);
procedure OnRotPollTimer(Sender: TObject);
public
constructor Create;
destructor Destroy; override;
property DebugMode : Boolean read fDebugMode write fDebugMode;
property RotCtldPath : String read fRotCtldPath write fRotCtldPath;
//path to rotctld binary
property RotCtldArgs : String read fRotCtldArgs write fRotCtldArgs;
//rotctld command line arguments
property RunRotCtld : Boolean read fRunRotCtld write fRunRotCtld;
//run rigctld command before connection
property RotId : Word read fRotId write fRotId;
//hamlib rot id
property RotDevice : String read fRotDevice write fRotDevice;
//port where is rot connected
property RotCtldPort : Word read fRotCtldPort write fRotCtldPort;
// port where rotctld is listening to connecions, default 4533
property RotCtldHost : String read fRotCtldHost write fRotCtldHost;
//host where is rotctld running
property Connected : Boolean read RotConnected;
//connect rigctld
property RotPoll : Word read fRotPoll write fRotPoll;
//poll rate in miliseconds
// property RigSendCWR : Boolean read fRigSendCWR write fRigSendCWR;
//send CWR instead of CW
property LastError : String read fLastError;
//last error during operation
{
function GetCurrVFO : TVFO;
function GetModePass : TRigMode;
function GetModeOnly : String;}
function GetAzimut : Double;
{ function GetFreqKHz : Double;
function GetFreqMHz : Double;
function GetModePass(vfo : TVFO) : TRigMode; overload;
function GetModeOnly(vfo : TVFO) : String; overload;
function GetFreqHz(vfo : TVFO) : Double; overload;
function GetFreqKHz(vfo : TVFO) : Double; overload;
function GetFreqMHz(vfo : TVFO) : Double; overload;}
function GetLine1(const cSeparator, inString: String) : String;
{ procedure SetCurrVFO(vfo : TVFO);
procedure SetModePass(mode : TRigMode); }
procedure SetAzimuth(azim : String);
// procedure ClearRit;
procedure Restart;
end;
implementation
constructor TRotControl.Create;
begin
RotCommand := TStringList.Create;
fDebugMode := True;
if DebugMode then Writeln('In create');
fRotCtldHost := 'localhost';
fRotCtldPort := 4533;
fRotPoll := 500;
fRunRotCtld := True;
rcvdAzimut := TLTCPComponent.Create(nil);
rotProcess := TProcess.Create(nil);
tmrRotPoll := TTimer.Create(nil);
tmrRotPoll.Enabled := False;
if DebugMode then Writeln('All objects created');
tmrRotPoll.OnTimer := @OnRotPollTimer;
rcvdAzimut.OnReceive := @OnReceivedRcvdAzimut
end;
function TRotControl.StartRotctld : Boolean;
var
cmd : String;
begin
cmd := fRotCtldPath + ' ' +RotCtldArgs;
{
cmd := StringReplace(cmd,'%m',IntToStr(fRigId),[rfReplaceAll, rfIgnoreCase]);
cmd := StringReplace(cmd,'%r',fRigDevice,[rfReplaceAll, rfIgnoreCase]);
cmd := StringReplace(cmd,'%t',IntToStr(fRigCtldPort),[rfReplaceAll, rfIgnoreCase]);
}
if DebugMode then Writeln('Starting RotCtld ...');
if fDebugMode then Writeln(cmd);
rotProcess.CommandLine := cmd;
try
rotProcess.Execute;
sleep(1000)
except
on E : Exception do
begin
if fDebugMode then
Writeln('Starting rigctld E: ',E.Message);
fLastError := E.Message;
Result := False;
exit
end
end;
tmrRotPoll.Interval := fRotPoll;
tmrRotPoll.Enabled := True;
Result := True
end;
function TRotControl.RotConnected : Boolean;
const
ERR_MSG = 'Could not connect to rigctld';
begin
if fDebugMode then
begin
Writeln('');
Writeln('Settings:');
Writeln('-----------------------------------------------------');
Writeln('RotCtldPath:',RotCtldPath);
Writeln('RotCtldArgs:',RotCtldArgs);
Writeln('RunRotCtld: ',RunRotCtld);
Writeln('RotDevice: ',RotDevice);
Writeln('RotCtldPort:',RotCtldPort);
Writeln('RotCtldHost:',RotCtldHost);
Writeln('RotPoll: ',RotPoll);
// Writeln('RotSendCWR: ',RigSendCWR);
Writeln('RotId: ',RotId);
Writeln('')
end;
if fRunRotCtld then
begin
if not StartRotctld then
begin
if fDebugMode then Writeln('rotctld failed to start!');
Result := False;
exit
end
end;
if fDebugMode then Writeln('rotctld started!');
rcvdAzimut.Host := fRotCtldHost;
rcvdAzimut.Port := fRotCtldPort;
//rcvdAzimut.Connect(fRotCtldHost,fRotCtldPort);
if rcvdAzimut.Connect(fRotCtldHost,fRotCtldPort) then
begin
if fDebugMode then Writeln('Connected to ',fRotCtldHost,':',fRotCtldPort);
result := True;
tmrRotPoll.Interval := fRotPoll;
tmrRotPoll.Enabled := True
end
else begin
if fDebugMode then Writeln('NOT connected to ',fRotCtldHost,':',fRotCtldPort);
fLastError := ERR_MSG;
Result := False
end
end;
{
procedure TRigControl.SetCurrVFO(vfo : TVFO);
begin
case vfo of
VFOA : RigCommand.Add('V VFOA');//sendCommand.SendMessage('V VFOA'+LineEnding);
VFOB : RigCommand.Add('V VFOB')//sendCommand.SendMessage('V VFOB'+LineEnding);
end //case
end;
procedure TRigControl.SetModePass(mode : TRigMode);
begin
if (mode.mode='CW') and fRigSendCWR then
mode.mode := 'CWR';
RigCommand.Add('M '+mode.mode+' '+IntToStr(mode.pass))
end;
}
procedure TRotControl.SetAzimuth(azim : String);
begin
// RotCommand.Add('P '+FloatToStr(azim))
RotCommand.Add('P '+azim+' 0'+LineEnding )
end;
{
procedure TRigControl.ClearRit;
begin
RigCommand.Add('J 0')
end;
function TRigControl.GetCurrVFO : TVFO;
begin
result := fVFO
end;
function TRigControl.GetModePass : TRigMode;
begin
result := fMode
end;
function TRigControl.GetModeOnly : String;
begin
result := fMode.mode
end;
}
function TRotControl.GetAzimut : Double;
begin
result := fAzimut
end;
{
function TRigControl.GetFreqKHz : Double;
begin
result := fFreq / 1000
end;
function TRigControl.GetFreqMHz : Double;
begin
result := fFreq / 1000000
end;
function TRigControl.GetModePass(vfo : TVFO) : TRigMode;
var
old_vfo : TVFO;
begin
if fVFO <> vfo then
begin
old_vfo := fVFO;
SetCurrVFO(vfo);
Sleep(fRigPoll*2);
result := fMode;
SetCurrVFO(old_vfo)
end;
result := fMode
end;
function TRigControl.GetModeOnly(vfo : TVFO) : String;
var
old_vfo : TVFO;
begin
if fVFO <> vfo then
begin
old_vfo := fVFO;
SetCurrVFO(vfo);
Sleep(fRigPoll*2);
result := fMode.mode;
SetCurrVFO(old_vfo)
end;
result := fMode.mode
end;
function TRigControl.GetFreqHz(vfo : TVFO) : Double;
var
old_vfo : TVFO;
begin
if fVFO <> vfo then
begin
old_vfo := fVFO;
SetCurrVFO(vfo);
Sleep(fRigPoll*2);
result := fFreq;
SetCurrVFO(old_vfo)
end;
result := fFreq
end;
function TRigControl.GetFreqKHz(vfo : TVFO) : Double;
var
old_vfo : TVFO;
begin
if fVFO <> vfo then
begin
old_vfo := fVFO;
SetCurrVFO(vfo);
Sleep(fRigPoll*2);
result := fFreq/1000;
SetCurrVFO(old_vfo)
end;
result := fFreq
end;
function TRigControl.GetFreqMHz(vfo : TVFO) : Double;
var
old_vfo : TVFO;
begin
if fVFO <> vfo then
begin
old_vfo := fVFO;
SetCurrVFO(vfo);
Sleep(fRigPoll*2);
result := fFreq/1000000;
SetCurrVFO(old_vfo)
end;
result := fFreq
end;
}
procedure TRotControl.OnReceivedRcvdAzimut(aSocket: TLSocket);
var
msg : String;
tmp : String;
poz : Word;
wdt : Integer;
// a : TExplodeArray;
i : Integer;
Az : Double;
begin
if aSocket.GetMessage(msg) > 0 then
begin
// Writeln('Whole MSG:|',msg,'|');
tmp:= GetLine1(LineEnding,msg);
// Writeln('Line 1:|',tmp,'|');
if TryStrToFloat(tmp,Az) then
fAzimut := Az;
{msg := trim(msg);
a := Explode(LineEnding,msg);
for i:=0 to Length(a)-1 do
begin
//Writeln('a[i]:',a[i]);
if a[i]='' then Continue;
if TryStrToFloat(a[i],f) then
begin
if f>20000 then
fAzimut := f
else
fMode.pass := round(f);
Continue
end;
//if (a[i][1] in ['A'..'Z']) and (a[i][1] <> 'V' ) then //receiving mode info
//FT-920 returned VFO as MEM
if (a[i][1] in ['A'..'Z']) and (a[i][1] <> 'V' ) and (a[i]<>'MEM') then//receiving mode info
begin
if Pos('RPRT',a[i]) = 0 then
begin
fMode.mode := a[i];
if (fMode.mode = 'USB') or (fMode.mode = 'LSB') then
fMode.mode := 'SSB';
if fMode.mode = 'CWR' then
fMode.mode := 'CW';
end
end;
if (a[i][1] = 'V') then
begin
if Pos('VFOB',msg) > 0 then
fVFO := VFOB
else
fVFO := VFOA
end
end;
{
if (Length(a)<4) then
begin
for i:=0 to Length(a)-1 do
Writeln('a[',i,']:',a[i]);
if (msg[1] = 'V') then
begin
if Pos('VFOB',msg) > 0 then
fVFO := VFOB
else
fVFO := VFOA
end;
if (msg[1] in ['A'..'Z']) and (msg[1] <> 'V' ) then //receiving mode info
begin
if Pos('RPRT',msg) = 0 then
begin
tmp := copy(msg,1,Pos(LineEnding,msg)-1);
fMode.mode := trim(tmp);
if (fMode.mode = 'USB') or (fMode.mode = 'LSB') then
fMode.mode := 'SSB';
tmp := trim(copy(msg,Pos(LineEnding,msg)+1,5));
if not TryStrToInt(tmp,wdt) then
begin
fMode.pass := 0;
fLastError := 'Could not get mode width from radio';
if fDebugMode then Writeln(fLastError,':',msg,'*')
end
else
fMode.pass := wdt
end
end
else begin
if (msg[1] <> 'V' ) then
begin
tmp := trim(msg);
if not TryStrToFloat(tmp,fFreq) then
begin
fFreq := 0;
fLastError := 'Could not get freq from radio';
if fDebugMode then Writeln(fLastError,':',msg,'*')
end
end
end
end
else begin
if not TryStrToFloat(a[0],fFreq) then
begin
fFreq := 0;
fLastError := 'Could not get freq from radio';
if fDebugMode then Writeln(fLastError,':',msg,'*',a[0],'*')
end;
if Pos('RPRT',a[1]) = 0 then
begin
fMode.mode := trim(a[1]);
if (fMode.mode = 'USB') or (fMode.mode = 'LSB') then
fMode.mode := 'SSB';
if fMode.mode = 'CWR' then
fMode.mode := 'CW';
tmp := a[2];
if not TryStrToInt(tmp,wdt) then
begin
fMode.pass := 0;
fLastError := 'Could not get mode width from radio';
if fDebugMode then Writeln(fLastError,':',msg,'*')
end
else
fMode.pass := wdt
end;
if Pos('VFOB',a[3]) > 0 then
fVFO := VFOB
else
fVFO := VFOA
end;}
{ Writeln('-----');
Writeln('VFO :',fVFO);
Writeln('FREQ :',fFreq);
Writeln('Mode :',fMode.mode);
Writeln('Bandwidth:',fMode.pass);
Writeln('-----')} }
end
end;
procedure TRotControl.OnRotPollTimer(Sender: TObject);
var
cmd : String;
i : Integer;
begin
if (RotCommand.Text<>'') then
begin
for i:=0 to RotCommand.Count-1 do
begin
sleep(100);
cmd := RotCommand.Strings[i]+LineEnding;
rcvdAzimut.SendMessage(cmd);
Writeln('Sending: '+cmd)
end;
RotCommand.Clear
end
else begin
rcvdAzimut.SendMessage('p'+LineEnding)
end
end;
procedure TRotControl.Restart;
var
excode : Integer;
begin
rotProcess.Terminate(excode);
tmrRotPoll.Enabled := False;
rcvdAzimut.Disconnect();
RotConnected
end;
{
function TRigControl.Explode(const cSeparator, vString: String): TExplodeArray;
var
i: Integer;
S: String;
begin
S := vString;
SetLength(Result, 0);
i := 0;
while Pos(cSeparator, S) > 0 do begin
SetLength(Result, Length(Result) +1);
Result[i] := Copy(S, 1, Pos(cSeparator, S) -1);
Inc(i);
S := Copy(S, Pos(cSeparator, S) + Length(cSeparator), Length(S));
end;
SetLength(Result, Length(Result) +1);
Result[i] := Copy(S, 1, Length(S))
end;
}
function TRotControl.GetLine1(const cSeparator, inString: String) : String;
begin
result := Copy(inString, 1, Pos(cSeparator, inString)-1);
end;
destructor TRotControl.Destroy;
var
excode : Integer=0;
begin
inherited;
Writeln(1);
if fRunRotCtld then
begin
if rotProcess.Running then
begin
Writeln('1a');
rotProcess.Terminate(excode)
end
end;
Writeln(2);
tmrRotPoll.Enabled := False;
Writeln(3);
rcvdAzimut.Disconnect();
Writeln(4);
FreeAndNil(rcvdAzimut);
Writeln(5);
FreeAndNil(rotProcess);
FreeAndNil(RotCommand);
Writeln(6);
end;
end.