⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modlinkdemomain.pas

📁 ModLink VCL component 组件以及代码。版本是shareware edition of ModLink 2.10
💻 PAS
📖 第 1 页 / 共 5 页
字号:

//--------------------------------------------------------------------------------------------------

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 + -