OMRON 上位リンク通信 (2017/02/26)
上位リンク C コマンドと FINS コマンド で通信します。
C コマンドのほうが、シンプルで速いです。
Write-ReadBytes は、コメントアウトしていますが、WriteLn-ReadLn と同じ結果になります。
WriteLn の場合、CRLF (#13#10) が付加されるので、ターミネータの CR (#13) は不要です。
unit FINSUnit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Edit,
FMX.Controls.Presentation, FMX.StdCtrls, IdBaseComponent, IdComponent,
IdTCPConnection, IdTCPClient, IdGlobal;
type
TForm1 = class(TForm)
IdTCPClient1: TIdTCPClient;
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ private 宣言 }
public
{ public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
// FCS 計算
function FCS(const src: string):integer;
var
i :integer;
begin
result := 0;
for i := 0 to Pred(src.Length) do
result := Ord(src.Chars[i]) Xor result;
end;
// FINS コマンド
procedure TForm1.Button1Click(Sender: TObject);
// uses ... , IdGlobal;
var
snd, res : string;
//AData : TBytes;
Ticks:Cardinal;
begin
IdTCPClient1.Host := '1.2.3.4';
IdTCPClient1.Port := 2000;
IdTCPClient1.ConnectTimeout := 2000;
snd := '@';
snd := snd + '00'; // 上位リンク用ユニットNo
snd := snd + 'FA'; // ヘッダーコード
snd := snd + '0'; // レスポンスウェイト時間
snd := snd + '00'; // ICF (ネットワーク上=80, でない時=00)
snd := snd + '00'; // DA2
snd := snd + '00'; // SA2
snd := snd + '00'; // SID (通常00)再送の場合のカウンタ
snd := snd + '0101'; // 連続したI/O メモリエリアの内容を読み出し
snd := snd + '30'; // CIO=30 (16進2桁)
snd := snd + '000000'; // 読出し開始アドレス(16進4桁+16進2桁) 0000CH の00BIT
snd := snd + '0010'; // 読出しビット数(BIN) (16 進 4 桁)$10=16個
snd := snd + IntToHex(FCS(snd), 2); // FCS (16進 4桁)
snd := snd + '*';// + #13; // ターミネーター
IdTCPClient1.Connect;
if IdTCPClient1.Connected then begin
Ticks := TThread.GetTickCount;
{
AData := TEncoding.ANSI.GetBytes(snd);
IdTCPClient1.IOHandler.Write(TIdBytes(AData), snd.Length);
// レスポンス受信
SetLength(AData, 0);
IdTCPClient1.IOHandler.ReadBytes(TIdBytes(Adata), -1);
res := TEncoding.ANSI.GetString(Adata);
}
IdTCPClient1.IOHandler.WriteLn(snd);
res := IdTCPClient1.IOHandler.ReadLn(#13);
if res.Substring(5, 2) = '00' then
// ビットは、24文字目から2文字ずつ取得 00=OFF, 01=ON
res := res.Substring(23, 32);
Edit1.Text := res;
ShowMessage(IntToStr(TThread.GetTickCount - Ticks));
IdTCPClient1.Disconnect;
end;
end;
// C コマンド
procedure TForm1.Button2Click(Sender: TObject);
// uses ... , IdGlobal;
var
snd, res : string;
//AData : TBytes;
Ticks : Cardinal;
begin
IdTCPClient1.Host := '1.2.3.4';
IdTCPClient1.Port := 2000;
IdTCPClient1.ConnectTimeout := 2000;
snd := '@';
// ユニットNo.(BCD 2文字)
snd := snd + '00';
// ヘッダコード
snd := snd + 'RR'; //CIOエリア読出
snd := snd + '0000'; // 読出開始チャネル:BCD 4桁
// モード
snd := snd + '0001'; // 読出チャネル数:BCD 4桁
// FCS (HEX 2 桁)
snd := snd + IntToHex(FCS(snd), 2);
// ターミネーター
snd := snd + '*';// + #13;
AData := TEncoding.ANSI.GetBytes(snd);
IdTCPClient1.Connect;
if IdTCPClient1.Connected then begin
Ticks := TThread.GetTickCount;
{
AData := TEncoding.ANSI.GetBytes(snd);
IdTCPClient1.IOHandler.Write(TIdBytes(AData), snd.Length);
// レスポンス受信
SetLength(AData, 0);
IdTCPClient1.IOHandler.ReadBytes(TIdBytes(Adata), -1);
res := TEncoding.ANSI.GetString(Adata);
}
IdTCPClient1.IOHandler.WriteLn(snd);
res := IdTCPClient1.IOHandler.ReadLn(#13);
if res.Substring(5, 2) = '00' then
// BCD 4桁
res := res.Substring(7, 4);
Edit1.Text := res;
ShowMessage(IntToStr(TThread.GetTickCount - Ticks));
IdTCPClient1.Disconnect;
end;
end;
end.