unit ModbusTest;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  ModLink, ExtCtrls, ComCtrls, Grids, ValEdit, StdCtrls, Spin;

type
  TForm1 = class(TForm)
    AVRcoModbusConnection: TModbusConnection;
    AVRcoModbusClient: TModbusClient;
    ReadModbusTagsTimer: TTimer;
    Voltage1: TProgressBar;
    ModbusTags: TValueListEditor;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Light1: TPanel;
    Light2: TPanel;
    StartJobButton: TButton;
    Memo1: TMemo;
    ComPortSpinEdit: TSpinEdit;
    RunButton: TButton;
    Label4: TLabel;
    procedure AVRcoModbusClientInputRegistersRead(Sender: TModbusClient;
      const Info: TTransactionInfo; StartReg, RegCount: Word;
      const RegValues: TRegValues);
    procedure ReadModbusTagsTimerTimer(Sender: TObject);
    procedure StartJobButtonClick(Sender: TObject);
    procedure RunButtonClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure ComPortSpinEditChange(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AVRcoModbusClientInputRegistersRead(Sender: TModbusClient;
  const Info: TTransactionInfo; StartReg, RegCount: Word;
  const RegValues: TRegValues);
var
   f: single;
   l: longword;
   p: pointer;
   ps: psingle;
begin
   ModbusTags.Values['counter1'] := IntToStr(RegValues[00]);
   ModbusTags.Values['counter2'] := IntToStr(RegValues[10]);
   ModbusTags.Values['counter3'] := IntToStr(RegValues[11]);

   ModbusTags.Values['scans_per_second'] := IntToStr(RegValues[4] + 65536 * RegValues[5]);

   if (RegValues[12] and (1 shl 10)) <> 0 then
      begin
         ModbusTags.Values['light1_on'] := 'ON';
         Light1.Color := clRed;
      end
   else
      begin
         ModbusTags.Values['light1_on'] := 'OFF';
         Light1.Color := clMaroon;
      end;

   if (RegValues[12] and (1 shl 11)) <> 0 then
      begin
         ModbusTags.Values['light2_on'] := 'ON';
         Light2.Color := clRed;
      end
   else
      begin
         ModbusTags.Values['light2_on'] := 'OFF';
         Light2.Color := clMaroon;
      end;

   ModbusTags.Values['inverted_byte'] := IntToStr(RegValues[13] and 255);
   ModbusTags.Values['port_b'] := IntToStr(RegValues[2] and 255);
   ModbusTags.Values['port_c'] := IntToStr((RegValues[2] and (255 shl 8)) shr 8);

   // let's convert 2 words to float
   l := RegValues[8] + 65536 * RegValues[9];
   p  := @l;
   ps := PSingle(P);
   f  := ps^;
   ModbusTags.Values['voltage1'] := FloatToStr(f);
   Voltage1.Position := Round(f*100);

   ModbusTags.Values['COMPILEYEAR']   := IntToStr(2000 + RegValues[14]);
   ModbusTags.Values['COMPILEMONTH']  := IntToStr(RegValues[15]);
   ModbusTags.Values['COMPILEDAY']    := IntToStr(RegValues[16]);
   ModbusTags.Values['COMPILEHOUR']   := IntToStr(RegValues[17]);
   ModbusTags.Values['COMPILEMINUTE'] := IntToStr(RegValues[18]);
   ModbusTags.Values['PROJECTBUILD']  := IntToStr(RegValues[19]);

   if (RegValues[1] and (1 shl 15)) <> 0 then
      ModbusTags.Values['job_is_started'] := 'ON'
   else
      ModbusTags.Values['job_is_started'] := 'OFF';
end;

procedure TForm1.ReadModbusTagsTimerTimer(Sender: TObject);
begin
   AVRcoModbusClient.ReadInputRegisters(0, 20);
end;

procedure TForm1.StartJobButtonClick(Sender: TObject);
begin
   if ModbusTags.Values['job_is_started'] = 'ON' then
      AVRcoModbusClient.WriteSingleCoil(31, false)
   else
      AVRcoModbusClient.WriteSingleCoil(31, true);
end;

procedure TForm1.RunButtonClick(Sender: TObject);
begin
   StartJobButton.Enabled := true;
   ReadModbusTagsTimer.Enabled := false;
   AVRcoModbusConnection.Active := false;
   AVRcoModbusConnection.Port := 'COM' + IntToStr(ComPortSpinEdit.Value);
   AVRcoModbusConnection.Active := true;
   ReadModbusTagsTimer.Enabled := true;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   ReadModbusTagsTimer.Enabled := false;
end;

procedure TForm1.ComPortSpinEditChange(Sender: TObject);
begin
   ReadModbusTagsTimer.Enabled := false;
   StartJobButton.Enabled := false;
end;

end.
