📄 modlinkdemomain.pas
字号:
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogExceptionStatusBit(BitIndex: Word; BitValue: Boolean);
const
BitStates: array [Boolean] of string = ('OFF', 'ON');
begin
LogString(Format('Exception status bit %d is %s.', [BitIndex, BitStates[BitValue]]));
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogFrame(const Data: TFrameData; Send: Boolean);
var
S: string;
I: Integer;
begin
if Send then
S := 'TX: '
else
S := 'RX: ';
if Length(Data) = 0 then
S := S + '<empty>'
else
for I := 0 to High(Data) do
S := S + IntToHex(Data[I], 2) + ' ';
LogString(S);
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogIdentificationData(const Data: TServerIdentificationData);
var
S: string;
I: Integer;
begin
if Length(Data) = 0 then
S := '<empty>'
else
begin
S := '';
for I := 0 to High(Data) do
S := S + IntToHex(Data[I], 2) + ' ';
end;
LogString(S);
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogInit(ID: Cardinal; const CmdDesc: string);
begin
LogString(Format('INIT: %s [ID: %d]', [CmdDesc, ID]));
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogProcessedBits(BitCount: Word; Coils: Boolean);
var
Temp: string;
begin
if BitCount > 1 then
if Coils then
Temp := 'coils were'
else
Temp := 'discrete inputs were'
else
if Coils then
Temp := 'coil was'
else
Temp := 'discrete input was';
LogString(Format('%d %s processed.', [BitCount, Temp]));
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogProcessedRegs(RegCount: Word; Holding: Boolean);
var
Temp: string;
begin
if RegCount > 1 then
if Holding then
Temp := 'holding registers were'
else
Temp := 'input registers were'
else
if Holding then
Temp := 'holding register was'
else
Temp := 'input register was';
LogString(Format('%d %s processed.', [RegCount, Temp]));
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogServerReadError(ItemKind: TItemKind; ItemAddr: Word);
const
ItemKinds: array [TItemKind] of string = (
'coil',
'discrete input',
'holding register',
'input register'
);
begin
LogString(Format('[Read Request Error] No %s found at local server address %d.',
[ItemKinds[ItemKind], ItemAddr]));
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogServerWriteError(ItemKind: TItemKind; ItemAddr: Word;
ItemValue: Word; Status: TItemWriteStatus);
const
ItemKinds: array [TItemKind] of string = (
'coil',
'discrete input',
'holding register',
'input register'
);
begin
if ItemKind in [ikCoil, ikHoldingRegister] then
begin
case Status of
iwsIllegalAddress:
LogString(Format('[Write Request Error] No writeable %s found at local server address %d.',
[ItemKinds[ItemKind], ItemAddr]));
iwsIllegalValue:
LogString(Format('[Write Request Error] Illegal value (%d) for %s at local server address %d.',
[ItemValue, ItemKinds[ItemKind], ItemAddr]));
end;
end;
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogSingleBit(BitIndex: Word; BitValue: Boolean; Coil: Boolean);
const
BitStates: array [Boolean] of string = ('OFF', 'ON');
var
Temp: string;
begin
if Coil then
Temp := 'Coil'
else
Temp := 'Discrete input';
LogString(Format('%s %d is %s.', [Temp, BitIndex, BitStates[BitValue]]));
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogSingleRegister(RegIndex: Word; RegValue: Word; Holding: Boolean);
const
RegNames: array [Boolean] of string = ('input', 'holding');
begin
LogString(Format('Value of %s register %d is %d',
[RegNames[Holding], RegIndex, RegValue]));
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogStatus(const Info: TTransactionInfo);
begin
LogString(ServerReplies[Info.Reply]);
if Info.Reply = srExceptionReply then
LogString('Server exception: ' + ModbusClient1.ExceptionCodeToStr(Info.ExceptionCode));
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogString(const S: string);
function FormatLoggingTime(const aTime: TDateTime): string;
begin
Result := FormatDateTime('hh:nn:ss.zzz', aTime);
end;
var
vStringToLog: string;
begin
if S <> '' then
vStringToLog := Format('[%s] %s', [FormatLoggingTime(Now), S])
else
vStringToLog := '';
LogMemo.Lines.Add(vStringToLog);
if fLogTransactionsToFile then
LogStringToFile(vStringToLog);
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.LogStringToFile(const S: string);
const
cCRLF = #13#10;
var
vLength: Integer;
begin
BeginLogTransactions;
try
Assert(Assigned(fLogFile));
vLength := Length(S);
if vLength > 0 then
fLogFile.WriteBuffer(PAnsiChar(S)^, vLength);
vLength := Length(cCRLF);
fLogFile.WriteBuffer(cCRLF, vLength);
finally
EndLogTransactions;
end;
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.SaveServerItems(const aFileName: string);
var
vStream: TFileStream;
I: Integer;
vItem: PServerItem;
begin
vStream := TFileStream.Create(aFileName, fmCreate);
try
for I := 0 to Pred(ServerItemsListView.Items.Count) do
begin
vItem := PServerItem(ServerItemsListView.Items[I].Data);
SaveServerItem(vItem, vStream);
end;
finally
vStream.Free;
end;
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.SaveSettings(aIniFile: TCustomIniFile);
begin
aIniFile.WriteBool(gcGeneral, gcLogTransactionsToFile, fLogTransactionsToFile);
with ModbusConnection1 do
begin
aIniFile.WriteInteger(gcModbusConnection1, gcBaudRate, Ord(BaudRate));
if BaudRate = brCustom then
aIniFile.WriteInteger(gcModbusConnection1, gcCustomBaudRate, CustomBaudRate);
aIniFile.WriteInteger(gcModbusConnection1, gcConnectionMode, Ord(ConnectionMode));
aIniFile.WriteInteger(gcModbusConnection1, gcDataBits, Ord(DataBits));
aIniFile.WriteBool(gcModbusConnection1, gcDTREnabled, DTREnabled);
aIniFile.WriteBool(gcModbusConnection1, gcEchoQryBeforeRpy, EchoQueryBeforeReply);
aIniFile.WriteInteger(gcModbusConnection1, gcFlowControl, Ord(FlowControl));
aIniFile.WriteInteger(gcModbusConnection1, gcMaxRetries, MaxRetries);
aIniFile.WriteInteger(gcModbusConnection1, gcParity, Ord(Parity));
aIniFile.WriteString(gcModbusConnection1, gcPort, Port);
aIniFile.WriteInteger(gcModbusConnection1, gcReceiveTimeout, ReceiveTimeout);
aIniFile.WriteInteger(gcModbusConnection1, gcRefetchDelay, RefetchDelay);
aIniFile.WriteBool(gcModbusConnection1, gcRTSEnabled, RTSEnabled);
aIniFile.WriteInteger(gcModbusConnection1, gcSendTimeout, SendTimeout);
aIniFile.WriteInteger(gcModbusConnection1, gcSilentInterval, SilentInterval);
aIniFile.WriteInteger(gcModbusConnection1, gcStopBits, Ord(StopBits));
aIniFile.WriteInteger(gcModbusConnection1, gcThreadPriority, Ord(ThreadPriority));
aIniFile.WriteInteger(gcModbusConnection1, gcTransmissionMode, Ord(TransmissionMode));
aIniFile.WriteInteger(gcModbusConnection1, gcTurnaroundDelay, TurnaroundDelay);
end;
aIniFile.WriteInteger(gcModbusClient1, gcServerAddress, ModbusClient1.ServerAddress);
aIniFile.WriteInteger(gcModbusServer1, gcAddress, ModbusServer1.Address);
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.UpdateConnectionStatus;
begin
if ModbusConnection1.Active then
StatusBar1.Panels[0].Text := Format('Modbus connection: Opened [%s]', [ModbusConnection1.Port])
else
StatusBar1.Panels[0].Text := 'Modbus connection: Closed';
if ModbusConnection1.ConnectionMode = cmClient then
StatusBar1.Panels[1].Text := Format('Remote server address: %d', [ModbusClient1.ServerAddress])
else
StatusBar1.Panels[1].Text := Format('Local server address: %d', [ModbusServer1.Address]);
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.UpdateDiscreteListView;
var
StartBit, BitCount: Word;
I: Integer;
begin
ValidateDiscreteWriteGroupBox;
StartBit := Word(StrToInt(WriteStartBitEdit.Text));
BitCount := Word(StrToInt(WriteBitCountEdit.Text));
with DiscreteListView.Items do
begin
BeginUpdate;
try
if Count < BitCount then
while Count < BitCount do
Add
else if Count > BitCount then
while (Count > 0) and (Count > BitCount) do
Delete(Count - 1);
for I := 0 to Count - 1 do
Item[I].Caption := Format('Coil %d', [StartBit + I]);
finally
EndUpdate;
WriteSingleCoilButton.Enabled := Count = 1;
end;
end;
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.UpdateRegisterListView;
var
StartReg, RegCount: Word;
I: Integer;
Temp: TListItem;
begin
ValidateRegisterWriteGroupBox;
StartReg := Word(StrToInt(WriteStartRegEdit.Text));
RegCount := Word(StrToInt(WriteRegCountEdit.Text));
with RegisterListView.Items do
begin
BeginUpdate;
try
if Count < RegCount then
while Count < RegCount do
begin
Temp := Add;
Temp.Caption := '0';
Temp.SubItems.Add('');
end
else if Count > RegCount then
while (Count > 0) and (Count > RegCount) do
Delete(Count - 1);
for I := 0 to Count - 1 do
Item[I].SubItems[0] := Format('Register %d', [StartReg + I]);
finally
EndUpdate;
WriteSingleRegisterButton.Enabled := (Count = 1);
end;
end;
end;
//--------------------------------------------------------------------------------------------------
procedure TModLinkDemoMainForm.UpdateServerItem(Item: TListItem);
const
ItemKinds: array [TItemKind] of string = (
'Coil',
'Discrete Input',
'Holding Register',
'Input Register'
);
Booleans: array [Boolean] of string = (
'Off',
'On'
);
StatusMessages: array [Boolean] of string = (
'Read-Only',
'Read/Write'
);
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -