unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    gbConfig: TGroupBox;
    Label2: TLabel;
    cbModuleID: TComboBox;
    Label3: TLabel;
    cbCom: TComboBox;
    Label4: TLabel;
    cbBaudRate: TComboBox;
    Label6: TLabel;
    eOutVal: TEdit;
    btnActive: TButton;
    btnExit: TButton;
    cbChecksum: TComboBox;
    Label7: TLabel;
    Label5: TLabel;
    eAddress: TEdit;
    Label1: TLabel;
    eSlot: TEdit;
    rgOutputMode: TRadioGroup;
    tmLoop: TTimer;
    Label8: TLabel;
    eInVal: TEdit;
    rgChannelMode: TRadioGroup;
    Label9: TLabel;
    eChannel: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure btnExitClick(Sender: TObject);
    procedure btnActiveClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure tmLoopTimer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1  : TForm1;
  wRtn   : WORD;
  wTtlChannel : WORD;
  wMaxValue   : LongInt;

implementation

Uses I7000, I7000u, I8000;

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
     // Initalize Setting for GUI
     cbModuleID.ItemIndex := 0;
     cbCom.ItemIndex      := 0;
     cbBaudRate.ItemIndex := 4;
     cbChecksum.ItemIndex := 0;

     // Setting the COM port strings
     ISetCOMString( cbCOM, 1, 255 );

     // Allocate the memory space
     gszSend    := StrAlloc( 100 );
     gszReceive := StrAlloc( 100 );
end;

procedure TForm1.btnExitClick(Sender: TObject);
begin
     Close;
end;

procedure TForm1.btnActiveClick(Sender: TObject);
begin
     // Stop by user
     if btnActive.Caption = 'Stop' then
     begin
          tmLoop.Enabled := False; // Stop timer
          Sleep(500);              // Wait the tmLoop to end
          Close_Com( gcPort );     // Close COM port
          btnActive.Caption := 'Active';
          btnExit.Enabled   := True;
          gbConfig.Enabled  := True;
          exit;
     end;

     gcPort     := Char(cbCom.ItemIndex + 1 );   // Com Port
     gdwBaudRate := StrToInt( cbBaudRate.Text ); // Baud Rate
     wRtn := IOpenCom(gcPort, gdwBaudRate);      // Open COM port
     if wRtn <> NoError then
     begin
          ShowMessage( 'COM port open error!!' );
          exit;
     end;

     gdwBuf[0] := Word(gcPort);                   // COM Port
     gdwBuf[1] := StrToInt('$' + eAddress.Text);  // Module Address
     gdwBuf[2] := StrToInt('$' + cbModuleID.Text);// Module ID
     gdwBuf[3] := cbChecksum.ItemIndex;           // CheckSum Disable or Enable
     gdwBuf[4] := 100;                            // TimeOut = 0.1 second
     //gdwBuf[5] := StrToInt( '$' + eOutVal.Text ); // 16-bit digital data to output
     gdwBuf[6] := 1;                              // string debug
     gdwBuf[7] := StrToInt( eSlot.Text );         // Slot Number for 8K series

     // Total Channels & Max Output value
     case gdwBuf[2] of
     $8063:
         begin
            wTtlChannel := 4;
            wMaxValue   := $F;
         end;
     $8060:
         begin
            wTtlChannel := 6;
            wMaxValue   := $3F;
         end;
     $8054, $8055, $8064, $8065, $8066, $8068:
         begin
            wTtlChannel := 8;
            wMaxValue   := $FF;
         end;
     $8056, $8057:
         begin
            wTtlChannel := 16;
            wMaxValue   := $FFFF;
         end;
     else
         begin
            wTtlChannel := 16;
            wMaxValue   := $FFFF;
         end;
     end;

     btnActive.Caption := 'Stop';
     btnExit.Enabled   := False;
     gbConfig.Enabled  := False;
     tmLoop.Enabled    := True;    // Start the Timer
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
     // Free the memory space
     StrDispose(gszSend);
     StrDispose(gszReceive);
end;

procedure TForm1.tmLoopTimer(Sender: TObject);
begin
     // data to output
     gdwBuf[5] := StrToInt( eOutVal.Text ) and 1;
     case rgOutputMode.ItemIndex of
     1:  gdwBuf[5] := 1 - gdwBuf[5] ;  // Inverted Value
     end;
     eOutVal.Text  := IntToStr(gdwBuf[5]);

     // Channel Number (Bit)
     gdwBuf[8] := StrToInt( eChannel.Text ) and $F;
     case rgChannelMode.ItemIndex of
     1:  // Increment
       begin
            gdwBuf[8] := gdwBuf[8] + 1;
            if gdwBuf[8] >= wTtlChannel then
               gdwBuf[8] := 0;
       end;
     2:  // Decrement
       begin
            gdwBuf[8] := gdwBuf[8] - 1;
            if gdwBuf[8] < 0 then
               gdwBuf[8] := wTtlChannel -1;
       end;
     end;
     eChannel.Text := IntToStr(gdwBuf[8]);

     // Calling the Digital Bit Output function for 8K series
     wRtn := DigitalBitOut_8K(@gdwBuf[0], @gfBuf[0], gszSend, gszReceive);
     If wRtn <> 0 Then
     Begin
         btnActiveClick( sender );
         Beep;
         ShowMessage( 'The Error Code:' + IntToStr(wRtn) + #13 + IGetErrorString(wRtn) );
     end;

     gdwBuf[5] := 0;
     // Calling the digital Output Read-Back function for 8K series
     wRtn := DigitalOutReadBack_8K(@gdwBuf[0], @gfBuf[0], gszSend, gszReceive);
     if wRtn <> 0 then
     begin
          Beep;
          eInVal.Text := 'Error';
     end
     else
          eInVal.Text := IntToStr( (gdwBuf[5] shr gdwBuf[8]) and 1);
end;

end.
