Selection of \dump_state used in preferences. Stup button, warn/err clolors in RotContorl form

This commit is contained in:
OH1KH 2020-03-09 18:43:04 +02:00
parent 2d55a68d2f
commit f4792ff7cd
11 changed files with 201 additions and 97 deletions

View File

@ -231,14 +231,15 @@
<img src=img/h10b.png border=0><br><br>
<br>
Setting up Rotator control is very similar to setting up Rig control.
<br><br><strong>Note:</strong>
<br>Rot control asks turning limits AzMin and AzMax values from rotctld with command <strong>'+\dump_state'</strong>.
<br>
<br>If <b>Use rotctld \dump_state info for limits</b> cheked rotctld asks turning limits AzMin and AzMax values from rotctld with command <strong>'+\dump_state'</strong>.
That makes user possible to set turning limits other than rotator default turn with
<strong>Extra command line arguments</strong>. Using string <strong> --set-conf=min_az=10,max_az=355</strong> you can set rotator so that cqrlog will never turn it below 10deg or over 355deg.
</p><p>Rotctld knows rotators with turn from -180deg-0deg-180deg (south stop), like Hamlib Dummy test rotator.
<br>Most of rotators are with turn 0deg - 360deg.
<br>Some are with turn 0deg - >360 deg. With them cqrlog never drives values over 360, but reads position right if rotor sends over 360 deg value (sent_value-360 = cqrlog display).
<br>Using negative value at az_min causes Cqrlog set it's 0degrees "P"-command to given negative value (while still displaying 0). I.E if az_min=-180 Cqrlog will use turning commands from "P-180" to "P180".
<br>Without negative az_min or when checkbox <b>Use rotctld \dump_state info for limits</b> is not set Cqrlog sends commands in usual range "P0 to "P360".
</p><p>Some rotators have turn from -180deg-0deg-180deg (south stop), like Hamlib Dummy test rotator.
<br>Most of rotators have turn 0deg - 360deg.
<br>Some may turn 0deg - >360 deg. With them cqrlog never drives values over 360, but reads position right if rotor sends over 360 deg value (sent_value-360 = cqrlog display).
</p>
<p>See also <a href="h30.html">Operation: TRX/ROT Control</a>
</p><p align=center><img src=img/line.png></p>

View File

@ -67,12 +67,15 @@ So do not wonder if you get smaller amount of memories than in your list when pr
<p>
From NewQSO/Window you can open <strong>Rotor control</strong> window.
<p><img src="img/h121a.png" name="7" width="353" height="367">
<p><img src="img/h121a.png" name="121a"> <img src="img/h121b.png" name="121b"> <img src="img/h121c.png" name="121c">
</p>
Window shows current position of rotor, Buttons to set Short/Long path direction and radio buttons to select rotor 1 or rotor 2.
<br><br> When you have filled a call to NewQSO callsign field and moved away from that field DXCC info part is filled against call prefix, and/or locator grid if entered.
At that point, when DXCC/AZIM shows a value it is possible to press <b>Short Path</b> or <b>Long Path buttons</b> and your rotator will turn your antenna to that direction.
<br><br> If you make changes to <b>preferences/Rot Control</b> after that just select another rotator (even if not existing) from radio buttons <b>Rotor 1</b> , <b>Rotor 2</b>. Then select back the previous rotor and new values are read. It is possible also reload settings from <b>NewQSO/File/Refresh TRX/ROT control</b>.</p>
<br>Pressing <b>Stop button</b> stops rotator turning.</p>
<p>If error message is received from rotctld button box turns red. If requested turn command is ok, but az_min or az_maz limits prevent antenna to reach requested direction button box will turn yellow. The length of color flash depends poll rate and is error permanent or not.
<br>
<br>If you make changes to <b>preferences/Rot Control</b> after that just select another rotator (even if not existing) from radio buttons <b>Rotor 1</b> , <b>Rotor 2</b>. Then select back the previous rotor and new values are read. It is possible also reload settings from <b>NewQSO/File/Refresh TRX/ROT control</b>.</p>
</p><p>See also <a href="h1.html#ah7">setting up TRX/ROTControl</a>
</p><table width="100%" border="0" cellpadding="2" cellspacing="2">
<tbody>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
help/img/h121b.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

BIN
help/img/h121c.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -1,7 +1,7 @@
object frmPreferences: TfrmPreferences
Left = 106
Left = 135
Height = 659
Top = 31
Top = 114
Width = 1098
HelpType = htKeyword
HelpKeyword = 'help/h1.html'
@ -2533,11 +2533,10 @@ object frmPreferences: TfrmPreferences
object chkRot1RunRotCtld: TCheckBox
AnchorSideLeft.Control = edtRot1RotCtldArgs
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = edtRot1RotCtldArgs
AnchorSideTop.Side = asrCenter
AnchorSideTop.Control = lblExtaArgs1
Left = 285
Height = 23
Top = 104
Top = 81
Width = 235
BorderSpacing.Left = 24
Caption = 'Run rotctld when program starts'
@ -2856,6 +2855,17 @@ object frmPreferences: TfrmPreferences
TabOrder = 6
Text = 'cmbModelRot1'
end
object chkRot1AzMinMax: TCheckBox
AnchorSideLeft.Control = chkRot1RunRotCtld
AnchorSideTop.Control = chkRot1RunRotCtld
AnchorSideTop.Side = asrBottom
Left = 285
Height = 23
Top = 104
Width = 276
Caption = 'Use rotctrld \dump:state info for limits'
TabOrder = 7
end
end
object edtRotor1: TEdit
AnchorSideLeft.Control = tabRot1
@ -2978,11 +2988,10 @@ object frmPreferences: TfrmPreferences
object chkRot2RunRotCtld: TCheckBox
AnchorSideLeft.Control = edtRot2RotCtldArgs
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = edtRot2RotCtldArgs
AnchorSideTop.Side = asrCenter
AnchorSideTop.Control = lblExtaArgs2
Left = 285
Height = 23
Top = 104
Top = 81
Width = 235
BorderSpacing.Left = 24
Caption = 'Run rotctld when program starts'
@ -3302,6 +3311,17 @@ object frmPreferences: TfrmPreferences
TabOrder = 6
Text = 'cmbModelRot2'
end
object chkRot2AzMinMax: TCheckBox
AnchorSideLeft.Control = chkRot2RunRotCtld
AnchorSideTop.Control = chkRot2RunRotCtld
AnchorSideTop.Side = asrBottom
Left = 285
Height = 23
Top = 104
Width = 276
Caption = 'Use rotctrld \dump:state info for limits'
TabOrder = 7
end
end
object edtRotor2: TEdit
AnchorSideLeft.Control = tabRot2

View File

@ -120,6 +120,8 @@ type
cb60m: TCheckBox;
cb30cm: TCheckBox;
cgLimit: TCheckGroup;
chkRot1AzMinMax: TCheckBox;
chkRot2AzMinMax: TCheckBox;
chkShowOwnPos: TCheckBox;
chkDistance: TCheckBox;
chkSTX: TCheckBox;
@ -1282,6 +1284,7 @@ begin
cqrini.WriteString('ROT1', 'RotCtldPort', edtRot1RotCtldPort.Text);
cqrini.WriteString('ROT1', 'ExtraRotCtldArgs', edtRot1RotCtldArgs.Text);
cqrini.WriteBool('ROT1', 'RunRotCtld', chkRot1RunRotCtld.Checked);
cqrini.WriteBool('ROT1', 'RotAzMinMax', chkRot1AzMinMax.Checked);
cqrini.WriteString('ROT1', 'host', edtRot1Host.Text);
cqrini.WriteInteger('ROT1', 'SerialSpeed', cmbSpeedRot1.ItemIndex);
cqrini.WriteInteger('ROT1', 'DataBits', cmbDataBitsRot1.ItemIndex);
@ -1298,6 +1301,7 @@ begin
cqrini.WriteString('ROT2', 'RotCtldPort', edtRot2RotCtldPort.Text);
cqrini.WriteString('ROT2', 'ExtraRotCtldArgs', edtRot2RotCtldArgs.Text);
cqrini.WriteBool('ROT2', 'RunRotCtld', chkRot2RunRotCtld.Checked);
cqrini.WriteBool('ROT2', 'RotAzMinMax', chkRot2AzMinMax.Checked);
cqrini.WriteString('ROT2', 'host', edtRot2Host.Text);
cqrini.WriteInteger('ROT2', 'SerialSpeed', cmbSpeedRot2.ItemIndex);
cqrini.WriteInteger('ROT2', 'DataBits', cmbDataBitsRot2.ItemIndex);
@ -2678,6 +2682,7 @@ begin
edtRot1RotCtldPort.Text := cqrini.ReadString('ROT1', 'RotCtldPort', '4533');
edtRot1RotCtldArgs.Text := cqrini.ReadString('ROT1', 'ExtraRotCtldArgs', '');
chkRot1RunRotCtld.Checked := cqrini.ReadBool('ROT1', 'RunRotCtld', False);
chkRot1AzMinMax.Checked := cqrini.ReadBool('ROT1', 'RotAzMinMax', False);
edtRot1Host.Text := cqrini.ReadString('ROT1', 'host', 'localhost');
cmbSpeedRot1.ItemIndex := cqrini.ReadInteger('ROT1', 'SerialSpeed', 0);
cmbDataBitsRot1.ItemIndex := cqrini.ReadInteger('ROT1', 'DataBits', 0);
@ -2693,6 +2698,7 @@ begin
edtRot2RotCtldPort.Text := cqrini.ReadString('ROT2', 'RotCtldPort', '4533');
edtRot2RotCtldArgs.Text := cqrini.ReadString('ROT2', 'ExtraRotCtldArgs', '');
chkRot2RunRotCtld.Checked := cqrini.ReadBool('ROT2', 'RunRotCtld', False);
chkRot2AzMinMax.Checked := cqrini.ReadBool('ROT2', 'RotAzMinMax', False);
edtRot2Host.Text := cqrini.ReadString('ROT2', 'host', 'localhost');
cmbSpeedRot2.ItemIndex := cqrini.ReadInteger('ROT2', 'SerialSpeed', 0);
cmbDataBitsRot2.ItemIndex := cqrini.ReadInteger('ROT2', 'DataBits', 0);

View File

@ -1,67 +1,19 @@
object frmRotControl: TfrmRotControl
Left = 165
Height = 163
Top = 55
Width = 187
Left = 85
Height = 178
Top = 89
Width = 196
Anchors = []
BorderIcons = [biSystemMenu]
Caption = 'Rotor control'
ClientHeight = 163
ClientWidth = 187
ClientHeight = 178
ClientWidth = 196
KeyPreview = True
OnClose = FormClose
OnDestroy = FormDestroy
OnKeyUp = FormKeyUp
OnShow = FormShow
LCLVersion = '2.0.4.0'
object ButtonShortP: TButton
AnchorSideLeft.Control = GroupBox2
AnchorSideTop.Control = GroupBox2
AnchorSideTop.Side = asrBottom
Left = 6
Height = 25
Top = 71
Width = 75
BorderSpacing.Top = 6
Caption = 'Short Path'
OnClick = ButtonShortPClick
TabOrder = 1
end
object rbRotor1: TRadioButton
AnchorSideLeft.Control = ButtonShortP
AnchorSideTop.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 23
Top = 128
Width = 60
Anchors = [akLeft, akBottom]
BorderSpacing.Top = 12
BorderSpacing.Bottom = 12
Caption = 'ROT: '
Checked = True
OnClick = rbRotor1Click
TabOrder = 2
TabStop = True
end
object rbRotor2: TRadioButton
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = ButtonLongP
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 121
Height = 23
Top = 128
Width = 60
Anchors = [akRight, akBottom]
BorderSpacing.Top = 12
BorderSpacing.Bottom = 12
Caption = 'ROT: '
OnClick = rbRotor2Click
TabOrder = 3
end
object GroupBox2: TGroupBox
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner
@ -70,14 +22,14 @@ object frmRotControl: TfrmRotControl
Left = 6
Height = 64
Top = 1
Width = 175
Width = 184
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 6
BorderSpacing.Top = 1
BorderSpacing.Right = 6
Caption = 'Azimuth'
ClientHeight = 46
ClientWidth = 173
ClientWidth = 182
TabOrder = 0
object lblAzimuth: TLabel
AnchorSideLeft.Control = GroupBox2
@ -89,7 +41,7 @@ object frmRotControl: TfrmRotControl
Left = 3
Height = 40
Top = 3
Width = 167
Width = 176
Alignment = taRightJustify
Anchors = [akTop, akLeft, akRight, akBottom]
AutoSize = False
@ -106,20 +58,101 @@ object frmRotControl: TfrmRotControl
ParentFont = False
end
end
object ButtonLongP: TButton
object pnlBtns: TPanel
AnchorSideLeft.Control = GroupBox2
AnchorSideTop.Control = GroupBox2
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = GroupBox2
AnchorSideRight.Side = asrBottom
Left = 106
Height = 25
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 101
Top = 71
Width = 75
Anchors = [akTop, akRight]
Width = 184
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Top = 6
Caption = 'LongPath'
OnClick = ButtonLongPClick
TabOrder = 4
BorderSpacing.Bottom = 6
ClientHeight = 101
ClientWidth = 184
TabOrder = 1
object rbRotor1: TRadioButton
AnchorSideLeft.Control = pnlBtns
AnchorSideBottom.Control = pnlBtns
AnchorSideBottom.Side = asrBottom
Left = 7
Height = 23
Top = 71
Width = 69
Anchors = [akLeft, akBottom]
BorderSpacing.Left = 6
BorderSpacing.Bottom = 6
Caption = 'ROT1: '
Checked = True
OnClick = rbRotor1Click
TabOrder = 0
TabStop = True
end
object rbRotor2: TRadioButton
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = pnlBtns
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = pnlBtns
AnchorSideBottom.Side = asrBottom
Left = 108
Height = 23
Top = 71
Width = 69
Anchors = [akRight, akBottom]
BorderSpacing.Top = 12
BorderSpacing.Right = 6
BorderSpacing.Bottom = 6
Caption = 'ROT2: '
OnClick = rbRotor2Click
TabOrder = 1
end
object btnShortP: TButton
AnchorSideLeft.Control = pnlBtns
AnchorSideTop.Control = pnlBtns
Left = 7
Height = 25
Top = 7
Width = 75
BorderSpacing.Left = 6
BorderSpacing.Top = 6
Caption = 'Short Path'
OnClick = btnShortPClick
TabOrder = 2
end
object btnLongP: TButton
AnchorSideTop.Control = pnlBtns
AnchorSideRight.Control = pnlBtns
AnchorSideRight.Side = asrBottom
Left = 102
Height = 25
Top = 7
Width = 75
Anchors = [akTop, akRight]
BorderSpacing.Top = 6
BorderSpacing.Right = 6
Caption = 'LongPath'
OnClick = btnLongPClick
TabOrder = 3
end
object btnStop: TButton
AnchorSideLeft.Control = pnlBtns
AnchorSideLeft.Side = asrCenter
AnchorSideTop.Control = btnShortP
AnchorSideTop.Side = asrBottom
Left = 17
Height = 25
Top = 38
Width = 150
BorderSpacing.Top = 6
Caption = 'Stop'
OnClick = btnStopClick
TabOrder = 4
end
end
object tmrRotor: TTimer
Enabled = False

View File

@ -13,15 +13,18 @@ type
{ TfrmRotControl }
TfrmRotControl = class(TForm)
ButtonShortP: TButton;
ButtonLongP: TButton;
btnLongP: TButton;
btnShortP: TButton;
btnStop: TButton;
GroupBox2: TGroupBox;
lblAzimuth: TLabel;
pnlBtns: TPanel;
rbRotor1: TRadioButton;
rbRotor2: TRadioButton;
tmrRotor: TTimer;
procedure ButtonShortPClick(Sender: TObject);
procedure ButtonLongPClick(Sender: TObject);
procedure btnShortPClick(Sender: TObject);
procedure btnLongPClick(Sender: TObject);
procedure btnStopClick(Sender: TObject);
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormDestroy(Sender: TObject);
procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
@ -92,12 +95,12 @@ begin
end
end;
procedure TfrmRotControl.ButtonShortPClick(Sender: TObject);
procedure TfrmRotControl.btnShortPClick(Sender: TObject);
begin
rotor.SetAzimuth(fNewQSO.Azimuth)
end;
procedure TfrmRotControl.ButtonLongPClick(Sender: TObject);
procedure TfrmRotControl.btnLongPClick(Sender: TObject);
var
LAzimuth : String = '';
SAz : Double = 0 ;
@ -112,6 +115,11 @@ begin
rotor.SetAzimuth(LAzimuth)
end;
procedure TfrmRotControl.btnStopClick(Sender: TObject);
begin
rotor.StopRot;
end;
function TfrmRotControl.InicializeRot : Boolean;
var
n : String = '';

View File

@ -5,7 +5,7 @@ unit uRotControl;
interface
uses
Classes, SysUtils, Process, ExtCtrls, lNetComponents, lnet, strutils;
Classes, SysUtils, Process, ExtCtrls, lNetComponents, lnet, strutils, graphics;
{type TRigMode = record
mode : String[10];
@ -74,7 +74,7 @@ type TRotControl = class
//last error during operation
function GetAzimut : Double;
procedure StopRot;
procedure SetAzimuth(azim : String);
procedure Restart;
@ -84,11 +84,13 @@ var
//most used defaults
AzMax :Double = 360;
AzMin :Double = 0;
//FAzMax :Double = 360;
//FAzMin :Double = 0;
UseState,
WarnFix: boolean;
implementation
uses fRotControl, uMyIni;
constructor TRotControl.Create;
begin
RotCommand := TStringList.Create;
@ -188,11 +190,20 @@ begin
if rcvdAzimut.Connect(fRotCtldHost,fRotCtldPort) then
begin
if fDebugMode then Writeln('Connected to rotctld @ ',fRotCtldHost,':',fRotCtldPort);
AzMin:=0; //defaullt limits
AzMax:=360;
UseState:=False;
WarnFix:=False;
result := True;
tmrRotPoll.Interval := fRotPoll;
tmrRotPoll.Enabled := True;
RotCommand.Add('+\dump_caps'+LineEnding); //factory values
//RotCommand.Add('+\dump_state'+LineEnding); //user defined limits
UseState := ( (cqrini.ReadBool('ROT1', 'RotAzMinMax', False) and (frmRotControl.rbRotor1.Checked)) or
(cqrini.ReadBool('ROT2', 'RotAzMinMax', False) and (frmRotControl.rbRotor2.Checked)) );
if UseState then RotCommand.Add('+\dump_state'+LineEnding); //user defined limits
//RotCommand.Add('+\dump_caps'+LineEnding); //factory values
end
else begin
if fDebugMode then Writeln('NOT connected to rotctld @ ',fRotCtldHost,':',fRotCtldPort);
@ -203,19 +214,25 @@ end;
procedure TRotControl.SetAzimuth(azim : String);
var
az: double;
az,
azz: double;
begin
if fDebugMode then writeln('Requested Az:',azim);
if TryStrToFloat(azim,az) then
Begin
azz := az;
if az>360 then az:= az-360; // this should not happen by cqrlog
if AzMin< 0 then //-180 ..0.. 180 rotator case
if az>180 then az := az-360; //west results negative -180 .. 0 East is positive 0 .. 180
//if follow \dump_state and rotor type is -180 .. 180
//west results negative -180 .. 0 East is positive 0 .. 180
if (UseState and (AzMin<0 ) and (az>180)) then az := az-360;
if az<AzMin then az:=AzMin; //user limted minimum value by config parameters
if az>AzMax then az:=AzMax; //user limted maximum value by config parameters
WarnFix := azz<>az ;//P command is fixed, warn about it
azim:=FloatToStr(az);
end;
if fDebugMode then writeln('Requested fixed Az:',azim,' (AzMin:',FloatToStr(AzMin),' AzMax:',FloatToStr(AzMax),')');
@ -226,6 +243,10 @@ function TRotControl.GetAzimut : Double;
begin
result := fAzimut
end;
procedure TRotControl.StopRot ;
begin
rcvdAzimut.SendMessage('S'+LineEnding);
end;
procedure TRotControl.OnReceivedRcvdAzimut(aSocket: TLSocket);
var
@ -238,6 +259,18 @@ begin
begin
msg:=StringReplace(msg,#09,#32,[rfReplaceAll]); //convert TAB to SPACE
msg:=StringReplace(DelSpace(msg),':','=',[rfReplaceAll]); //remove SPACES, convert : to =
if pos('RPRT-',msg)>0 then
frmRotControl.pnlBtns.Color:=clRed
else
if WarnFix then
begin
frmRotControl.pnlBtns.Color:=clYellow;
WarnFix := False;
end
else
frmRotControl.pnlBtns.Color:=clDefault;
frmRotControl.pnlBtns.Repaint;
Resp := TStringList.create;
Resp.Delimiter := LineEnding;
Resp.DelimitedText:=msg;
@ -245,7 +278,7 @@ begin
Begin
if TryStrToFloat(Resp.Values['Azimuth'],Az) then fAzimut := Az;
if fDebugMode then writeln('Az:',FloatToStr(fAzimut));
if AzMin<0 then if fAzimut<>0 then fAzimut:= 360+fAzimut; //south stop -180..0..180 type rotor
if ( UseState and (AzMin<0 )) then if fAzimut<>0 then fAzimut:= 360+fAzimut; //south stop -180..0..180 type rotor
if fAzimut>360 then fAzimut:= fAzimut-360; //some rotators turn over 360 deg and -180..0.180 calculations may result, too
if fDebugMode then writeln('Fixed Az:',FloatToStr(fAzimut),' (AzMin:',FloatToStr(AzMin),' AzMax:',FloatToStr(AzMax),')');
end;