Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > COM-порт DLL Modbus не работает как надо


Автор: Rodeon 26.5.2019, 00:15
В соседней теме http://forum.vingrad.ru/forum/topic-394028/kw-событие-event-dll.html подымал вопрос как отловить событие у невизуального компонента.
Начал переносить все в DLL-ку и встал, уже неделю не хочет работать как надо.
Собственно код:

Код

library Fakel;

uses
  SysUtils,
  Classes,
  Forms,
  DateUtils,
  ModLink,
  SharedTypes in 'SharedTypes.pas';

const
  _NAME = 'Fakel';
  _VERSION = 1;
  _TYPE = dtFile;
  _OPTIONSCOUNT = 1;
  HEX:ARRAY['A'..'F'] OF INTEGER=(10,11,12,13,14,15);

var
  ModbusConnection1: TModbusConnection;
  ModbusClient1:  TModbusClient;
  ModuleOptions: TOptions;
  datet: TDateTime;

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;

Function HexToInt(HexValue:String):Integer;
var
  Int,i:integer;
begin
  Result:=-1;
  Int:=0;
  for i:=1 TO Length(HexValue) DO
  IF HexValue[i] < 'A' THEN
  begin
    Int:=Int * 16 + ORD(HexValue[i]) - 48;
    Result:=int;
  end ELSE
  begin
    Int:=Int * 16 + HEX[HexValue[i]];
    Result:=int;
  end;
end;

function GetData: TDeviceData; stdcall;
var
  dp: TDeviceDataItem;
  str:string;
  datet: TDateTime;
begin
  datet:=now;
  ModbusClient1.ReadHoldingRegisters(4096, 60); // Запрос начиная с адреса 4096 регистров 60 штук
  Result := TDeviceData.Create(True);
  dp := TDeviceDataItem.Create;
  dp.Name := 'Параметр';
  dp.Value := Random(10);
  Result.Add(dp);

  dp := TDeviceDataItem.Create;
  dp.Name := 'Время, мсек.';
  dp.Value := inttostr(MilliSecondsBetween(now,datet));
  Result.Add(dp);
end;

procedure Initialize(Options: TOptions); stdcall;
begin
  ModbusConnection1:=TModbusConnection.Create(Nil);
  ModbusClient1:=TModbusClient.Create(Nil);
  ModbusConnection1.Port:='COM3';
  ModbusConnection1.BaudRate:=br115200;
  ModbusConnection1.DataBits:=db8;
  ModbusConnection1.Parity:=psEven;
  ModbusConnection1.StopBits:=sb1;
  ModbusConnection1.Open;
  ModbusClient1.Connection:= ModbusConnection1;
  ModbusClient1.OnHoldingRegistersRead:=ModbusClient1.OnHoldingRegistersRead;
end;

procedure SetOptions(Options: TOptions); stdcall;
begin
  if _OPTIONSCOUNT > 0 then
    ModuleOptions := Options;
end;

function GetModuleInfo: TModuleInfo; stdcall;
begin
  Result := TModuleInfo.Create;
  with Result do begin
    Name :=         _NAME;
    Version :=      _VERSION;
    DeviceType :=   _TYPE;
    OptionsCount := _OPTIONSCOUNT;

    Options[1] := 'COM порт';
    OptionsTypes[1] := otComPort;
    OptionsValues[1] := 'COM3';
    OptionsCount := 1;
  end;
end;

{$R *.res}

exports GetModuleInfo, GetData, Initialize, SetOptions;

begin
end.


Порт открывается 100% (снифер об этом сообщает).
Но строчка
Код

  ModbusClient1.ReadHoldingRegisters(4096, 60);

не хочет выполнятся, точнее все, что после нее, так как если ее закомментировать, то все работает дальше.
т.е. в программе я вижу как приходят данные рандомные отсюда:
Код

  dp.Name := 'Параметр';
  dp.Value := Random(10);

Опять же, если вынести строку запроса данных в процедуру инициализации, то работает, но 1 раз:
Код

procedure Initialize(Options: TOptions); stdcall;
begin
  ModbusConnection1:=TModbusConnection.Create(Nil);
  ModbusClient1:=TModbusClient.Create(Nil);
  ModbusConnection1.Port:='COM3';
  ModbusConnection1.BaudRate:=br115200;
  ModbusConnection1.DataBits:=db8;
  ModbusConnection1.Parity:=psEven;
  ModbusConnection1.StopBits:=sb1;
  ModbusConnection1.Open;
  ModbusClient1.Connection:= ModbusConnection1;
  ModbusClient1.OnHoldingRegistersRead:=ModbusClient1.OnHoldingRegistersRead;
  ModbusClient1.ReadHoldingRegisters(4096, 60);
end;


Собственно, все приплыл. Прошу помощи.
Во всех случаях программа компилируется.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)