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.