Есть некая библиотека для работы с Modbus RTU. Если все компоненты размещать на форме, то все отлично, по нажатию кнопки отправляет запрос, принимает пакет. нужны всего 2 компонента: ModbusClient ModbusConnection Код | unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ModLink;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; Memo1: TMemo; ModbusClient1: TModbusClient; ModbusConnection1: TModbusConnection;
procedure Button1Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure ModbusClient1HoldingRegistersRead(Sender: TModbusClient; const Info: TTransactionInfo; StartReg, RegCount: Word; const RegValues: TRegValues);
private { Private declarations } public { Public declarations } end;
var Form1: TForm1; ModbusConnection1: TModbusConnection; ModbusClient1: TModbusClient;
implementation
{$R *.dfm}
function LayerFunc(Bin: string): Single; var SomeVar: Byte; begin SomeVar := StrToInt(Bin[1]); end; function IntToBinFloat(Value: Integer; var Float: Single): string; var i: Integer; begin Result := ''; for i := 31 downto 0 do if Value and (1 shl i) <> 0 then Result := Result + '1' else Result := Result + '0'; Float := LayerFunc(Result); end;
function HexToFloat(Hex: string): Single; begin try IntToBinFloat(StrToInt('$' + Hex), Result); except Result := 0.0 end; end;
procedure TForm1.Button1Click(Sender: TObject); begin ModbusConnection1.Port:='COM3'; ModbusConnection1.BaudRate:=br115200; ModbusConnection1.DataBits:=db8; ModbusConnection1.Parity:=psEven; ModbusConnection1.StopBits:=sb1; ModbusConnection1.Open; ModbusClient1.Connection:= ModbusConnection1; end;
procedure TForm1.Button3Click(Sender: TObject); begin ModbusClient1.ReadHoldingRegisters(4096, 60); end;
procedure TForm1.ModbusClient1HoldingRegistersRead(Sender: TModbusClient; const Info: TTransactionInfo; StartReg, RegCount: Word; const RegValues: TRegValues); Var i:Integer; begin if Info.Reply = srNormalReply then begin For i:=0 to 29 do {Эта часть пока чисто для визуализации, смотрю верные данные приходят или нет, данные по 4 байта} Memo1.Lines.Add(inttostr(i) + ' ' + IntToHex(RegValues[i*2],4)+IntToHex(RegValues[i*2+1],4)+' ' + FormatFloat('0.####',HexToFloat(IntToHex(RegValues[i*2],4)+IntToHex(RegValues[i*2+1],4)))); end;
end;
end.
|
Таже самая форма, компоненты ModbusConnection и ModbusClient создаются программно. Код | unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ModLink;
type TForm1 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Edit1: TEdit; Memo1: TMemo;
procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button3Click(Sender: TObject);
private { Private declarations } public { Public declarations } end;
var Form1: TForm1; ModbusConnection1: TModbusConnection; ModbusClient1: TModbusClient;
implementation
{$R *.dfm}
function LayerFunc(Bin: string): Single; var SomeVar: Byte; begin SomeVar := StrToInt(Bin[1]); end; function IntToBinFloat(Value: Integer; var Float: Single): string; var i: Integer; begin Result := ''; for i := 31 downto 0 do if Value and (1 shl i) <> 0 then Result := Result + '1' else Result := Result + '0'; Float := LayerFunc(Result); end;
function HexToFloat(Hex: string): Single; begin try IntToBinFloat(StrToInt('$' + Hex), Result); except Result := 0.0 end; end;
procedure TForm1.Button1Click(Sender: TObject); begin ModbusConnection1.Port:='COM3'; ModbusConnection1.BaudRate:=br115200; ModbusConnection1.DataBits:=db8; ModbusConnection1.Parity:=psEven; ModbusConnection1.StopBits:=sb1; ModbusConnection1.Open; ModbusClient1.Connection:= ModbusConnection1; end;
procedure TForm1.Button2Click(Sender: TObject); begin If ModbusConnection1.Active=true then ModbusConnection1.Close; end;
procedure TForm1.FormCreate(Sender: TObject); begin ModbusConnection1:=TModbusConnection.Create(self); ModbusClient1:=TModbusClient.Create(self); end;
procedure TForm1.Button3Click(Sender: TObject); begin ModbusClient1.ReadHoldingRegisters(4096, 60); end;
procedure ModbusClient1HoldingRegistersRead(Sender: TModbusClient; const Info: TTransactionInfo; StartReg, RegCount: Word; const RegValues: TRegValues); Var i:Integer; begin if Info.Reply = srNormalReply then begin For i:=0 to 29 do Form1.Memo1.Lines.Add(inttostr(i) + ' ' + IntToHex(RegValues[i*2],4)+IntToHex(RegValues[i*2+1],4)+' ' + FormatFloat('0.####',HexToFloat(IntToHex(RegValues[i*2],4)+IntToHex(RegValues[i*2+1],4)))); end;
end;
end.
|
Проверяю в снифере порта - все работает, данные уходят, устройство данные отправляет. Не могу понять как объявить процедуру события ModbusClient1HoldingRegistersRead? На всякие нажатия кнопки и создание компонентов во время создания формы не обращайте внимания, как все заработает выведу все в ДЛЛ-ку. Подскажите, кто знает.
|